From 42ab09e82131c628f6675ad2b306e6acf60a265c Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 28 Jan 2004 23:58:18 +0000 Subject: 2004-01-29 Marcus Brinkmann * gpgconf-list.c: File removed. * README.gpgconf: New file. * gpgconf-comp.c: New file. * Makefile.am (gpgconf_SOURCES): Remove gpgconf-list.c, add gpgconf-comp.c. --- tools/gpgconf-comp.c | 1321 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1321 insertions(+) create mode 100644 tools/gpgconf-comp.c (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c new file mode 100644 index 000000000..0e0ae5d7c --- /dev/null +++ b/tools/gpgconf-comp.c @@ -0,0 +1,1321 @@ +/* gpgconf-comp.c - Configuration utility for GnuPG. + Copyright (C) 2003 g10 Code GmbH + + This file is part of GnuPG. + + GnuPG is free software; you can 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. + + GnuPG is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GnuPG; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H +#include +#endif +#include +#include +#include +/* FIXME use gettext.h */ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gpgconf.h" + + +/* TODO: + Portability - Add gnulib replacements for getline, error, etc. + Backend: File backend must be able to write out changes !!! + Components: Add more components and their options. + Robustness: Do more validation. Call programs to do validation for us. +*/ + + +/* Backend configuration. Backends are used to decide how the default + and current value of an option can be determined, and how the + option can be changed. To every option in every component belongs + exactly one backend that controls and determines the option. Some + backends are programs from the GPG system. Others might be + implemented by GPGConf itself. If you change this enum, don't + forget to update GC_BACKEND below. */ +typedef enum + { + /* Any backend, used for find_option (). */ + GC_BACKEND_ANY, + + /* The Gnu Privacy Guard. */ + GC_BACKEND_GPG, + + /* The Gnu Privacy Guard for S/MIME. */ + GC_BACKEND_GPGSM, + + /* The GPG Agent. */ + GC_BACKEND_GPG_AGENT, + + /* The Aegypten directory manager. */ + GC_BACKEND_DIRMNGR, + + /* The LDAP server list file for the Aegypten director manager. */ + GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST, + + /* The number of the above entries. */ + GC_BACKEND_NR + } gc_backend_t; + + +/* To be able to implement generic algorithms for the various + backends, we collect all information about them in this struct. */ +static struct +{ + /* The name of the backend. */ + const char *name; + + /* The name of the program that acts as the backend. Some backends + don't have an associated program, but are implemented directly by + GPGConf. In this case, PROGRAM is NULL. */ + char *program; + + /* The option name for the configuration filename of this backend. + This must be an absolute pathname. It can be an option from a + different backend (but then ordering of the options might + matter). */ + const char *option_config_filename; + + /* If this is a file backend rather than a program backend, then + this is the name of the option associated with the file. */ + const char *option_name; +} gc_backend[GC_BACKEND_NR] = + { + { NULL, NULL, NULL }, /* GC_BACKEND_ANY dummy entry. */ + { "GnuPG", "gpg", "gpgconf-config-file" }, + { "GPGSM", "gpgsm", "gpgconf-config-file" }, + { "GPG Agent", "gpg-agent", "gpgconf-config-file" }, + { "DirMngr", "dirmngr", "gpgconf-config-file" }, + { "DirMngr LDAP Server List", NULL, "ldapserverlist-file", "LDAP Server" }, + }; + + +/* Option configuration. */ + +/* An option might take an argument, or not. Argument types can be + basic or complex. Basic types are generic and easy to validate. + Complex types provide more specific information about the intended + use, but can be difficult to validate. If you add to this enum, + don't forget to update GC_ARG_TYPE below. YOU MUST NOT CHANGE THE + NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE EXTERNAL + INTERFACE. */ +typedef enum + { + /* Basic argument types. */ + + /* No argument. */ + GC_ARG_TYPE_NONE = 0, + + /* A String argument. */ + GC_ARG_TYPE_STRING = 1, + + /* A signed integer argument. */ + GC_ARG_TYPE_INT32 = 2, + + /* An unsigned integer argument. */ + GC_ARG_TYPE_UINT32 = 3, + + + /* Complex argument types. */ + + /* A complete pathname. */ + GC_ARG_TYPE_PATHNAME = 4, + + /* An LDAP server in the format + HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */ + GC_ARG_TYPE_LDAP_SERVER = 5, + + /* A 40 character fingerprint. */ + GC_ARG_TYPE_KEY_FPR = 6, + + /* ADD NEW ENTRIES HERE. */ + + /* The number of the above entries. */ + GC_ARG_TYPE_NR + } gc_arg_type_t; + + +/* For every argument, we record some information about it in the + following struct. */ +static struct +{ + /* For every argument type exists a basic argument type that can be + used as a fallback for input and validation purposes. */ + gc_arg_type_t fallback; + + /* Human-readable name of the type. */ + const char *name; +} gc_arg_type[GC_ARG_TYPE_NR] = + { + /* The basic argument types have their own types as fallback. */ + { GC_ARG_TYPE_NONE, "none" }, + { GC_ARG_TYPE_STRING, "string" }, + { GC_ARG_TYPE_INT32, "int32" }, + { GC_ARG_TYPE_UINT32, "uint32" }, + + /* The complex argument types have a basic type as fallback. */ + { GC_ARG_TYPE_STRING, "pathname" }, + { GC_ARG_TYPE_STRING, "ldap server" }, + { GC_ARG_TYPE_STRING, "key fpr" }, + }; + + +/* Every option has an associated expert level, than can be used to + hide advanced and expert options from beginners. If you add to + this list, don't forget to update GC_LEVEL below. YOU MUST NOT + CHANGE THE NUMBERS OF THE EXISTING ENTRIES, AS THEY ARE PART OF THE + EXTERNAL INTERFACE. */ +typedef enum + { + /* The basic options should always be displayed. */ + GC_LEVEL_BASIC, + + /* The advanced options may be hidden from beginners. */ + GC_LEVEL_ADVANCED, + + /* The expert options should only be displayed to experts. */ + GC_LEVEL_EXPERT, + + /* The invisible options should normally never be displayed. */ + GC_LEVEL_INVISIBLE, + + /* The internal options are never exported, they mark options that + are recorded for internal use only. */ + GC_LEVEL_INTERNAL, + + /* ADD NEW ENTRIES HERE. */ + + /* The number of the above entries. */ + GC_LEVEL_NR + } gc_expert_level_t; + +/* A description for each expert level. */ +static struct +{ + const char *name; +} gc_level[] = + { + { "basic" }, + { "advanced" }, + { "expert" }, + { "invisible" }, + { "internal" } + }; + + +/* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING + FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ +#define GC_OPT_FLAG_NONE 0 +/* Some entries in the option list are not options, but mark the + beginning of a new group of options. These entries have the GROUP + flag set. */ +#define GC_OPT_FLAG_GROUP (1 << 0) +/* The ARG_OPT flag for an option indicates that the argument is + optional. */ +#define GC_OPT_FLAG_ARG_OPT (1 << 1) +/* The LIST flag for an option indicates that the option can occur + several times. A comma separated list of arguments is used as the + argument value. */ +#define GC_OPT_FLAG_LIST (1 << 2) +/* The RUNTIME flag for an option indicates that the option can be + changed at runtime. */ +#define GC_OPT_FLAG_RUNTIME (1 << 3) + +/* A human-readable description for each flag. */ +static struct +{ + const char *name; +} gc_flag[] = + { + { "group" }, + { "optional arg" }, + { "list" }, + { "runtime" } + }; + + +/* To each option, or group marker, the information in the GC_OPTION + struct is provided. If you change this, don't forget to update the + option list of each component. */ +struct gc_option +{ + /* If this is NULL, then this is a terminator in an array of unknown + length. Otherwise, if this entry is a group marker (see FLAGS), + then this is the name of the group described by this entry. + Otherwise it is the name of the option described by this + entry. The name must not contain a colon. */ + const char *name; + + /* The option flags. If the GROUP flag is set, then this entry is a + group marker, not an option, and only the fields LEVEL, + DESC_DOMAIN and DESC are valid. In all other cases, this entry + describes a new option and all fields are valid. */ + unsigned int flags; + + /* The expert level. This field is valid for options and groups. A + group has the expert level of the lowest-level option in the + group. */ + gc_expert_level_t level; + + /* A gettext domain in which the following description can be found. + If this is NULL, then DESC is not translated. Valid for groups + and options. */ + const char *desc_domain; + + /* A gettext description for this group or option. If it starts + with a '|', then the string up to the next '|' describes the + argument, and the description follows the second '|'. */ + const char *desc; + + /* The following fields are only valid for options. */ + + /* The type of the option argument. */ + gc_arg_type_t arg_type; + + /* The backend that implements this option. */ + gc_backend_t backend; + + /* The following fields are set to NULL at startup (because all + option's are declared as static variables). They are at the end + of the list so that they can be omitted from the option + declarations. */ + + /* The default value for this option. This is NULL if the option is + not present in the backend, the empty string if no default is + available, and otherwise a quoted string. */ + char *default_value; + + /* The current value of this option. */ + char *value; + + /* The new value of this option. */ + char *new_value; +}; +typedef struct gc_option gc_option_t; + +/* Use this macro to terminate an option list. */ +#define GC_OPTION_NULL { NULL } + + +/* The options of the GC_COMPONENT_GPG_AGENT component. */ +static gc_option_t gc_options_gpg_agent[] = + { + GC_OPTION_NULL + }; + + +/* The options of the GC_COMPONENT_DIRMNGR component. */ +static gc_option_t gc_options_dirmngr[] = + { + /* The configuration file to which we write the changes. */ + { "gpgconf-config-file", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, + + { "Monitor", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the diagnostic output" }, + { "verbose", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "verbose", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "be somewhat more quiet", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + + { "Format", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the format of the output" }, + { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "sh-style command output", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "csh-style command output", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + + { "Configuration", + GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, + NULL, "Options controlling the configuration" }, + { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "dirmngr", "|FILE|read options from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, + + { "Debug", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "dirmngr", "Options useful for debugging" }, + { "debug", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "dirmngr", "|FLAGS|set the debugging FLAGS", + GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + { "debug-all", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "set all debugging flags", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "do not detach from the console", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "|FILE|write logs to FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, + { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + + { "Enforcement", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the interactivity and enforcement" }, + { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "run without asking a user", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "force", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "force loading of outdated CRLs", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + + { "LDAP", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Configuration of LDAP servers to use" }, + { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "add new servers discovered in CRL distribution points" + " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "|N|set LDAP timeout to N seconds", + GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + /* The following entry must not be removed, as it is required for + the GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST. */ + { "ldapserverlist-file", + GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + "dirmngr", "|FILE|read LDAP server list from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, + /* This entry must come after at least one entry for + GC_BACKEND_DIRMNGR in this component, so that the entry for + "ldapserverlist-file will be initialized before this one. */ + { "LDAP Server", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + NULL, "LDAP server list", + GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST }, + + { "CRL", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Configuration of the CRL" }, + { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "|N|do not return more than N items in one query", + GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + + GC_OPTION_NULL + }; + + +/* Component system. Each component is a set of options that can be + configured at the same time. If you change this, don't forget to + update GC_COMPONENT below. */ +typedef enum + { + /* The GPG Agent. */ + GC_COMPONENT_GPG_AGENT, + + /* The LDAP Directory Manager for CRLs. */ + GC_COMPONENT_DIRMNGR, + + /* The number of components. */ + GC_COMPONENT_NR + } gc_component_t; + + +/* The information associated with each component. */ +static struct +{ + /* The name of this component. Must not contain a colon (':') + character. */ + const char *name; + + /* The gettext domain for the description DESC. If this is NULL, + then the description is not translated. */ + const char *desc_domain; + + /* The description for this domain. */ + const char *desc; + + /* The list of options for this component, terminated by + GC_OPTION_NULL. */ + gc_option_t *options; +} gc_component[] = + { + { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, + { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } + }; + + +/* Robust version of dgettext. */ +static const char * +my_dgettext (const char *domain, const char *msgid) +{ + if (domain) + { + char *text = dgettext (domain, msgid); + return text ? text : msgid; + } + else + return msgid; +} + + +/* Percent-Escape special characters. The string is valid until the + next invocation of the function. */ +static char * +percent_escape (const char *src) +{ + static char *esc_str; + static int esc_str_len; + int new_len = 3 * strlen (src) + 1; + char *dst; + + if (esc_str_len < new_len) + { + char *new_esc_str = realloc (esc_str, new_len); + if (!new_esc_str) + error (1, 1, "Can not escape string"); + esc_str = new_esc_str; + esc_str_len = new_len; + } + + dst = esc_str; + while (*src) + { + if (*src == '%') + { + *(dst++) = '%'; + *(dst++) = '2'; + *(dst++) = '5'; + } + else if (*src == ':') + { + /* The colon is used as field separator. */ + *(dst++) = '%'; + *(dst++) = '3'; + *(dst++) = 'a'; + } + else if (*src == ',') + { + /* The comma is used as list separator. */ + *(dst++) = '%'; + *(dst++) = '2'; + *(dst++) = 'c'; + } + else + *(dst++) = *(src); + src++; + } + *dst = '\0'; + return esc_str; +} + + + +/* List all components that are available. */ +void +gc_component_list_components (FILE *out) +{ + gc_component_t idx; + + for (idx = 0; idx < GC_COMPONENT_NR; idx++) + { + const char *desc = gc_component[idx].desc; + desc = my_dgettext (gc_component[idx].desc_domain, desc); + fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc)); + } +} + + +/* Find the component with the name NAME. Returns -1 if not + found. */ +int +gc_component_find (const char *name) +{ + gc_component_t idx; + + for (idx = 0; idx < GC_COMPONENT_NR; idx++) + { + if (!strcmp (name, gc_component[idx].name)) + return idx; + } + return -1; +} + + +/* List all options of the component COMPONENT. */ +void +gc_component_list_options (int component, FILE *out) +{ + const gc_option_t *option = gc_component[component].options; + + while (option->name) + { + const char *desc = NULL; + char *arg_name = NULL; + + /* Do not output unknown or internal options. */ + if (!option->default_value || option->level == GC_LEVEL_INTERNAL) + { + option++; + continue; + } + + if (option->desc) + { + desc = my_dgettext (option->desc_domain, option->desc); + + if (*desc == '|') + { + const char *arg_tail = strchr (&desc[1], '|'); + + if (arg_tail) + { + int arg_len = arg_tail - &desc[1]; + arg_name = malloc (arg_len + 1); + if (!arg_name) + error (1, 1, "Can not build argument name"); + memcpy (arg_name, &desc[1], arg_len); + arg_name[arg_len] = '\0'; + desc = arg_tail + 1; + } + } + } + + /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR + ORDER IS PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE + ANY FIELDS. */ + + /* The name field. */ + fprintf (out, "%s", option->name); + + /* The flags field. */ + fprintf (out, ":%u", option->flags); + if (opt.verbose) + { + putc (' ', out); + + if (!option->flags) + fprintf (out, "none"); + else + { + unsigned int flags = option->flags; + unsigned int flag = 0; + unsigned int first = 1; + + while (flags) + { + if (flags & 1) + { + if (first) + first = 0; + else + putc (',', out); + fprintf (out, "%s", gc_flag[flag].name); + } + flags >>= 1; + flag++; + } + } + } + + /* The level field. */ + fprintf (out, ":%u", option->level); + if (opt.verbose) + fprintf (out, " %s", gc_level[option->level].name); + + /* The description field. */ + fprintf (out, ":%s", desc ? percent_escape (desc) : ""); + + /* The type field. */ + fprintf (out, ":%u", option->arg_type); + if (opt.verbose) + fprintf (out, " %s", gc_arg_type[option->arg_type].name); + + /* The alternate type field. */ + fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); + if (opt.verbose) + fprintf (out, " %s", + gc_arg_type[gc_arg_type[option->arg_type].fallback].name); + + /* The argument name field. */ + fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); + if (arg_name) + free (arg_name); + + /* The default value field. */ + fprintf (out, ":%s", option->default_value ? option->default_value : ""); + + /* The value field. */ + fprintf (out, ":%s", option->value ? option->value : ""); + + /* ADD NEW FIELDS HERE. */ + + putc ('\n', out); + option++; + } +} + + +/* Find the option NAME in component COMPONENT, for the backend + BACKEND. If BACKEND is GC_BACKEND_ANY, any backend will match. */ +static gc_option_t * +find_option (gc_component_t component, const char *name, + gc_backend_t backend) +{ + gc_option_t *option = gc_component[component].options; + while (option->name) + { + if (!(option->flags & GC_OPT_FLAG_GROUP) + && !strcmp (option->name, name) + && (backend == GC_BACKEND_ANY || option->backend == backend)) + break; + option++; + } + return option->name ? option : NULL; +} + + +/* Determine the configuration pathname for the component COMPONENT + and backend BACKEND. */ +static char * +get_config_pathname (gc_component_t component, gc_backend_t backend) +{ + char *pathname; + gc_option_t *option = find_option + (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY); + assert (option); + + if (!option->default_value) + error (1, 0, "Option %s, needed by backend %s, was not initialized", + gc_backend[backend].option_config_filename, + gc_backend[backend].name); + if (*option->value) + pathname = option->value; + else + pathname = option->default_value; + + if (*pathname != '/') + error (1, 0, "Option %s, needed by backend %s, is not absolute", + gc_backend[backend].option_config_filename, + gc_backend[backend].name); + + return pathname; +} + + +/* Retrieve the options for the component COMPONENT from backend + BACKEND, which we already know is a program-type backend. */ +static void +retrieve_options_from_program (gc_component_t component, gc_backend_t backend) +{ + char *cmd_line; + char *line = NULL; + size_t line_len = 0; + ssize_t length; + FILE *output; + + asprintf (&cmd_line, "%s --gpgconf-list", gc_backend[backend].program); + if (!cmd_line) + error (1, 1, "Can not construct command line"); + + output = popen (cmd_line, "r"); + if (!output) + error (1, 1, "Could not gather active options from %s", cmd_line); + + while ((length = getline (&line, &line_len, output)) > 0) + { + gc_option_t *option; + char *default_value; + char *value; + + /* Strip newline and carriage return, if present. */ + while (length > 0 + && (line[length - 1] == '\n' || line[length - 1] == '\r')) + line[--length] = '\0'; + + /* Extract default value and value, if present. Default to + empty if not. */ + default_value = strchr (line, ':'); + if (!default_value) + { + default_value = ""; + value = ""; + } + else + { + *(default_value++) = '\0'; + value = strchr (default_value, ':'); + if (!value) + value = ""; + else + { + char *end; + + *(value++) = '\0'; + end = strchr (value, ':'); + if (end) + *end = '\0'; + } + } + + /* Look up the option in the component and install the + configuration data. */ + option = find_option (component, line, backend); + if (option) + { + if (option->default_value) + error (1, 1, "Option %s returned twice from %s", + line, cmd_line); + option->default_value = strdup (default_value); + option->value = strdup (value); + if (!option->default_value || !option->value) + error (1, 1, "Could not store options"); + } + } + if (ferror (output)) + error (1, 1, "Error reading from %s", cmd_line); + if (fclose (output) && ferror (output)) + error (1, 1, "Error closing %s", cmd_line); + free (cmd_line); +} + + +/* Retrieve the options for the component COMPONENT from backend + BACKEND, which we already know is of type file list. */ +static void +retrieve_options_from_file (gc_component_t component, gc_backend_t backend) +{ + gc_option_t *list_option; + char *list_pathname; + FILE *list_file; + char *line = NULL; + size_t line_len = 0; + ssize_t length; + char *list; + + list_option = find_option (component, + gc_backend[backend].option_name, GC_BACKEND_ANY); + assert (list_option); + + list_pathname = get_config_pathname (component, backend); + + list_file = fopen (list_pathname, "r"); + if (ferror (list_file)) + error (1, 1, "Can not open list file %s", list_pathname); + + list = strdup ("\""); + if (!list) + error (1, 1, "Can not allocate initial list string"); + + while ((length = getline (&line, &line_len, list_file)) > 0) + { + char *start; + char *end; + char *new_list; + + start = line; + while (*start == ' ' || *start == '\t') + start++; + if (!*start || *start == '#' || *start == '\r' || *start == '\n') + continue; + + end = start; + while (*end && *end != '#' && *end != '\r' && *end != '\n') + end++; + /* Walk back to skip trailing white spaces. Looks evil, but + works because of the conditions on START and END imposed + at this point (END is at least START + 1, and START is + not a whitespace character). */ + while (*(end - 1) == ' ' || *(end - 1) == '\t') + end--; + *end = '\0'; + /* FIXME: Oh, no! This is so lame! Use realloc and really + append. */ + if (list) + { + asprintf (&new_list, "%s,%s", list, percent_escape (start)); + free (list); + list = new_list; + } + if (!list) + error (1, 1, "Can not construct list"); + } + if (ferror (list_file)) + error (1, 1, "Can not read list file %s", list_pathname); + list_option->default_value = ""; + list_option->value = list; +} + + +/* Retrieve the currently active options and their defaults from all + involved backends for this component. */ +void +gc_component_retrieve_options (int component) +{ + int backend_seen[GC_BACKEND_NR]; + gc_backend_t backend; + gc_option_t *option = gc_component[component].options; + + for (backend = 0; backend < GC_BACKEND_NR; backend++) + backend_seen[backend] = 0; + + while (option->name) + { + if (!(option->flags & GC_OPT_FLAG_GROUP)) + { + backend = option->backend; + + if (backend_seen[backend]) + { + option++; + continue; + } + backend_seen[backend] = 1; + + assert (backend != GC_BACKEND_ANY); + + if (gc_backend[backend].program) + retrieve_options_from_program (component, backend); + else + retrieve_options_from_file (component, backend); + } + option++; + } +} + + +/* Perform a simple validity check based on the type. */ +static void +option_check_validity (gc_option_t *option, const char *new_value) +{ + if (option->new_value) + error (1, 0, "Option %s already changed", option->name); + + if (!*new_value) + return; + + /* FIXME. Verify that lists are lists, numbers are numbers, strings + are strings, etc. */ +} + + +/* Create and verify the new configuration file for the specified + backend and component. Returns 0 on success and -1 on error. */ +static int +change_options_file (gc_component_t component, gc_backend_t backend, + char **src_filenamep, char **dest_filenamep, + char **orig_filenamep) +{ + /* FIXME. */ + assert (!"Not implemented."); + return -1; +} + + +/* Create and verify the new configuration file for the specified + backend and component. Returns 0 on success and -1 on error. */ +static int +change_options_program (gc_component_t component, gc_backend_t backend, + char **src_filenamep, char **dest_filenamep, + char **orig_filenamep) +{ + static const char marker[] = "###+++--- GPGConf ---+++###"; + /* True if we are within the marker in the config file. */ + int in_marker = 0; + gc_option_t *option; +#define LINE_LEN 4096 + char line[LINE_LEN]; + int res; + int fd; + FILE *src_file = NULL; + FILE *dest_file = NULL; + char *src_filename; + char *dest_filename; + char *orig_filename; + + /* FIXME. Throughout the function, do better error reporting. */ + dest_filename = strdup (get_config_pathname (component, backend)); + if (!dest_filename) + return -1; + asprintf (&src_filename, "%s.gpgconf.%i.new", dest_filename, getpid ()); + if (!src_filename) + return -1; + asprintf (&orig_filename, "%s.gpgconf.%i.bak", dest_filename, getpid ()); + if (!orig_filename) + return -1; + + res = link (dest_filename, orig_filename); + if (res < 0 && errno != ENOENT) + return -1; + if (res < 0) + { + free (orig_filename); + orig_filename = NULL; + } + /* We now initialize the return strings, so the caller can do the + cleanup for us. */ + *src_filenamep = src_filename; + *dest_filenamep = dest_filename; + *orig_filenamep = orig_filename; + + /* Use open() so that we can use O_EXCL. */ + fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); + if (fd < 0) + return -1; + src_file = fdopen (fd, "w"); + res = errno; + if (!src_file) + { + errno = res; + return -1; + } + + /* Only if ORIG_FILENAME is not NULL did the configuration file + exist already. In this case, we will copy its content into the + new configuration file, changing it to our liking in the + process. */ + if (orig_filename) + { + dest_file = fopen (dest_filename, "r"); + if (!dest_file) + goto change_one_err; + + while (fgets (line, LINE_LEN, dest_file)) + { + int length; + int disable = 0; + char *start; + char *end; + + line[LINE_LEN - 1] = '\0'; + length = strlen (line); + if (length == LINE_LEN - 1) + { + /* FIXME */ + errno = ENAMETOOLONG; + goto change_one_err; + } + + if (!strncmp (marker, line, sizeof (marker) - 1)) + { + if (!in_marker) + in_marker = 1; + else + break; + } + + start = line; + while (*start == ' ' || *start == '\t') + start++; + if (*start && *start != '\r' && *start != '\n' && *start != '#') + { + char saved_end; + + end = start; + while (*end && *end != ' ' && *end != '\t' + && *end != '\r' && *end != '\n' && *end != '#') + end++; + saved_end = *end; + *end = '\0'; + + option = find_option (component, start, backend); + *end = saved_end; + if (option && option->new_value) + disable = 1; + } + if (disable) + { + if (!in_marker) + { + fprintf (src_file, + "# GPGConf disabled this option here at FIXME\n"); + if (ferror (src_file)) + goto change_one_err; + fprintf (src_file, "# %s", line); + if (ferror (src_file)) + goto change_one_err; + } + } + else + { + fprintf (src_file, "%s", line); + if (ferror (src_file)) + goto change_one_err; + } + } + if (ferror (dest_file)) + goto change_one_err; + } + + if (!in_marker) + { + /* There was no marker. This is the first time we edit the + file. We add our own marker at the end of the file and + proceed. Note that we first write a newline, this guards us + against files which lack the newline at the end of the last + line, while it doesn't hurt us in all other cases. */ + fprintf (src_file, "\n%s\n", marker); + if (ferror (src_file)) + goto change_one_err; + } + /* At this point, we have copied everything up to the end marker + into the new file, except for the options we are going to change. + Now, dump the changed options (except for those we are going to + revert to their default), and write the end marker, possibly + followed by the rest of the original file. */ + option = gc_component[component].options; + while (option->name) + { + if (!(option->flags & GC_OPT_FLAG_GROUP) + && option->backend == backend + && option->new_value + && *option->new_value) + { + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) + fprintf (src_file, "%s %s\n", option->name, &option->new_value[1]); + else if (option->arg_type == GC_ARG_TYPE_NONE) + fprintf (src_file, "%s\n", option->name); + else + fprintf (src_file, "%s %s\n", option->name, option->new_value); + if (ferror (src_file)) + goto change_one_err; + } + option++; + } + { + time_t cur_time = time (NULL); + + /* asctime() returns a string that ends with a newline + character! */ + fprintf (src_file, "%s %s", marker, asctime (localtime (&cur_time))); + if (ferror (src_file)) + goto change_one_err; + } + if (!in_marker) + { + fprintf (src_file, "# GPGConf edited this configuration file.\n"); + if (ferror (src_file)) + goto change_one_err; + fprintf (src_file, "# It will disable options before this marked " + "block, but it will\n"); + if (ferror (src_file)) + goto change_one_err; + fprintf (src_file, "# never change anything below these lines.\n"); + if (ferror (src_file)) + goto change_one_err; + } + if (dest_file) + { + while (fgets (line, LINE_LEN, dest_file)) + { + int length; + + line[LINE_LEN - 1] = '\0'; + length = strlen (line); + if (length == LINE_LEN - 1) + { + /* FIXME */ + errno = ENAMETOOLONG; + goto change_one_err; + } + fprintf (src_file, "%s", line); + if (ferror (src_file)) + goto change_one_err; + } + if (ferror (dest_file)) + goto change_one_err; + } + res = fclose (src_file); + if (res) + { + res = errno; + close (fd); + if (dest_file) + fclose (dest_file); + errno = res; + return -1; + } + close (fd); + if (dest_file) + { + res = fclose (dest_file); + if (res) + return -1; + } + return 0; + + change_one_err: + res = errno; + if (src_file) + { + fclose (src_file); + close (fd); + } + if (dest_file) + fclose (dest_file); + errno = res; + return -1; +} + +/* Read the modifications from IN and apply them. */ +void +gc_component_change_options (int component, FILE *in) +{ + int err = 0; + char *src_pathname[GC_BACKEND_NR]; + char *dest_pathname[GC_BACKEND_NR]; + char *orig_pathname[GC_BACKEND_NR]; + gc_backend_t backend; + gc_option_t *option; + char *line = NULL; + size_t line_len = 0; + ssize_t length; + + for (backend = 0; backend < GC_BACKEND_NR; backend++) + { + src_pathname[backend] = NULL; + dest_pathname[backend] = NULL; + orig_pathname[backend] = NULL; + } + + while ((length = getline (&line, &line_len, in)) > 0) + { + char *value; + + /* Strip newline and carriage return, if present. */ + while (length > 0 + && (line[length - 1] == '\n' || line[length - 1] == '\r')) + line[--length] = '\0'; + + value = strchr (line, ':'); + if (!value) + value = ""; + else + { + char *end; + + *(value++) = '\0'; + end = strchr (value, ':'); + if (end) + *end = '\0'; + } + + option = find_option (component, line, GC_BACKEND_ANY); + if (!option) + error (1, 0, "Unknown option %s", line); + + option_check_validity (option, value); + option->new_value = strdup (value); + } + + /* Now that we have collected and locally verified the changes, + write them out to new configuration files, verify them + externally, and then commit them. */ + option = gc_component[component].options; + while (option->name) + { + /* Go on if we have already seen this backend, or if there is + nothing to do. */ + if (src_pathname[option->backend] || !option->new_value) + { + option++; + continue; + } + + if (gc_backend[option->backend].program) + err = change_options_program (component, option->backend, + &src_pathname[component], + &dest_pathname[component], + &orig_pathname[component]); + else + err = change_options_file (component, option->backend, + &src_pathname[component], + &dest_pathname[component], + &orig_pathname[component]); + + if (err) + break; + + option++; + } + if (!err) + { + int i; + + for (i = 0; i < GC_COMPONENT_NR; i++) + { + if (src_pathname[i]) + { + /* FIXME: Make a verification here. */ + + assert (dest_pathname[i]); + + if (orig_pathname[i]) + err = rename (src_pathname[i], dest_pathname[i]); + else + { + /* This is a bit safer than rename() because we + expect DEST_PATHNAME not to be there. If it + happens to be there, this will fail. */ + err = link (src_pathname[i], dest_pathname[i]); + if (!err) + unlink (src_pathname[i]); + } + if (err) + break; + src_pathname[i] = NULL; + } + } + } + + if (err) + { + int i; + int res = errno; + + /* An error occured. */ + for (i = 0; i < GC_COMPONENT_NR; i++) + { + if (src_pathname[i]) + { + /* The change was not yet committed. */ + unlink (src_pathname[i]); + if (orig_pathname[i]) + unlink (orig_pathname[i]); + } + else + { + /* The changes were already committed. FIXME: This is a + tad dangerous, as we don't know if we don't overwrite + a version of the file that is even newer than the one + we just installed. */ + if (orig_pathname[i]) + rename (orig_pathname[i], dest_pathname[i]); + else + unlink (dest_pathname[i]); + } + } + errno = res; + error (1, 1, "Could not commit changes"); + } +} -- cgit From 0329746dce6800fd3bd5926ae4971f0e63edd6ae Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 30 Jan 2004 10:38:07 +0000 Subject: 2004-01-30 Marcus Brinkmann * gpgconf-comp.c: Use xmalloc, libcommon's asctimestamp and gnupg_get_time, fix error() invocation and use getline() consistently. --- tools/ChangeLog | 6 ++++ tools/gpgconf-comp.c | 84 ++++++++++++++++++++-------------------------------- 2 files changed, 38 insertions(+), 52 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 4d7511713..a9254bd99 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,9 @@ +2004-01-30 Marcus Brinkmann + + * gpgconf-comp.c: Use xmalloc, libcommon's asctimestamp and + gnupg_get_time, fix error() invocation and use getline() + consistently. + 2004-01-30 Werner Koch * Makefile.am (sbin_SCRIPTS): New, to install addgnupghome. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 0e0ae5d7c..5a1629fb8 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -34,6 +34,9 @@ #include +/* For asctimestamp(), gnupg_get_time (). */ +#include "util.h" + #include "gpgconf.h" @@ -42,6 +45,8 @@ Backend: File backend must be able to write out changes !!! Components: Add more components and their options. Robustness: Do more validation. Call programs to do validation for us. + Don't use popen, as this will not tell us if the program had a + non-zero exit code. */ @@ -493,7 +498,7 @@ percent_escape (const char *src) { char *new_esc_str = realloc (esc_str, new_len); if (!new_esc_str) - error (1, 1, "Can not escape string"); + error (1, errno, "can not escape string"); esc_str = new_esc_str; esc_str_len = new_len; } @@ -591,9 +596,7 @@ gc_component_list_options (int component, FILE *out) if (arg_tail) { int arg_len = arg_tail - &desc[1]; - arg_name = malloc (arg_len + 1); - if (!arg_name) - error (1, 1, "Can not build argument name"); + arg_name = xmalloc (arg_len + 1); memcpy (arg_name, &desc[1], arg_len); arg_name[arg_len] = '\0'; desc = arg_tail + 1; @@ -660,7 +663,7 @@ gc_component_list_options (int component, FILE *out) /* The argument name field. */ fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); if (arg_name) - free (arg_name); + xfree (arg_name); /* The default value field. */ fprintf (out, ":%s", option->default_value ? option->default_value : ""); @@ -706,7 +709,7 @@ get_config_pathname (gc_component_t component, gc_backend_t backend) assert (option); if (!option->default_value) - error (1, 0, "Option %s, needed by backend %s, was not initialized", + error (1, 0, "option %s, needed by backend %s, was not initialized", gc_backend[backend].option_config_filename, gc_backend[backend].name); if (*option->value) @@ -715,7 +718,7 @@ get_config_pathname (gc_component_t component, gc_backend_t backend) pathname = option->default_value; if (*pathname != '/') - error (1, 0, "Option %s, needed by backend %s, is not absolute", + error (1, 0, "option %s, needed by backend %s, is not absolute", gc_backend[backend].option_config_filename, gc_backend[backend].name); @@ -736,11 +739,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) asprintf (&cmd_line, "%s --gpgconf-list", gc_backend[backend].program); if (!cmd_line) - error (1, 1, "Can not construct command line"); + error (1, errno, "can not construct command line"); output = popen (cmd_line, "r"); if (!output) - error (1, 1, "Could not gather active options from %s", cmd_line); + error (1, errno, "could not gather active options from %s", cmd_line); while ((length = getline (&line, &line_len, output)) > 0) { @@ -784,18 +787,18 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) if (option) { if (option->default_value) - error (1, 1, "Option %s returned twice from %s", + error (1, errno, "option %s returned twice from %s", line, cmd_line); option->default_value = strdup (default_value); option->value = strdup (value); if (!option->default_value || !option->value) - error (1, 1, "Could not store options"); + error (1, errno, "could not store options"); } } if (ferror (output)) - error (1, 1, "Error reading from %s", cmd_line); + error (1, errno, "error reading from %s", cmd_line); if (fclose (output) && ferror (output)) - error (1, 1, "Error closing %s", cmd_line); + error (1, errno, "error closing %s", cmd_line); free (cmd_line); } @@ -821,11 +824,11 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) list_file = fopen (list_pathname, "r"); if (ferror (list_file)) - error (1, 1, "Can not open list file %s", list_pathname); + error (1, errno, "can not open list file %s", list_pathname); list = strdup ("\""); if (!list) - error (1, 1, "Can not allocate initial list string"); + error (1, errno, "can not allocate initial list string"); while ((length = getline (&line, &line_len, list_file)) > 0) { @@ -858,10 +861,10 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) list = new_list; } if (!list) - error (1, 1, "Can not construct list"); + error (1, errno, "can not construct list"); } if (ferror (list_file)) - error (1, 1, "Can not read list file %s", list_pathname); + error (1, errno, "can not read list file %s", list_pathname); list_option->default_value = ""; list_option->value = list; } @@ -909,7 +912,7 @@ static void option_check_validity (gc_option_t *option, const char *new_value) { if (option->new_value) - error (1, 0, "Option %s already changed", option->name); + error (1, 0, "option %s already changed", option->name); if (!*new_value) return; @@ -943,8 +946,9 @@ change_options_program (gc_component_t component, gc_backend_t backend, /* True if we are within the marker in the config file. */ int in_marker = 0; gc_option_t *option; -#define LINE_LEN 4096 - char line[LINE_LEN]; + char *line; + size_t line_len; + ssize_t length; int res; int fd; FILE *src_file = NULL; @@ -1000,22 +1004,12 @@ change_options_program (gc_component_t component, gc_backend_t backend, if (!dest_file) goto change_one_err; - while (fgets (line, LINE_LEN, dest_file)) + while ((length = getline (&line, &line_len, dest_file)) > 0) { - int length; int disable = 0; char *start; char *end; - line[LINE_LEN - 1] = '\0'; - length = strlen (line); - if (length == LINE_LEN - 1) - { - /* FIXME */ - errno = ENAMETOOLONG; - goto change_one_err; - } - if (!strncmp (marker, line, sizeof (marker) - 1)) { if (!in_marker) @@ -1048,7 +1042,8 @@ change_options_program (gc_component_t component, gc_backend_t backend, if (!in_marker) { fprintf (src_file, - "# GPGConf disabled this option here at FIXME\n"); + "# GPGConf disabled this option here at %s\n", + asctimestamp (gnupg_get_time ())); if (ferror (src_file)) goto change_one_err; fprintf (src_file, "# %s", line); @@ -1103,11 +1098,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, option++; } { - time_t cur_time = time (NULL); - - /* asctime() returns a string that ends with a newline - character! */ - fprintf (src_file, "%s %s", marker, asctime (localtime (&cur_time))); + fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); if (ferror (src_file)) goto change_one_err; } @@ -1126,18 +1117,8 @@ change_options_program (gc_component_t component, gc_backend_t backend, } if (dest_file) { - while (fgets (line, LINE_LEN, dest_file)) + while ((length = getline (&line, &line_len, dest_file)) > 0) { - int length; - - line[LINE_LEN - 1] = '\0'; - length = strlen (line); - if (length == LINE_LEN - 1) - { - /* FIXME */ - errno = ENAMETOOLONG; - goto change_one_err; - } fprintf (src_file, "%s", line); if (ferror (src_file)) goto change_one_err; @@ -1222,7 +1203,7 @@ gc_component_change_options (int component, FILE *in) option = find_option (component, line, GC_BACKEND_ANY); if (!option) - error (1, 0, "Unknown option %s", line); + error (1, 0, "unknown option %s", line); option_check_validity (option, value); option->new_value = strdup (value); @@ -1291,7 +1272,7 @@ gc_component_change_options (int component, FILE *in) if (err) { int i; - int res = errno; + int saved_errno = errno; /* An error occured. */ for (i = 0; i < GC_COMPONENT_NR; i++) @@ -1315,7 +1296,6 @@ gc_component_change_options (int component, FILE *in) unlink (dest_pathname[i]); } } - errno = res; - error (1, 1, "Could not commit changes"); + error (1, saved_errno, "could not commit changes"); } } -- cgit From 74a20c31e3c15d81c3258dc66ca235034e575cfa Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 30 Jan 2004 12:15:53 +0000 Subject: 2004-01-30 Marcus Brinkmann * gpgconf-comp.c (gc_error): New function, use it instead of error() throughout. --- tools/ChangeLog | 3 ++ tools/gpgconf-comp.c | 87 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 25 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index a9254bd99..a91f4fe68 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,8 @@ 2004-01-30 Marcus Brinkmann + * gpgconf-comp.c (gc_error): New function, use it instead of + error() throughout. + * gpgconf-comp.c: Use xmalloc, libcommon's asctimestamp and gnupg_get_time, fix error() invocation and use getline() consistently. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5a1629fb8..a6bda075d 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -31,24 +31,61 @@ #include #include #include +#include -#include - -/* For asctimestamp(), gnupg_get_time (). */ +/* For log_logv(), asctimestamp(), gnupg_get_time (). */ +#define JNLIB_NEED_LOG_LOGV #include "util.h" #include "gpgconf.h" /* TODO: - Portability - Add gnulib replacements for getline, error, etc. + Portability - Add gnulib replacements for getline, etc. Backend: File backend must be able to write out changes !!! Components: Add more components and their options. Robustness: Do more validation. Call programs to do validation for us. Don't use popen, as this will not tell us if the program had a non-zero exit code. + Add options to change backend binary path. + Extract binary path for some backends from gpgsm/gpg config. */ + +#if defined (__riscos__) \ + || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) +void gc_error (int status, int errnum, const char *fmt, ...) \ + __attribute__ ((format (printf, 3, 4))); +#endif + +/* Output a diagnostic message. If ERRNUM is not 0, then the output + is followed by a colon, a white space, and the error string for the + error number ERRNUM. In any case the output is finished by a + newline. The message is prepended by the program name, a colon, + and a whitespace. The output may be further formatted or + redirected by the jnlib logging facility. */ +void +gc_error (int status, int errnum, const char *fmt, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, fmt); + log_logv (JNLIB_LOG_ERROR, fmt, arg_ptr); + va_end (arg_ptr); + + if (errnum) + log_printf (": %s\n", strerror (errnum)); + else + log_printf ("\n"); + + if (status) + { + log_printf (NULL); + log_printf ("fatal error (exit status %i)\n", status); + exit (status); + } +} + /* Backend configuration. Backends are used to decide how the default and current value of an option can be determined, and how the @@ -498,7 +535,7 @@ percent_escape (const char *src) { char *new_esc_str = realloc (esc_str, new_len); if (!new_esc_str) - error (1, errno, "can not escape string"); + gc_error (1, errno, "can not escape string"); esc_str = new_esc_str; esc_str_len = new_len; } @@ -709,18 +746,18 @@ get_config_pathname (gc_component_t component, gc_backend_t backend) assert (option); if (!option->default_value) - error (1, 0, "option %s, needed by backend %s, was not initialized", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); + gc_error (1, 0, "option %s, needed by backend %s, was not initialized", + gc_backend[backend].option_config_filename, + gc_backend[backend].name); if (*option->value) pathname = option->value; else pathname = option->default_value; if (*pathname != '/') - error (1, 0, "option %s, needed by backend %s, is not absolute", - gc_backend[backend].option_config_filename, - gc_backend[backend].name); + gc_error (1, 0, "option %s, needed by backend %s, is not absolute", + gc_backend[backend].option_config_filename, + gc_backend[backend].name); return pathname; } @@ -739,11 +776,11 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) asprintf (&cmd_line, "%s --gpgconf-list", gc_backend[backend].program); if (!cmd_line) - error (1, errno, "can not construct command line"); + gc_error (1, errno, "can not construct command line"); output = popen (cmd_line, "r"); if (!output) - error (1, errno, "could not gather active options from %s", cmd_line); + gc_error (1, errno, "could not gather active options from %s", cmd_line); while ((length = getline (&line, &line_len, output)) > 0) { @@ -787,18 +824,18 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) if (option) { if (option->default_value) - error (1, errno, "option %s returned twice from %s", - line, cmd_line); + gc_error (1, errno, "option %s returned twice from %s", + line, cmd_line); option->default_value = strdup (default_value); option->value = strdup (value); if (!option->default_value || !option->value) - error (1, errno, "could not store options"); + gc_error (1, errno, "could not store options"); } } if (ferror (output)) - error (1, errno, "error reading from %s", cmd_line); + gc_error (1, errno, "error reading from %s", cmd_line); if (fclose (output) && ferror (output)) - error (1, errno, "error closing %s", cmd_line); + gc_error (1, errno, "error closing %s", cmd_line); free (cmd_line); } @@ -824,11 +861,11 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) list_file = fopen (list_pathname, "r"); if (ferror (list_file)) - error (1, errno, "can not open list file %s", list_pathname); + gc_error (1, errno, "can not open list file %s", list_pathname); list = strdup ("\""); if (!list) - error (1, errno, "can not allocate initial list string"); + gc_error (1, errno, "can not allocate initial list string"); while ((length = getline (&line, &line_len, list_file)) > 0) { @@ -861,10 +898,10 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) list = new_list; } if (!list) - error (1, errno, "can not construct list"); + gc_error (1, errno, "can not construct list"); } if (ferror (list_file)) - error (1, errno, "can not read list file %s", list_pathname); + gc_error (1, errno, "can not read list file %s", list_pathname); list_option->default_value = ""; list_option->value = list; } @@ -912,7 +949,7 @@ static void option_check_validity (gc_option_t *option, const char *new_value) { if (option->new_value) - error (1, 0, "option %s already changed", option->name); + gc_error (1, 0, "option %s already changed", option->name); if (!*new_value) return; @@ -1203,7 +1240,7 @@ gc_component_change_options (int component, FILE *in) option = find_option (component, line, GC_BACKEND_ANY); if (!option) - error (1, 0, "unknown option %s", line); + gc_error (1, 0, "unknown option %s", line); option_check_validity (option, value); option->new_value = strdup (value); @@ -1296,6 +1333,6 @@ gc_component_change_options (int component, FILE *in) unlink (dest_pathname[i]); } } - error (1, saved_errno, "could not commit changes"); + gc_error (1, saved_errno, "could not commit changes"); } } -- cgit From cff3f7686269b994ec47ee9e1400c84a7893fd1f Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sat, 31 Jan 2004 13:58:27 +0000 Subject: 2004-01-31 Marcus Brinkmann * gpgconf-comp.c: Some bug fixes, parse only defaults from the program, and read the current values from the configuration file directly. --- tools/ChangeLog | 6 + tools/gpgconf-comp.c | 308 ++++++++++++++++++++++++++++++++++----------------- 2 files changed, 210 insertions(+), 104 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 1d2181227..110a434d7 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,9 @@ +2004-01-31 Marcus Brinkmann + + * gpgconf-comp.c: Some bug fixes, parse only defaults from the + program, and read the current values from the configuration file + directly. + 2004-01-30 Marcus Brinkmann * gpgconf-comp.c (gc_error): New function, use it instead of diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index a6bda075d..fc3d4edcf 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1,5 +1,5 @@ /* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2003 g10 Code GmbH + Copyright (C) 2004 g10 Code GmbH This file is part of GnuPG. @@ -143,10 +143,10 @@ static struct } gc_backend[GC_BACKEND_NR] = { { NULL, NULL, NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", "gpgconf-config-file" }, - { "GPGSM", "gpgsm", "gpgconf-config-file" }, - { "GPG Agent", "gpg-agent", "gpgconf-config-file" }, - { "DirMngr", "dirmngr", "gpgconf-config-file" }, + { "GnuPG", "gpg", "gpgconf-gpg.conf" }, + { "GPGSM", "gpgsm", "gpgconf-gpgsm.conf" }, + { "GPG Agent", "gpg-agent", "gpgconf-gpg-agent.conf" }, + { "DirMngr", "dirmngr", "gpgconf-dirmngr.conf" }, { "DirMngr LDAP Server List", NULL, "ldapserverlist-file", "LDAP Server" }, }; @@ -341,6 +341,10 @@ struct gc_option of the list so that they can be omitted from the option declarations. */ + /* This is true if the option is supported by this version of the + backend. */ + int active; + /* The default value for this option. This is NULL if the option is not present in the backend, the empty string if no default is available, and otherwise a quoted string. */ @@ -369,13 +373,13 @@ static gc_option_t gc_options_gpg_agent[] = static gc_option_t gc_options_dirmngr[] = { /* The configuration file to which we write the changes. */ - { "gpgconf-config-file", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + { "gpgconf-dirmngr.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, "dirmngr", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, @@ -616,7 +620,7 @@ gc_component_list_options (int component, FILE *out) char *arg_name = NULL; /* Do not output unknown or internal options. */ - if (!option->default_value || option->level == GC_LEVEL_INTERNAL) + if (!option->active || option->level == GC_LEVEL_INTERNAL) { option++; continue; @@ -740,26 +744,29 @@ find_option (gc_component_t component, const char *name, static char * get_config_pathname (gc_component_t component, gc_backend_t backend) { - char *pathname; + char *pathname = NULL; gc_option_t *option = find_option (component, gc_backend[backend].option_config_filename, GC_BACKEND_ANY); assert (option); + assert (option->arg_type == GC_ARG_TYPE_PATHNAME); + assert (!(option->flags & GC_OPT_FLAG_LIST)); - if (!option->default_value) - gc_error (1, 0, "option %s, needed by backend %s, was not initialized", + if (!option->active || !option->default_value) + gc_error (1, 0, "Option %s, needed by backend %s, was not initialized", gc_backend[backend].option_config_filename, gc_backend[backend].name); - if (*option->value) + + if (option->value && *option->value) pathname = option->value; else pathname = option->default_value; - if (*pathname != '/') - gc_error (1, 0, "option %s, needed by backend %s, is not absolute", + if (pathname[1] != '/') + gc_error (1, 0, "Option %s, needed by backend %s, is not absolute", gc_backend[backend].option_config_filename, gc_backend[backend].name); - return pathname; + return &pathname[1]; } @@ -772,20 +779,18 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) char *line = NULL; size_t line_len = 0; ssize_t length; - FILE *output; + FILE *config; + char *config_pathname; - asprintf (&cmd_line, "%s --gpgconf-list", gc_backend[backend].program); - if (!cmd_line) - gc_error (1, errno, "can not construct command line"); + cmd_line = xasprintf ("%s --gpgconf-list", gc_backend[backend].program); - output = popen (cmd_line, "r"); - if (!output) + config = popen (cmd_line, "r"); + if (!config) gc_error (1, errno, "could not gather active options from %s", cmd_line); - while ((length = getline (&line, &line_len, output)) > 0) + while ((length = getline (&line, &line_len, config)) > 0) { gc_option_t *option; - char *default_value; char *value; /* Strip newline and carriage return, if present. */ @@ -793,29 +798,19 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) && (line[length - 1] == '\n' || line[length - 1] == '\r')) line[--length] = '\0'; - /* Extract default value and value, if present. Default to - empty if not. */ - default_value = strchr (line, ':'); - if (!default_value) - { - default_value = ""; - value = ""; - } + /* Extract default value, if present. Default to empty if + not. */ + value = strchr (line, ':'); + if (!value) + value = ""; else { - *(default_value++) = '\0'; - value = strchr (default_value, ':'); - if (!value) - value = ""; - else - { - char *end; + char *end; - *(value++) = '\0'; - end = strchr (value, ':'); - if (end) - *end = '\0'; - } + *(value++) = '\0'; + end = strchr (value, ':'); + if (end) + *end = '\0'; } /* Look up the option in the component and install the @@ -823,20 +818,122 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) option = find_option (component, line, backend); if (option) { - if (option->default_value) + if (option->active) gc_error (1, errno, "option %s returned twice from %s", line, cmd_line); - option->default_value = strdup (default_value); - option->value = strdup (value); - if (!option->default_value || !option->value) - gc_error (1, errno, "could not store options"); + option->active = 1; + if (*value) + option->default_value = xstrdup (value); } } - if (ferror (output)) + if (ferror (config)) gc_error (1, errno, "error reading from %s", cmd_line); - if (fclose (output) && ferror (output)) + if (fclose (config) && ferror (config)) gc_error (1, errno, "error closing %s", cmd_line); - free (cmd_line); + xfree (cmd_line); + + /* At this point, we can parse the configuration file. */ + config_pathname = get_config_pathname (component, backend); + + config = fopen (config_pathname, "r"); + if (!config) + gc_error (0, errno, "warning: can not open config file %s", + config_pathname); + else + { + while ((length = getline (&line, &line_len, config)) > 0) + { + char *name; + char *value; + gc_option_t *option; + + name = line; + while (*name == ' ' || *name == '\t') + name++; + if (!*name || *name == '#' || *name == '\r' || *name == '\n') + continue; + + value = name; + while (*value && *value != ' ' && *value != '\t' + && *value != '#' && *value != '\r' && *value != '\n') + value++; + if (*value == ' ' || *value == '\t') + { + char *end; + + *(value++) = '\0'; + while (*value == ' ' || *value == '\t') + value++; + + end = value; + while (*end && *end != '#' && *end != '\r' && *end != '\n') + end++; + while (end > value && (end[-1] == ' ' || end[-1] == '\t')) + end--; + *end = '\0'; + } + else + *value = '\0'; + + /* Look up the option in the component and install the + configuration data. */ + option = find_option (component, line, backend); + if (option) + { + char *opt_value; + + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) + { + if (*value) + gc_error (0, 0, + "warning: ignoring argument %s for option %s", + value, name); + opt_value = xstrdup ("Y"); + } + else if (gc_arg_type[option->arg_type].fallback + == GC_ARG_TYPE_STRING) + opt_value = xasprintf ("\"%s", percent_escape (value)); + else + { + /* FIXME: Verify that the number is sane. */ + opt_value = xstrdup (value); + } + + /* Now enter the option into the table. */ + if (!(option->flags & GC_OPT_FLAG_LIST)) + { + if (option->value) + free (option->value); + option->value = opt_value; + } + else + { + if (!option->value) + option->value = opt_value; + else + { + char *opt_val = opt_value; + + if (gc_arg_type[option->arg_type].fallback + == GC_ARG_TYPE_STRING) + opt_val++; + + option->value = xasprintf ("%s,%s", option->value, + opt_val); + xfree (opt_value); + } + } + } + } + + if (ferror (config)) + gc_error (1, errno, "error reading from %s", config_pathname); + if (fclose (config) && ferror (config)) + gc_error (1, errno, "error closing %s", config_pathname); + } + + if (line) + free (line); } @@ -851,59 +948,62 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) char *line = NULL; size_t line_len = 0; ssize_t length; - char *list; + char *list = NULL; list_option = find_option (component, gc_backend[backend].option_name, GC_BACKEND_ANY); assert (list_option); + assert (!list_option->active); list_pathname = get_config_pathname (component, backend); - list_file = fopen (list_pathname, "r"); - if (ferror (list_file)) - gc_error (1, errno, "can not open list file %s", list_pathname); - - list = strdup ("\""); - if (!list) - gc_error (1, errno, "can not allocate initial list string"); - - while ((length = getline (&line, &line_len, list_file)) > 0) + if (!list_file) + gc_error (0, errno, "warning: can not open list file %s", list_pathname); + else { - char *start; - char *end; - char *new_list; - - start = line; - while (*start == ' ' || *start == '\t') - start++; - if (!*start || *start == '#' || *start == '\r' || *start == '\n') - continue; - - end = start; - while (*end && *end != '#' && *end != '\r' && *end != '\n') - end++; - /* Walk back to skip trailing white spaces. Looks evil, but - works because of the conditions on START and END imposed - at this point (END is at least START + 1, and START is - not a whitespace character). */ - while (*(end - 1) == ' ' || *(end - 1) == '\t') - end--; - *end = '\0'; - /* FIXME: Oh, no! This is so lame! Use realloc and really - append. */ - if (list) + + while ((length = getline (&line, &line_len, list_file)) > 0) { - asprintf (&new_list, "%s,%s", list, percent_escape (start)); - free (list); - list = new_list; + char *start; + char *end; + char *new_list; + + start = line; + while (*start == ' ' || *start == '\t') + start++; + if (!*start || *start == '#' || *start == '\r' || *start == '\n') + continue; + + end = start; + while (*end && *end != '#' && *end != '\r' && *end != '\n') + end++; + /* Walk back to skip trailing white spaces. Looks evil, but + works because of the conditions on START and END imposed + at this point (END is at least START + 1, and START is + not a whitespace character). */ + while (*(end - 1) == ' ' || *(end - 1) == '\t') + end--; + *end = '\0'; + /* FIXME: Oh, no! This is so lame! Use realloc and really + append. */ + if (list) + { + new_list = xasprintf ("%s,%s", list, percent_escape (start)); + xfree (list); + list = new_list; + } + else + list = xasprintf ("\"%s", percent_escape (start)); } - if (!list) - gc_error (1, errno, "can not construct list"); + if (ferror (list_file)) + gc_error (1, errno, "can not read list file %s", list_pathname); } - if (ferror (list_file)) - gc_error (1, errno, "can not read list file %s", list_pathname); - list_option->default_value = ""; + + list_option->active = 1; list_option->value = list; + + if (line) + free (line); } @@ -983,7 +1083,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, /* True if we are within the marker in the config file. */ int in_marker = 0; gc_option_t *option; - char *line; + char *line = NULL; size_t line_len; ssize_t length; int res; @@ -995,22 +1095,16 @@ change_options_program (gc_component_t component, gc_backend_t backend, char *orig_filename; /* FIXME. Throughout the function, do better error reporting. */ - dest_filename = strdup (get_config_pathname (component, backend)); - if (!dest_filename) - return -1; - asprintf (&src_filename, "%s.gpgconf.%i.new", dest_filename, getpid ()); - if (!src_filename) - return -1; - asprintf (&orig_filename, "%s.gpgconf.%i.bak", dest_filename, getpid ()); - if (!orig_filename) - return -1; + dest_filename = xstrdup (get_config_pathname (component, backend)); + src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); + orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); res = link (dest_filename, orig_filename); if (res < 0 && errno != ENOENT) return -1; if (res < 0) { - free (orig_filename); + xfree (orig_filename); orig_filename = NULL; } /* We now initialize the return strings, so the caller can do the @@ -1163,6 +1257,8 @@ change_options_program (gc_component_t component, gc_backend_t backend, if (ferror (dest_file)) goto change_one_err; } + if (line) + free (line); res = fclose (src_file); if (res) { @@ -1183,6 +1279,8 @@ change_options_program (gc_component_t component, gc_backend_t backend, return 0; change_one_err: + if (line) + free (line); res = errno; if (src_file) { @@ -1243,7 +1341,7 @@ gc_component_change_options (int component, FILE *in) gc_error (1, 0, "unknown option %s", line); option_check_validity (option, value); - option->new_value = strdup (value); + option->new_value = xstrdup (value); } /* Now that we have collected and locally verified the changes, @@ -1335,4 +1433,6 @@ gc_component_change_options (int component, FILE *in) } gc_error (1, saved_errno, "could not commit changes"); } + if (line) + free (line); } -- cgit From bdae155c7b22e0fbe36a5f5e6ca13c298475c37e Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 1 Feb 2004 15:30:50 +0000 Subject: Fix copyright line. --- tools/gpgconf-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index fc3d4edcf..efe2bf5a8 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1,5 +1,5 @@ /* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2004 g10 Code GmbH + Copyright (C) 2004 Free Software Foundation, Inc. This file is part of GnuPG. -- cgit From e588e13d7c85388db70b75c18273ba79715ecd3d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 18 Feb 2004 17:00:56 +0000 Subject: Added empty components for gpgsm and scdaemon. --- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index bd99271d6..7796acbed 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-02-18 Werner Koch + + * gpgconf-comp.c: Added empty components for gpgsm and scdaemon. + 2004-02-12 Werner Koch * watchgnupg.c (main): Implement option "--". diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index efe2bf5a8..857ba0840 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -369,6 +369,20 @@ static gc_option_t gc_options_gpg_agent[] = }; +/* The options of the GC_COMPONENT_SCDAEMON component. */ +static gc_option_t gc_options_scdaemon[] = + { + GC_OPTION_NULL + }; + + +/* The options of the GC_COMPONENT_GPGSM component. */ +static gc_option_t gc_options_gpgsm[] = + { + GC_OPTION_NULL + }; + + /* The options of the GC_COMPONENT_DIRMNGR component. */ static gc_option_t gc_options_dirmngr[] = { @@ -479,6 +493,12 @@ typedef enum /* The GPG Agent. */ GC_COMPONENT_GPG_AGENT, + /* The Smardcard Daemon. */ + GC_COMPONENT_SCDAEMON, + + /* GPG for S/MIME. */ + GC_COMPONENT_GPGSM, + /* The LDAP Directory Manager for CRLs. */ GC_COMPONENT_DIRMNGR, @@ -507,6 +527,8 @@ static struct } gc_component[] = { { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, + { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, + { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } }; -- cgit From c38f60920601f859c4877d2fa532178b3c01084b Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 23 Feb 2004 19:37:04 +0000 Subject: 2004-02-23 Marcus Brinkmann * gpgconf-comp.c (hextobyte): New function. (percent_deescape): New function. (get_config_pathname): Percent deescape pathname if taken from option (default) value. Use default value only if it exists and is not empty. Use empty string otherwise. Don't include leading quote in pathname. (change_options_program): Percent deescape string before writing it out. --- tools/ChangeLog | 14 ++++++++ tools/gpgconf-comp.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 11 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 7796acbed..4c55ed4fe 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,17 @@ +2004-02-23 Marcus Brinkmann + + * gpgconf-comp.c (hextobyte): New function. + (percent_deescape): New function. + (get_config_pathname): Percent deescape pathname if taken from + option (default) value. Use default value only if it exists and + is not empty. Use empty string otherwise. Don't include leading + quote in pathname. + (change_options_program): Percent deescape string before writing + it out. + + * gpgconf-comp.c (gc_component_list_options): Do not skip groups + on output. + 2004-02-18 Werner Koch * gpgconf-comp.c: Added empty components for gpgsm and scdaemon. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 857ba0840..2065a6587 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -598,6 +598,74 @@ percent_escape (const char *src) } +/* Convert two hexadecimal digits from STR to the value they + represent. Returns -1 if one of the characters is not a + hexadecimal digit. */ +static int +hextobyte (const char *str) +{ + int val = 0; + int i; + +#define NROFHEXDIGITS 2 + for (i = 0; i < NROFHEXDIGITS; i++) + { + if (*str >= '0' && *str <= '9') + val += *str - '0'; + else if (*str >= 'A' && *str <= 'F') + val += 10 + *str - 'A'; + else if (*str >= 'a' && *str <= 'f') + val += 10 + *str - 'a'; + else + return -1; + if (i < NROFHEXDIGITS - 1) + val *= 16; + str++; + } + return val; +} + + + +/* Percent-Deescape special characters. The string is valid until the + next invocation of the function. */ +static char * +percent_deescape (const char *src) +{ + static char *str; + static int str_len; + int new_len = 3 * strlen (src) + 1; + char *dst; + + if (str_len < new_len) + { + char *new_str = realloc (str, new_len); + if (!new_str) + gc_error (1, errno, "can not deescape string"); + str = new_str; + str_len = new_len; + } + + dst = str; + while (*src) + { + if (*src == '%') + { + int val = hextobyte (src + 1); + + if (val < 0) + gc_error (1, 0, "malformed end of string %s", src); + + *(dst++) = (char) val; + src += 3; + } + else + *(dst++) = *(src++); + } + *dst = '\0'; + return str; +} + /* List all components that are available. */ void @@ -642,7 +710,8 @@ gc_component_list_options (int component, FILE *out) char *arg_name = NULL; /* Do not output unknown or internal options. */ - if (!option->active || option->level == GC_LEVEL_INTERNAL) + if (!(option->flags & GC_OPT_FLAG_GROUP) + && (!option->active || option->level == GC_LEVEL_INTERNAL)) { option++; continue; @@ -779,16 +848,18 @@ get_config_pathname (gc_component_t component, gc_backend_t backend) gc_backend[backend].name); if (option->value && *option->value) - pathname = option->value; + pathname = percent_deescape (&option->value[1]); + else if (option->default_value && *option->default_value) + pathname = percent_deescape (&option->default_value[1]); else - pathname = option->default_value; + pathname = ""; - if (pathname[1] != '/') + if (pathname[0] != '/') gc_error (1, 0, "Option %s, needed by backend %s, is not absolute", gc_backend[backend].option_config_filename, gc_backend[backend].name); - return &pathname[1]; + return pathname; } @@ -1234,13 +1305,15 @@ change_options_program (gc_component_t component, gc_backend_t backend, option = gc_component[component].options; while (option->name) { + /* FIXME: Add support for lists. */ if (!(option->flags & GC_OPT_FLAG_GROUP) && option->backend == backend && option->new_value && *option->new_value) { if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - fprintf (src_file, "%s %s\n", option->name, &option->new_value[1]); + fprintf (src_file, "%s %s\n", option->name, + percent_deescape (&option->new_value[1])); else if (option->arg_type == GC_ARG_TYPE_NONE) fprintf (src_file, "%s\n", option->name); else @@ -1250,11 +1323,11 @@ change_options_program (gc_component_t component, gc_backend_t backend, } option++; } - { - fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); - if (ferror (src_file)) - goto change_one_err; - } + + fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); + if (ferror (src_file)) + goto change_one_err; + if (!in_marker) { fprintf (src_file, "# GPGConf edited this configuration file.\n"); -- cgit From 54d5446797fc4c1e40e36a74fa7fa12c87ba5ab9 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 24 Feb 2004 14:31:59 +0000 Subject: 2004-02-24 Marcus Brinkmann * README.gpgconf: Revert last change. Add new flags "default", "default desc" and "no arg desc". Add new field ARGDEF. Add new field FLAG to backend interface. * gpgconf-comp.c (struct gc_option): Make flags of type unsigned long. (gc_component_list_options): Adjust type for flags. Add default argument field. (retrieve_options_from_program): Use "1" as value for non-option arguments, not "Y". (gc_component_change_options): Read in flags from input. --- tools/ChangeLog | 13 ++++ tools/README.gpgconf | 140 ++++++++++++++++++++++++++++++++++------- tools/gpgconf-comp.c | 173 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 266 insertions(+), 60 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 1871f8b15..efb3794b9 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,16 @@ +2004-02-24 Marcus Brinkmann + + * README.gpgconf: Revert last change. Add new flags "default", + "default desc" and "no arg desc". Add new field ARGDEF. Add new + field FLAG to backend interface. + * gpgconf-comp.c (struct gc_option): Make flags of type unsigned + long. + (gc_component_list_options): Adjust type for flags. + Add default argument field. + (retrieve_options_from_program): Use "1" as value for non-option + arguments, not "Y". + (gc_component_change_options): Read in flags from input. + 2004-02-23 Marcus Brinkmann * README.gpgconf: Change meaning of type 0 options value if it is diff --git a/tools/README.gpgconf b/tools/README.gpgconf index 848e1c59f..84fed518b 100644 --- a/tools/README.gpgconf +++ b/tools/README.gpgconf @@ -82,9 +82,8 @@ argument depends on the type of the option and on some flags: The simplest case is that the option does not take an argument at all (TYPE is 0). Then the option argument is either empty if the option is not set, or an unsigned number that specifies how often the option -occurs. If the LIST flag is not set, then the only valid numbers are -0 and 1. 0 often has a special meaning in this context as it actually -negates setting the option one or more times. +occurs. If the LIST flag is not set, then the only valid number is 1. +Options that don't take an argument never have the "default" flag set. If the option takes a number argument (ALT-TYPE is 2 or 3), and it can only occur once (LIST flag is not set), then the option argument is @@ -175,7 +174,7 @@ the next group and so on. The format of each line is: -NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:VALUE +NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE NAME @@ -189,13 +188,19 @@ FLAGS The flags field contains an unsigned number. Its value is the OR-wise combination of the following flag values: - 1 group If this flag is set, this is a line describing + 1 group If this flag is set, this is a line describing a group and not an option. - O 2 optional arg If this flag is set, the argument is optional. - O 4 list If this flag is set, the option can be given + O 2 optional arg If this flag is set, the argument is optional. + O 4 list If this flag is set, the option can be given multiple times. - O 8 runtime If this flag is set, the option can be changed + O 8 runtime If this flag is set, the option can be changed at runtime. + O 16 default If this flag is set, a default value is available. + O 32 default desc If this flag is set, a (runtime) default is available. + This and the 'default' flag are mutually exclusive. + O 64 no arg desc If this flag is set, and the 'optional arg' flag + is set, then the option has a special meaning if no + argument is given. Flags marked with a 'O' are only defined for options (ie, if the GROUP flag is not set). @@ -230,13 +235,16 @@ This field is only defined for options. It contains an unsigned number that specifies the type of the option's argument, if any. The following types are defined: - 0 none No argument allowed. - 1 string An unformatted string. - 2 int32 A signed integer number. - 3 uint32 An unsigned integer number. - 4 pathname A string that describes the pathname of a file. + Basic types + 0 none No argument allowed. + 1 string An unformatted string. + 2 int32 A signed integer number. + 3 uint32 An unsigned integer number. + + Complex types + 32 pathname A string that describes the pathname of a file. The file does not necessarily need to exist. - 5 ldap server A string that describes an LDAP server in the format + 33 ldap server A string that describes an LDAP server in the format HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. More types will be added in the future. Please see the ALT-TYPE field @@ -244,12 +252,14 @@ for information on how to cope with unknown types. ALT-TYPE -This field is identical to TYPE, except that only the types 0 to 3 are -allowed. The GUI is expected to present the user the option in the -format specified by TYPE. But if the argument type TYPE is not +This field is identical to TYPE, except that only the types 0 to 31 +are allowed. The GUI is expected to present the user the option in +the format specified by TYPE. But if the argument type TYPE is not supported by the GUI, it can still display the option in the more -generic basic type ALT-TYPE. The GUI must support the basic types 0 -to 3 to be able to display all options. +generic basic type ALT-TYPE. The GUI must support all the defined +basic types to be able to display all options. More basic types may +be added in future versions. If the GUI encounters a basic type it +doesn't support, it should report an error and abort the operation. ARGNAME @@ -267,6 +277,18 @@ value specifies the default value for this option. Note that this field is also meaningful if the option itself does not take a real argument. +ARGDEF + +This field is defined only for options for which the "optional arg" +flag is set. If the "no arg desc" flag is not set, its format is that +of an option argument (see section Format Conventions for details). +If the default value is empty, then no default is known. Otherwise, +the value specifies the default value for this option. If the "no arg +desc" flag is set, the field is either empty or contains a description +of the effect of this option if no argument is given. Note that this +field is also meaningful if the option itself does not take a real +argument. + VALUE This field is defined only for options. Its format is that of an @@ -283,18 +305,35 @@ CHANGING OPTIONS To change the options for a component, you must provide them in the following format: -NAME:NEW-VALUE +NAME:FLAGS:NEW-VALUE NAME This is the name of the option to change. +FLAGS + +The flags field contains an unsigned number. Its value is the +OR-wise combination of the following flag values: + + 16 default If this flag is set, the option is deleted and the + default value is used instead (if applicable). + NEW-VALUE -The new value for the option. The format is that of an option -argument. If it is empty (or the field is omitted), the option will -be deleted, so that the default value is used. Otherwise, the option -will be set to the specified value. +The new value for the option. This field is only defined if the +"default" flag is not set. The format is that of an option argument. +If it is empty (or the field is omitted), the default argument is used +(only allowed if the argument is optional for this option). +Otherwise, the option will be set to the specified value. + + +Example: +To set the option force, which is of basic type 0 (none). +$ echo 'force:0:1' | gpgconf --change-options dirmngr +To delete the option force: +$ echo 'force:16:0' | gpgconf --change-options dirmngr + Option --runtime ---------------- @@ -316,9 +355,62 @@ List the location of the configuration file, and all default values of all options. The location of the configuration file must be an absolute pathname. +The format of each line is: + +NAME:FLAGS:DEFAULT:ARGDEF + +NAME + +This field contains a name tag for the group or option. The name tag +is used to specify the group or option in all communication with +GPGConf. The name tag is to be used verbatim. It is not in any +escaped format. + +FLAGS + +The flags field contains an unsigned number. Its value is the +OR-wise combination of the following flag values: + + 16 default If this flag is set, a default value is available. + 32 default desc If this flag is set, a (runtime) default is available. + This and the "default" flag are mutually exclusive. + 64 no arg desc If this flag is set, and the "optional arg" flag + is set, then the option has a special meaning if no + argument is given. + +DEFAULT + +This field is defined only for options. Its format is that of an +option argument (see section Format Conventions for details). If the +default value is empty, then no default is known. Otherwise, the +value specifies the default value for this option. Note that this +field is also meaningful if the option itself does not take a real +argument. + +ARGDEF + +This field is defined only for options for which the "optional arg" +flag is set. If the "no arg desc" flag is not set, its format is that +of an option argument (see section Format Conventions for details). +If the default value is empty, then no default is known. Otherwise, +the value specifies the default value for this option. If the "no arg +desc" flag is set, the field is either empty or contains a description +of the effect of this option if no argument is given. Note that this +field is also meaningful if the option itself does not take a real +argument. + + Example: $ dirmngr --gpgconf-list gpgconf-config-file:/mnt/marcus/.gnupg/dirmngr.conf ldapservers-file:/mnt/marcus/.gnupg/dirmngr_ldapservers.conf add-servers:0 max-replies:10 + + +TODO +---- + +* Extend the backend interface to include gettext domain and +description, if available, to avoid repeating this information in +gpgconf. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 2065a6587..4dc2fbbe8 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -176,20 +176,21 @@ typedef enum /* An unsigned integer argument. */ GC_ARG_TYPE_UINT32 = 3, + /* ADD NEW BASIC TYPE ENTRIES HERE. */ /* Complex argument types. */ /* A complete pathname. */ - GC_ARG_TYPE_PATHNAME = 4, + GC_ARG_TYPE_PATHNAME = 32, /* An LDAP server in the format HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN. */ - GC_ARG_TYPE_LDAP_SERVER = 5, + GC_ARG_TYPE_LDAP_SERVER = 33, /* A 40 character fingerprint. */ - GC_ARG_TYPE_KEY_FPR = 6, + GC_ARG_TYPE_KEY_FPR = 34, - /* ADD NEW ENTRIES HERE. */ + /* ADD NEW COMPLEX TYPE ENTRIES HERE. */ /* The number of the above entries. */ GC_ARG_TYPE_NR @@ -214,6 +215,22 @@ static struct { GC_ARG_TYPE_INT32, "int32" }, { GC_ARG_TYPE_UINT32, "uint32" }, + /* Reserved basic type entries for future extension. */ + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + { GC_ARG_TYPE_NR, NULL }, { GC_ARG_TYPE_NR, NULL }, + /* The complex argument types have a basic type as fallback. */ { GC_ARG_TYPE_STRING, "pathname" }, { GC_ARG_TYPE_STRING, "ldap server" }, @@ -266,21 +283,32 @@ static struct /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */ -#define GC_OPT_FLAG_NONE 0 +#define GC_OPT_FLAG_NONE 0UL /* Some entries in the option list are not options, but mark the beginning of a new group of options. These entries have the GROUP flag set. */ -#define GC_OPT_FLAG_GROUP (1 << 0) +#define GC_OPT_FLAG_GROUP (1UL << 0) /* The ARG_OPT flag for an option indicates that the argument is optional. */ -#define GC_OPT_FLAG_ARG_OPT (1 << 1) +#define GC_OPT_FLAG_ARG_OPT (1UL << 1) /* The LIST flag for an option indicates that the option can occur several times. A comma separated list of arguments is used as the argument value. */ -#define GC_OPT_FLAG_LIST (1 << 2) +#define GC_OPT_FLAG_LIST (1UL << 2) /* The RUNTIME flag for an option indicates that the option can be changed at runtime. */ -#define GC_OPT_FLAG_RUNTIME (1 << 3) +#define GC_OPT_FLAG_RUNTIME (1UL << 3) + +/* The following flags are incorporated from the backend. */ +/* The DEFAULT flag for an option indicates that the option has a + default value. */ +#define GC_OPT_FLAG_DEFAULT (1UL << 4) +/* The DEF_DESC flag for an option indicates that the option has a + default, which is described by the value of the default field. */ +#define GC_OPT_FLAG_DEF_DESC (1UL << 5) +/* The NO_ARG_DESC flag for an option indicates that the argument has + a default, which is described by the value of the ARGDEF field. */ +#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) /* A human-readable description for each flag. */ static struct @@ -311,7 +339,7 @@ struct gc_option group marker, not an option, and only the fields LEVEL, DESC_DOMAIN and DESC are valid. In all other cases, this entry describes a new option and all fields are valid. */ - unsigned int flags; + unsigned long flags; /* The expert level. This field is valid for options and groups. A group has the expert level of the lowest-level option in the @@ -350,6 +378,11 @@ struct gc_option available, and otherwise a quoted string. */ char *default_value; + /* The default argument is only valid if the "optional arg" flag is + set, and specifies the default argument (value) that is used if + the argument is omitted. */ + char *default_arg; + /* The current value of this option. */ char *value; @@ -744,7 +777,7 @@ gc_component_list_options (int component, FILE *out) fprintf (out, "%s", option->name); /* The flags field. */ - fprintf (out, ":%u", option->flags); + fprintf (out, ":%lu", option->flags); if (opt.verbose) { putc (' ', out); @@ -753,9 +786,9 @@ gc_component_list_options (int component, FILE *out) fprintf (out, "none"); else { - unsigned int flags = option->flags; - unsigned int flag = 0; - unsigned int first = 1; + unsigned long flags = option->flags; + unsigned long flag = 0; + unsigned long first = 1; while (flags) { @@ -800,6 +833,9 @@ gc_component_list_options (int component, FILE *out) /* The default value field. */ fprintf (out, ":%s", option->default_value ? option->default_value : ""); + /* The default argument field. */ + fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); + /* The value field. */ fprintf (out, ":%s", option->value ? option->value : ""); @@ -884,26 +920,53 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) while ((length = getline (&line, &line_len, config)) > 0) { gc_option_t *option; - char *value; - + char *linep; + unsigned long flags = 0; + char *default_value = NULL; + /* Strip newline and carriage return, if present. */ while (length > 0 && (line[length - 1] == '\n' || line[length - 1] == '\r')) line[--length] = '\0'; + linep = strchr (line, ':'); + if (linep) + *(linep++) = '\0'; + + /* Extract additional flags. Default to none. */ + if (linep) + { + char *end; + char *tail; + + end = strchr (linep, ':'); + if (end) + *(end++) = '\0'; + + errno = 0; + flags = strtoul (linep, &tail, 0); + if (errno) + gc_error (1, errno, "malformed flags in option %s from %s", line, cmd_line); + if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) + gc_error (1, 0, "garbage after flags in option %s from %s", line, cmd_line); + + linep = end; + } + /* Extract default value, if present. Default to empty if not. */ - value = strchr (line, ':'); - if (!value) - value = ""; - else + if (linep) { char *end; - *(value++) = '\0'; - end = strchr (value, ':'); + end = strchr (linep, ':'); if (end) - *end = '\0'; + *(end++) = '\0'; + + if (flags & GC_OPT_FLAG_DEFAULT) + default_value = linep; + + linep = end; } /* Look up the option in the component and install the @@ -915,8 +978,10 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) gc_error (1, errno, "option %s returned twice from %s", line, cmd_line); option->active = 1; - if (*value) - option->default_value = xstrdup (value); + + option->flags |= flags; + if (default_value && *default_value) + option->default_value = xstrdup (default_value); } } if (ferror (config)) @@ -981,7 +1046,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) gc_error (0, 0, "warning: ignoring argument %s for option %s", value, name); - opt_value = xstrdup ("Y"); + opt_value = xstrdup ("1"); } else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) @@ -1011,6 +1076,8 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) == GC_ARG_TYPE_STRING) opt_val++; + /* FIXME. For type none arguments, this is + wrong. */ option->value = xasprintf ("%s,%s", option->value, opt_val); xfree (opt_value); @@ -1411,32 +1478,66 @@ gc_component_change_options (int component, FILE *in) while ((length = getline (&line, &line_len, in)) > 0) { - char *value; + char *linep; + unsigned long flags = 0; + char *new_value = NULL; /* Strip newline and carriage return, if present. */ while (length > 0 && (line[length - 1] == '\n' || line[length - 1] == '\r')) line[--length] = '\0'; - value = strchr (line, ':'); - if (!value) - value = ""; - else + linep = strchr (line, ':'); + if (linep) + *(linep++) = '\0'; + + /* Extract additional flags. Default to none. */ + if (linep) + { + char *end; + char *tail; + + end = strchr (linep, ':'); + if (end) + *(end++) = '\0'; + + errno = 0; + flags = strtoul (linep, &tail, 0); + if (errno) + gc_error (1, errno, "malformed flags in option %s", line); + if (!(*tail == '\0' || *tail == ':' || *tail == ' ')) + gc_error (1, 0, "garbage after flags in option %s", line); + + linep = end; + } + + /* Extract default value, if present. Default to empty if + not. */ + if (linep) { char *end; - *(value++) = '\0'; - end = strchr (value, ':'); + end = strchr (linep, ':'); if (end) - *end = '\0'; + *(end++) = '\0'; + + if (!(flags & GC_OPT_FLAG_DEFAULT)) + new_value = linep; + + linep = end; } option = find_option (component, line, GC_BACKEND_ANY); if (!option) gc_error (1, 0, "unknown option %s", line); - option_check_validity (option, value); - option->new_value = xstrdup (value); + /* FIXME: This is not correct, as it ignores the optional arg + case. */ + if (flags & GC_OPT_FLAG_DEFAULT) + new_value = ""; + + option_check_validity (option, new_value); + option->new_value = xstrdup (new_value); } /* Now that we have collected and locally verified the changes, -- cgit From 8f8c5c47dd9495d1d4236ee632cd4e8193cb8607 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 25 Feb 2004 19:35:36 +0000 Subject: 2004-02-25 Marcus Brinkmann * gpgconf-comp.c (gc_component_list_options): Correct output for lists of arg type none. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index efb3794b9..b98e4c559 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-02-25 Marcus Brinkmann + + * gpgconf-comp.c (gc_component_list_options): Correct output for + lists of arg type none. + 2004-02-24 Marcus Brinkmann * README.gpgconf: Revert last change. Add new flags "default", diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 4dc2fbbe8..8e143010f 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -837,7 +837,14 @@ gc_component_list_options (int component, FILE *out) fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); /* The value field. */ - fprintf (out, ":%s", option->value ? option->value : ""); + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE + && (option->flags & GC_OPT_FLAG_LIST) + && option->value) + /* The special format "1,1,1,1,...,1" is converted to a number + here. */ + fprintf (out, ":%u", (strlen (option->value) + 1) / 2); + else + fprintf (out, ":%s", option->value ? option->value : ""); /* ADD NEW FIELDS HERE. */ -- cgit From 8817c66900b5f23b568d0cd7642739c050aa127b Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Wed, 25 Feb 2004 20:24:53 +0000 Subject: 2004-02-25 Marcus Brinkmann * gpgconf-comp.c (struct gc_option): Add new member new_flags. (option_check_validity): Check OPTION->new_flags beside OPTION->new_value. Add new argument FLAGS. (gc_component_change_options): Support default flag correctly. (change_options_program): Likewise. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 35 +++++++++++++++++++++-------------- 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index b98e4c559..fab5cafec 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -2,6 +2,11 @@ * gpgconf-comp.c (gc_component_list_options): Correct output for lists of arg type none. + (struct gc_option): Add new member new_flags. + (option_check_validity): Check OPTION->new_flags beside + OPTION->new_value. Add new argument FLAGS. + (gc_component_change_options): Support default flag correctly. + (change_options_program): Likewise. 2004-02-24 Marcus Brinkmann diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 8e143010f..ee980c5da 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -386,6 +386,11 @@ struct gc_option /* The current value of this option. */ char *value; + /* The new flags for this option. The only defined flag is actually + GC_OPT_FLAG_DEFAULT, and it means that the option should be + deleted. In this case, NEW_VALUE is NULL. */ + unsigned long new_flags; + /* The new value of this option. */ char *new_value; }; @@ -1213,11 +1218,16 @@ gc_component_retrieve_options (int component) /* Perform a simple validity check based on the type. */ static void -option_check_validity (gc_option_t *option, const char *new_value) +option_check_validity (gc_option_t *option, unsigned long flags, + const char *new_value) { - if (option->new_value) + if (option->new_flags || option->new_value) gc_error (1, 0, "option %s already changed", option->name); + if ((flags & GC_OPT_FLAG_DEFAULT) && *new_value) + gc_error (1, 0, "value %s provided for deleted option %s", + new_value, option->name); + if (!*new_value) return; @@ -1332,7 +1342,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, option = find_option (component, start, backend); *end = saved_end; - if (option && option->new_value) + if (option && (option->new_flags & GC_OPT_FLAG_DEFAULT)) disable = 1; } if (disable) @@ -1379,7 +1389,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, option = gc_component[component].options; while (option->name) { - /* FIXME: Add support for lists. */ + /* FIXME: Add support for lists and default arg (new_value eq ""). */ if (!(option->flags & GC_OPT_FLAG_GROUP) && option->backend == backend && option->new_value @@ -1487,7 +1497,7 @@ gc_component_change_options (int component, FILE *in) { char *linep; unsigned long flags = 0; - char *new_value = NULL; + char *new_value = ""; /* Strip newline and carriage return, if present. */ while (length > 0 @@ -1528,8 +1538,7 @@ gc_component_change_options (int component, FILE *in) if (end) *(end++) = '\0'; - if (!(flags & GC_OPT_FLAG_DEFAULT)) - new_value = linep; + new_value = linep; linep = end; } @@ -1538,13 +1547,11 @@ gc_component_change_options (int component, FILE *in) if (!option) gc_error (1, 0, "unknown option %s", line); - /* FIXME: This is not correct, as it ignores the optional arg - case. */ - if (flags & GC_OPT_FLAG_DEFAULT) - new_value = ""; + option_check_validity (option, flags, new_value); - option_check_validity (option, new_value); - option->new_value = xstrdup (new_value); + option->new_flags = flags; + if (!(flags & GC_OPT_FLAG_DEFAULT)) + option->new_value = xstrdup (new_value); } /* Now that we have collected and locally verified the changes, @@ -1555,7 +1562,7 @@ gc_component_change_options (int component, FILE *in) { /* Go on if we have already seen this backend, or if there is nothing to do. */ - if (src_pathname[option->backend] || !option->new_value) + if (src_pathname[option->backend] || !(option->new_flags || option->new_value)) { option++; continue; -- cgit From 7aa4fa9b095a70fb1c1049c9e61dbd6c9d96eeac Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 16:28:27 +0000 Subject: 2004-02-26 Marcus Brinkmann * README.gpgconf (NAME): Add info about optional arg and arg type 0. * gpgconf-comp.c (gc_component_change_options): Parse list of arg type 0 options. (option_check_validity): Add new argument NEW_VALUE_NR. Perform rigorous validity checks. (change_options_program): Disable an option also if we have a new value for it. --- tools/ChangeLog | 10 ++++ tools/README.gpgconf | 1 + tools/gpgconf-comp.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 141 insertions(+), 13 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index fab5cafec..69af2eb99 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,13 @@ +2004-02-26 Marcus Brinkmann + + * README.gpgconf (NAME): Add info about optional arg and arg type 0. + * gpgconf-comp.c (gc_component_change_options): Parse list of + arg type 0 options. + (option_check_validity): Add new argument NEW_VALUE_NR. Perform + rigorous validity checks. + (change_options_program): Disable an option also if we have a new + value for it. + 2004-02-25 Marcus Brinkmann * gpgconf-comp.c (gc_component_list_options): Correct output for diff --git a/tools/README.gpgconf b/tools/README.gpgconf index 84fed518b..2f6a2e073 100644 --- a/tools/README.gpgconf +++ b/tools/README.gpgconf @@ -191,6 +191,7 @@ OR-wise combination of the following flag values: 1 group If this flag is set, this is a line describing a group and not an option. O 2 optional arg If this flag is set, the argument is optional. + This is never set for arg type 0 (none) options. O 4 list If this flag is set, the option can be given multiple times. O 8 runtime If this flag is set, the option can be changed diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index ee980c5da..dc8de903c 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -289,7 +289,7 @@ static struct flag set. */ #define GC_OPT_FLAG_GROUP (1UL << 0) /* The ARG_OPT flag for an option indicates that the argument is - optional. */ + optional. This is never set for GC_ARG_TYPE_NONE options. */ #define GC_OPT_FLAG_ARG_OPT (1UL << 1) /* The LIST flag for an option indicates that the option can occur several times. A comma separated list of arguments is used as the @@ -1216,23 +1216,116 @@ gc_component_retrieve_options (int component) } -/* Perform a simple validity check based on the type. */ +/* Perform a simple validity check based on the type. Return in + NEW_VALUE_NR the value of the number in NEW_VALUE if OPTION is of + type GC_ARG_TYPE_NONE. */ static void option_check_validity (gc_option_t *option, unsigned long flags, - const char *new_value) + char *new_value, unsigned long *new_value_nr) { if (option->new_flags || option->new_value) gc_error (1, 0, "option %s already changed", option->name); - if ((flags & GC_OPT_FLAG_DEFAULT) && *new_value) - gc_error (1, 0, "value %s provided for deleted option %s", - new_value, option->name); + if (flags & GC_OPT_FLAG_DEFAULT) + { + if (*new_value) + gc_error (1, 0, "argument %s provided for deleted option %s", + new_value, option->name); + } + else + { + /* This is even correct for GC_ARG_TYPE_NONE options, for which + GC_OPT_FLAG_ARG_OPT is never set. */ + if (!(option->flags & GC_OPT_FLAG_ARG_OPT) && (*new_value == '\0')) + gc_error (1, 0, "no argument for option %s", option->name); + + if (*new_value) + { + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) + { + char *tail; + + errno = 0; + *new_value_nr = strtoul (new_value, &tail, 0); + + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); + if (*tail) + gc_error (1, 0, "garbage after argument for option %s", + option->name); + + if (!(option->flags & GC_OPT_FLAG_LIST)) + { + if (*new_value_nr != 1) + gc_error (1, 0, "argument for non-list option %s of type 0 " + "(none) must be 1", option->name); + } + else + { + if (*new_value_nr == 0) + gc_error (1, 0, "argument for option %s of type 0 (none) " + "must be positive", option->name); + } + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) + { + if (*new_value != '"') + gc_error (1, 0, "string argument for option %s must begin " + "with a quote (\") character", option->name); + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) + { + char *tail = new_value; + + while (*tail) + { + errno = 0; + (void) strtol (new_value, &tail, 0); - if (!*new_value) - return; + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); + if (*tail == ',') + { + if (!(option->flags & GC_OPT_FLAG_LIST)) + gc_error (1, 0, "list found for non-list option %s", + option->name); + tail++; + } + else if (*tail) + gc_error (1, 0, "garbage after argument for option %s", + option->name); + } + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32) + { + char *tail = new_value; - /* FIXME. Verify that lists are lists, numbers are numbers, strings - are strings, etc. */ + while (*tail) + { + errno = 0; + (void) strtoul (new_value, &tail, 0); + + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); + if (*tail == ',') + { + if (!(option->flags & GC_OPT_FLAG_LIST)) + gc_error (1, 0, "list found for non-list option %s", + option->name); + tail++; + } + else if (*tail) + gc_error (1, 0, "garbage after argument for option %s", + option->name); + } + } + else + assert (!"Unexpected argument type"); + } + } } @@ -1342,7 +1435,8 @@ change_options_program (gc_component_t component, gc_backend_t backend, option = find_option (component, start, backend); *end = saved_end; - if (option && (option->new_flags & GC_OPT_FLAG_DEFAULT)) + if (option && ((option->new_flags & GC_OPT_FLAG_DEFAULT) + || option->new_value)) disable = 1; } if (disable) @@ -1472,6 +1566,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, return -1; } + /* Read the modifications from IN and apply them. */ void gc_component_change_options (int component, FILE *in) @@ -1498,6 +1593,7 @@ gc_component_change_options (int component, FILE *in) char *linep; unsigned long flags = 0; char *new_value = ""; + unsigned long new_value_nr; /* Strip newline and carriage return, if present. */ while (length > 0 @@ -1547,11 +1643,32 @@ gc_component_change_options (int component, FILE *in) if (!option) gc_error (1, 0, "unknown option %s", line); - option_check_validity (option, flags, new_value); + option_check_validity (option, flags, new_value, &new_value_nr); option->new_flags = flags; if (!(flags & GC_OPT_FLAG_DEFAULT)) - option->new_value = xstrdup (new_value); + { + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE + && (option->flags & GC_OPT_FLAG_LIST)) + { + char *str; + + /* We convert the number to a list of 1's for + convenient list handling. */ + assert (new_value_nr > 0); + option->new_value = xmalloc ((2 * (new_value_nr - 1) + 1) + 1); + str = option->new_value; + *(str++) = '1'; + while (--new_value_nr > 0) + { + *(str++) = ','; + *(str++) = '1'; + } + *(str++) = '\0'; + } + else + option->new_value = xstrdup (new_value); + } } /* Now that we have collected and locally verified the changes, -- cgit From 255d2cea0435ad834581726ef2a424b1626c9872 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 18:22:02 +0000 Subject: 2004-02-26 Marcus Brinkmann * README.gpgconf: Fix description of arguments. * gpgconf-comp.c (option_check_validity): Rewritten to properly support optional arguments in lists. --- tools/ChangeLog | 6 +- tools/README.gpgconf | 31 +++++------ tools/gpgconf-comp.c | 155 ++++++++++++++++++++++++--------------------------- 3 files changed, 92 insertions(+), 100 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 69af2eb99..154ec55e8 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,6 +1,10 @@ 2004-02-26 Marcus Brinkmann - * README.gpgconf (NAME): Add info about optional arg and arg type 0. + * README.gpgconf: Fix description of arguments. + * gpgconf-comp.c (option_check_validity): Rewritten to properly + support optional arguments in lists. + + * README.gpgconf: Add info about optional arg and arg type 0. * gpgconf-comp.c (gc_component_change_options): Parse list of arg type 0 options. (option_check_validity): Add new argument NEW_VALUE_NR. Perform diff --git a/tools/README.gpgconf b/tools/README.gpgconf index 2f6a2e073..0973939d0 100644 --- a/tools/README.gpgconf +++ b/tools/README.gpgconf @@ -80,17 +80,17 @@ Some fields contain an option argument. The format of an option argument depends on the type of the option and on some flags: The simplest case is that the option does not take an argument at all -(TYPE is 0). Then the option argument is either empty if the option -is not set, or an unsigned number that specifies how often the option -occurs. If the LIST flag is not set, then the only valid number is 1. -Options that don't take an argument never have the "default" flag set. +(TYPE is 0). Then the option argument is an unsigned number that +specifies how often the option occurs. If the LIST flag is not set, +then the only valid number is 1. Options that don't take an argument +never have the "default" or "optional arg" flag set. If the option takes a number argument (ALT-TYPE is 2 or 3), and it can only occur once (LIST flag is not set), then the option argument is -either empty if the option is not set, or it is a number. A number is -a string that begins with an optional minus character, followed by one -or more digits. The number must fit into an integer variable -(unsigned or signed, depending on ALT-TYPE). +either empty (only allowed if the argument is optional), or it is a +number. A number is a string that begins with an optional minus +character, followed by one or more digits. The number must fit into +an integer variable (unsigned or signed, depending on ALT-TYPE). If the option takes a number argument and it can occur more than once, then the option argument is either empty, or it is a comma-separated @@ -98,19 +98,16 @@ list of numbers as described above. If the option takes a string argument (ALT-TYPE is 1), and it can only occur once (LIST flag is not set) then the option argument is either -empty if the option is not set, or it starts with a double quote -character (") followed by a percent-escaped string that is the -argument value. Note that there is only a leading double quote +empty (only allowed if the argument is optional), or it starts with a +double quote character (") followed by a percent-escaped string that +is the argument value. Note that there is only a leading double quote character, no trailing one. The double quote character is only needed to be able to differentiate between no value and the empty string as value. -If the option takes a string argument and it can occur more than once, -then the option argument is either empty or it starts with a double -quote character (") followed by a comma-separated list of -percent-escaped strings. Obviously any commas in the individual -strings must be percent-escaped. - +If the option takes a number argument and it can occur more than once, +then the option argument is either empty, or it is a comma-separated +list of string arguments as described above. FIXME: Document the active language and active character set. Allow to change it via the command line? diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index dc8de903c..524f2170d 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1223,6 +1223,8 @@ static void option_check_validity (gc_option_t *option, unsigned long flags, char *new_value, unsigned long *new_value_nr) { + char *arg; + if (option->new_flags || option->new_value) gc_error (1, 0, "option %s already changed", option->name); @@ -1231,101 +1233,89 @@ option_check_validity (gc_option_t *option, unsigned long flags, if (*new_value) gc_error (1, 0, "argument %s provided for deleted option %s", new_value, option->name); + + return; } - else + + /* GC_ARG_TYPE_NONE options have special list treatment. */ + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) { - /* This is even correct for GC_ARG_TYPE_NONE options, for which - GC_OPT_FLAG_ARG_OPT is never set. */ - if (!(option->flags & GC_OPT_FLAG_ARG_OPT) && (*new_value == '\0')) - gc_error (1, 0, "no argument for option %s", option->name); + char *tail; - if (*new_value) + errno = 0; + *new_value_nr = strtoul (new_value, &tail, 0); + + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); + if (*tail) + gc_error (1, 0, "garbage after argument for option %s", + option->name); + + if (!(option->flags & GC_OPT_FLAG_LIST)) { - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE) - { - char *tail; + if (*new_value_nr != 1) + gc_error (1, 0, "argument for non-list option %s of type 0 " + "(none) must be 1", option->name); + } + else + { + if (*new_value_nr == 0) + gc_error (1, 0, "argument for option %s of type 0 (none) " + "must be positive", option->name); + } - errno = 0; - *new_value_nr = strtoul (new_value, &tail, 0); + return; + } - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - if (*tail) - gc_error (1, 0, "garbage after argument for option %s", - option->name); + arg = new_value; + do + { + if (*arg == '\0' || *arg == ',') + { + if (!(option->flags & GC_OPT_FLAG_ARG_OPT)) + gc_error (1, 0, "argument required for option %s", option->name); - if (!(option->flags & GC_OPT_FLAG_LIST)) - { - if (*new_value_nr != 1) - gc_error (1, 0, "argument for non-list option %s of type 0 " - "(none) must be 1", option->name); - } - else - { - if (*new_value_nr == 0) - gc_error (1, 0, "argument for option %s of type 0 (none) " - "must be positive", option->name); - } - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - { - if (*new_value != '"') - gc_error (1, 0, "string argument for option %s must begin " - "with a quote (\") character", option->name); - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) - { - char *tail = new_value; + if (*arg == ',' && !(option->flags & GC_OPT_FLAG_LIST)) + gc_error (1, 0, "list found for non-list option %s", option->name); + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) + { + if (*arg != '"') + gc_error (1, 0, "string argument for option %s must begin " + "with a quote (\") character", option->name); + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) + { + errno = 0; + (void) strtol (arg, &arg, 0); - while (*tail) - { - errno = 0; - (void) strtol (new_value, &tail, 0); + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - if (*tail == ',') - { - if (!(option->flags & GC_OPT_FLAG_LIST)) - gc_error (1, 0, "list found for non-list option %s", - option->name); - tail++; - } - else if (*tail) - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - } - else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_UINT32) - { - char *tail = new_value; + if (*arg != '\0' && *arg != ',') + gc_error (1, 0, "garbage after argument for option %s", + option->name); + } + else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_INT32) + { + errno = 0; + (void) strtoul (arg, &arg, 0); - while (*tail) - { - errno = 0; - (void) strtoul (new_value, &tail, 0); + if (errno) + gc_error (1, errno, "invalid argument for option %s", + option->name); - if (errno) - gc_error (1, errno, "invalid argument for option %s", - option->name); - if (*tail == ',') - { - if (!(option->flags & GC_OPT_FLAG_LIST)) - gc_error (1, 0, "list found for non-list option %s", - option->name); - tail++; - } - else if (*tail) - gc_error (1, 0, "garbage after argument for option %s", - option->name); - } - } - else - assert (!"Unexpected argument type"); + if (*arg != '\0' && *arg != ',') + gc_error (1, 0, "garbage after argument for option %s", + option->name); } + arg = strchr (arg, ','); + if (arg) + arg++; } + while (arg && *arg); } @@ -1377,6 +1367,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, xfree (orig_filename); orig_filename = NULL; } + /* We now initialize the return strings, so the caller can do the cleanup for us. */ *src_filenamep = src_filename; -- cgit From aa7a4c1aec98d5a730059ef956cd85867523a00d Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 18:39:34 +0000 Subject: 2004-02-26 Marcus Brinkmann * gpgconf-comp.c (change_options_program): Support all types of options, including list types. --- tools/ChangeLog | 5 +++- tools/README.gpgconf | 8 ++++++ tools/gpgconf-comp.c | 77 ++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 13 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 154ec55e8..57c52f437 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,9 +1,12 @@ 2004-02-26 Marcus Brinkmann + * gpgconf-comp.c (change_options_program): Support all types of + options, including list types. + * README.gpgconf: Fix description of arguments. * gpgconf-comp.c (option_check_validity): Rewritten to properly support optional arguments in lists. - + * README.gpgconf: Add info about optional arg and arg type 0. * gpgconf-comp.c (gc_component_change_options): Parse list of arg type 0 options. diff --git a/tools/README.gpgconf b/tools/README.gpgconf index 0973939d0..03fd9daa7 100644 --- a/tools/README.gpgconf +++ b/tools/README.gpgconf @@ -412,3 +412,11 @@ TODO * Extend the backend interface to include gettext domain and description, if available, to avoid repeating this information in gpgconf. + +* Left out string arguments (optional) are written out exactly as +empty string arguments. Should we do quoting? + +* More string argument trouble: Special characters like newlines etc +cause trouble. Again, should we do quoting? + + diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 524f2170d..3b9927f61 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1474,21 +1474,73 @@ change_options_program (gc_component_t component, gc_backend_t backend, option = gc_component[component].options; while (option->name) { - /* FIXME: Add support for lists and default arg (new_value eq ""). */ if (!(option->flags & GC_OPT_FLAG_GROUP) && option->backend == backend - && option->new_value - && *option->new_value) + && option->new_value) { - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - fprintf (src_file, "%s %s\n", option->name, - percent_deescape (&option->new_value[1])); - else if (option->arg_type == GC_ARG_TYPE_NONE) - fprintf (src_file, "%s\n", option->name); - else - fprintf (src_file, "%s %s\n", option->name, option->new_value); - if (ferror (src_file)) - goto change_one_err; + char *arg = option->new_value; + + do + { + if (*arg == '\0' || *arg == ',') + { + fprintf (src_file, "%s\n", option->name); + if (ferror (src_file)) + goto change_one_err; + } + else if (gc_arg_type[option->arg_type].fallback + == GC_ARG_TYPE_NONE) + { + assert (*arg == '1'); + fprintf (src_file, "%s\n", option->name); + if (ferror (src_file)) + goto change_one_err; + + arg++; + } + else if (gc_arg_type[option->arg_type].fallback + == GC_ARG_TYPE_STRING) + { + char *end; + + assert (*arg == '"'); + arg++; + + end = strchr (arg, ','); + if (end) + *end = '\0'; + + fprintf (src_file, "%s %s\n", option->name, + percent_deescape (arg)); + if (ferror (src_file)) + goto change_one_err; + + if (end) + *end = ','; + arg = end; + } + else + { + char *end; + + end = strchr (arg, ','); + if (end) + *end = '\0'; + + fprintf (src_file, "%s %s\n", option->name, arg); + if (ferror (src_file)) + goto change_one_err; + + if (end) + *end = ','; + arg = end; + } + + assert (arg == NULL || *arg == '\0' || *arg == ','); + if (arg && *arg == ',') + arg++; + } + while (arg && *arg); } option++; } @@ -1692,6 +1744,7 @@ gc_component_change_options (int component, FILE *in) option++; } + if (!err) { int i; -- cgit From bfd5ed026ce2fc344cbc4b550a118ce492811939 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 18:54:46 +0000 Subject: 2004-02-26 Marcus Brinkmann * gpgconf-comp.c (retrieve_options_from_program): Remove broken string handling. --- tools/ChangeLog | 3 +++ tools/gpgconf-comp.c | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 57c52f437..084028c15 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,8 @@ 2004-02-26 Marcus Brinkmann + * gpgconf-comp.c (retrieve_options_from_program): Remove broken + string handling. + * gpgconf-comp.c (change_options_program): Support all types of options, including list types. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 3b9927f61..e56f9c49f 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1084,12 +1084,6 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) { char *opt_val = opt_value; - if (gc_arg_type[option->arg_type].fallback - == GC_ARG_TYPE_STRING) - opt_val++; - - /* FIXME. For type none arguments, this is - wrong. */ option->value = xasprintf ("%s,%s", option->value, opt_val); xfree (opt_value); -- cgit From 91a514f2a1b45fb4bd750bcd9ac44fdcf6ff78d7 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 22:18:36 +0000 Subject: 2004-02-26 Marcus Brinkmann * gpgconf-comp.c (option_check_validity): Check if option is active. (change_options_file): Implement. --- tools/ChangeLog | 4 + tools/gpgconf-comp.c | 291 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 292 insertions(+), 3 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 084028c15..1821d8b93 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,9 @@ 2004-02-26 Marcus Brinkmann + * gpgconf-comp.c (option_check_validity): Check if option is + active. + (change_options_file): Implement. + * gpgconf-comp.c (retrieve_options_from_program): Remove broken string handling. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e56f9c49f..bbf0649a9 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1219,6 +1219,9 @@ option_check_validity (gc_option_t *option, unsigned long flags, { char *arg; + if (!option->active) + gc_error (1, 0, "option %s not supported by backend", option->name); + if (option->new_flags || option->new_value) gc_error (1, 0, "option %s already changed", option->name); @@ -1320,8 +1323,290 @@ change_options_file (gc_component_t component, gc_backend_t backend, char **src_filenamep, char **dest_filenamep, char **orig_filenamep) { - /* FIXME. */ - assert (!"Not implemented."); + static const char marker[] = "###+++--- GPGConf ---+++###"; + /* True if we are within the marker in the config file. */ + int in_marker = 0; + gc_option_t *option; + char *line = NULL; + size_t line_len; + ssize_t length; + int res; + int fd; + FILE *src_file = NULL; + FILE *dest_file = NULL; + char *src_filename; + char *dest_filename; + char *orig_filename; + char *arg; + char *cur_arg = NULL; + + option = find_option (component, + gc_backend[backend].option_name, GC_BACKEND_ANY); + assert (option); + assert (option->active); + assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE); + assert (!(option->flags & GC_OPT_FLAG_ARG_OPT)); + + /* FIXME. Throughout the function, do better error reporting. */ + /* Note that get_config_pathname() calls percent_deescape(), so we + call this before processing the arguments. */ + dest_filename = xstrdup (get_config_pathname (component, backend)); + src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); + orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); + + arg = option->new_value; + if (arg) + { + char *end; + + arg++; + end = strchr (arg, ','); + if (end) + *end = '\0'; + + cur_arg = percent_deescape (arg); + if (end) + { + *end = ','; + arg = end + 1; + } + else + arg = NULL; + } + + res = link (dest_filename, orig_filename); + if (res < 0 && errno != ENOENT) + return -1; + if (res < 0) + { + xfree (orig_filename); + orig_filename = NULL; + } + + /* We now initialize the return strings, so the caller can do the + cleanup for us. */ + *src_filenamep = src_filename; + *dest_filenamep = dest_filename; + *orig_filenamep = orig_filename; + + /* Use open() so that we can use O_EXCL. */ + fd = open (src_filename, O_CREAT | O_EXCL | O_WRONLY, 0644); + if (fd < 0) + return -1; + src_file = fdopen (fd, "w"); + res = errno; + if (!src_file) + { + errno = res; + return -1; + } + + /* Only if ORIG_FILENAME is not NULL did the configuration file + exist already. In this case, we will copy its content into the + new configuration file, changing it to our liking in the + process. */ + if (orig_filename) + { + dest_file = fopen (dest_filename, "r"); + if (!dest_file) + goto change_file_one_err; + + while ((length = getline (&line, &line_len, dest_file)) > 0) + { + int disable = 0; + char *start; + + if (!strncmp (marker, line, sizeof (marker) - 1)) + { + if (!in_marker) + in_marker = 1; + else + break; + } + + start = line; + while (*start == ' ' || *start == '\t') + start++; + if (*start && *start != '\r' && *start != '\n' && *start != '#') + { + char *end; + char *endp; + char saved_end; + + endp = start; + end = endp; + + /* Search for the end of the line. */ + while (*endp && *endp != '#' && *endp != '\r' && *endp != '\n') + { + endp++; + if (*endp && *endp != ' ' && *endp != '\t' + && *endp != '\r' && *endp != '\n' && *endp != '#') + end = endp + 1; + } + saved_end = *end; + *end = '\0'; + + if ((option->new_flags & GC_OPT_FLAG_DEFAULT) + || !cur_arg || strcmp (start, cur_arg)) + disable = 1; + else + { + /* Find next argument. */ + if (arg) + { + char *arg_end; + + arg++; + arg_end = strchr (arg, ','); + if (arg_end) + *arg_end = '\0'; + + cur_arg = percent_deescape (arg); + if (arg_end) + { + *arg_end = ','; + arg = arg_end + 1; + } + else + arg = NULL; + } + else + cur_arg = NULL; + } + + *end = saved_end; + } + + if (disable) + { + if (!in_marker) + { + fprintf (src_file, + "# GPGConf disabled this option here at %s\n", + asctimestamp (gnupg_get_time ())); + if (ferror (src_file)) + goto change_file_one_err; + fprintf (src_file, "# %s", line); + if (ferror (src_file)) + goto change_file_one_err; + } + } + else + { + fprintf (src_file, "%s", line); + if (ferror (src_file)) + goto change_file_one_err; + } + } + if (ferror (dest_file)) + goto change_file_one_err; + } + + if (!in_marker) + { + /* There was no marker. This is the first time we edit the + file. We add our own marker at the end of the file and + proceed. Note that we first write a newline, this guards us + against files which lack the newline at the end of the last + line, while it doesn't hurt us in all other cases. */ + fprintf (src_file, "\n%s\n", marker); + if (ferror (src_file)) + goto change_file_one_err; + } + + /* At this point, we have copied everything up to the end marker + into the new file, except for the arguments we are going to add. + Now, dump the new arguments and write the end marker, possibly + followed by the rest of the original file. */ + while (cur_arg) + { + fprintf (src_file, "%s\n", cur_arg); + + /* Find next argument. */ + if (arg) + { + char *end; + + arg++; + end = strchr (arg, ','); + if (end) + *end = '\0'; + + cur_arg = percent_deescape (arg); + if (end) + { + *end = ','; + arg = end + 1; + } + else + arg = NULL; + } + else + cur_arg = NULL; + } + + fprintf (src_file, "%s %s\n", marker, asctimestamp (gnupg_get_time ())); + if (ferror (src_file)) + goto change_file_one_err; + + if (!in_marker) + { + fprintf (src_file, "# GPGConf edited this configuration file.\n"); + if (ferror (src_file)) + goto change_file_one_err; + fprintf (src_file, "# It will disable options before this marked " + "block, but it will\n"); + if (ferror (src_file)) + goto change_file_one_err; + fprintf (src_file, "# never change anything below these lines.\n"); + if (ferror (src_file)) + goto change_file_one_err; + } + if (dest_file) + { + while ((length = getline (&line, &line_len, dest_file)) > 0) + { + fprintf (src_file, "%s", line); + if (ferror (src_file)) + goto change_file_one_err; + } + if (ferror (dest_file)) + goto change_file_one_err; + } + if (line) + free (line); + res = fclose (src_file); + if (res) + { + res = errno; + close (fd); + if (dest_file) + fclose (dest_file); + errno = res; + return -1; + } + close (fd); + if (dest_file) + { + res = fclose (dest_file); + if (res) + return -1; + } + return 0; + + change_file_one_err: + if (line) + free (line); + res = errno; + if (src_file) + { + fclose (src_file); + close (fd); + } + if (dest_file) + fclose (dest_file); + errno = res; return -1; } @@ -1394,7 +1679,6 @@ change_options_program (gc_component_t component, gc_backend_t backend, { int disable = 0; char *start; - char *end; if (!strncmp (marker, line, sizeof (marker) - 1)) { @@ -1409,6 +1693,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, start++; if (*start && *start != '\r' && *start != '\n' && *start != '#') { + char *end; char saved_end; end = start; -- cgit From 4a038d65afa8cfffda86437b6e02636e8325e582 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 26 Feb 2004 22:45:19 +0000 Subject: 2004-02-26 Marcus Brinkmann * gpgconf-comp.c (gc_component_list_options): Do not print empty groups. --- tools/ChangeLog | 3 + tools/gpgconf-comp.c | 214 ++++++++++++++++++++++++++++----------------------- 2 files changed, 121 insertions(+), 96 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 1821d8b93..ba5df4765 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,8 @@ 2004-02-26 Marcus Brinkmann + * gpgconf-comp.c (gc_component_list_options): Do not print empty + groups. + * gpgconf-comp.c (option_check_validity): Check if option is active. (change_options_file): Implement. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index bbf0649a9..5dda4f306 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -736,124 +736,146 @@ gc_component_find (const char *name) } -/* List all options of the component COMPONENT. */ -void -gc_component_list_options (int component, FILE *out) -{ - const gc_option_t *option = gc_component[component].options; +/* List the option OPTION. */ +static void +list_one_option (const gc_option_t *option, FILE *out) +{ + const char *desc = NULL; + char *arg_name = NULL; - while (option->name) + if (option->desc) { - const char *desc = NULL; - char *arg_name = NULL; + desc = my_dgettext (option->desc_domain, option->desc); - /* Do not output unknown or internal options. */ - if (!(option->flags & GC_OPT_FLAG_GROUP) - && (!option->active || option->level == GC_LEVEL_INTERNAL)) + if (*desc == '|') { - option++; - continue; + const char *arg_tail = strchr (&desc[1], '|'); + + if (arg_tail) + { + int arg_len = arg_tail - &desc[1]; + arg_name = xmalloc (arg_len + 1); + memcpy (arg_name, &desc[1], arg_len); + arg_name[arg_len] = '\0'; + desc = arg_tail + 1; + } } + } + + + /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR ORDER IS + PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE ANY + FIELDS. */ - if (option->desc) + /* The name field. */ + fprintf (out, "%s", option->name); + + /* The flags field. */ + fprintf (out, ":%lu", option->flags); + if (opt.verbose) + { + putc (' ', out); + + if (!option->flags) + fprintf (out, "none"); + else { - desc = my_dgettext (option->desc_domain, option->desc); + unsigned long flags = option->flags; + unsigned long flag = 0; + unsigned long first = 1; - if (*desc == '|') + while (flags) { - const char *arg_tail = strchr (&desc[1], '|'); - - if (arg_tail) + if (flags & 1) { - int arg_len = arg_tail - &desc[1]; - arg_name = xmalloc (arg_len + 1); - memcpy (arg_name, &desc[1], arg_len); - arg_name[arg_len] = '\0'; - desc = arg_tail + 1; + if (first) + first = 0; + else + putc (',', out); + fprintf (out, "%s", gc_flag[flag].name); } + flags >>= 1; + flag++; } } + } - /* YOU MUST NOT REORDER THE FIELDS IN THIS OUTPUT, AS THEIR - ORDER IS PART OF THE EXTERNAL INTERFACE. YOU MUST NOT REMOVE - ANY FIELDS. */ + /* The level field. */ + fprintf (out, ":%u", option->level); + if (opt.verbose) + fprintf (out, " %s", gc_level[option->level].name); + + /* The description field. */ + fprintf (out, ":%s", desc ? percent_escape (desc) : ""); + + /* The type field. */ + fprintf (out, ":%u", option->arg_type); + if (opt.verbose) + fprintf (out, " %s", gc_arg_type[option->arg_type].name); + + /* The alternate type field. */ + fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); + if (opt.verbose) + fprintf (out, " %s", + gc_arg_type[gc_arg_type[option->arg_type].fallback].name); + + /* The argument name field. */ + fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); + if (arg_name) + xfree (arg_name); + + /* The default value field. */ + fprintf (out, ":%s", option->default_value ? option->default_value : ""); + + /* The default argument field. */ + fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); + + /* The value field. */ + if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE + && (option->flags & GC_OPT_FLAG_LIST) + && option->value) + /* The special format "1,1,1,1,...,1" is converted to a number + here. */ + fprintf (out, ":%u", (strlen (option->value) + 1) / 2); + else + fprintf (out, ":%s", option->value ? option->value : ""); - /* The name field. */ - fprintf (out, "%s", option->name); + /* ADD NEW FIELDS HERE. */ - /* The flags field. */ - fprintf (out, ":%lu", option->flags); - if (opt.verbose) - { - putc (' ', out); - - if (!option->flags) - fprintf (out, "none"); - else - { - unsigned long flags = option->flags; - unsigned long flag = 0; - unsigned long first = 1; + putc ('\n', out); +} - while (flags) - { - if (flags & 1) - { - if (first) - first = 0; - else - putc (',', out); - fprintf (out, "%s", gc_flag[flag].name); - } - flags >>= 1; - flag++; - } - } + +/* List all options of the component COMPONENT. */ +void +gc_component_list_options (int component, FILE *out) +{ + const gc_option_t *option = gc_component[component].options; + const gc_option_t *group_option = NULL; + + while (option->name) + { + /* Do not output unknown or internal options. */ + if (!(option->flags & GC_OPT_FLAG_GROUP) + && (!option->active || option->level == GC_LEVEL_INTERNAL)) + { + option++; + continue; } - /* The level field. */ - fprintf (out, ":%u", option->level); - if (opt.verbose) - fprintf (out, " %s", gc_level[option->level].name); - - /* The description field. */ - fprintf (out, ":%s", desc ? percent_escape (desc) : ""); - - /* The type field. */ - fprintf (out, ":%u", option->arg_type); - if (opt.verbose) - fprintf (out, " %s", gc_arg_type[option->arg_type].name); - - /* The alternate type field. */ - fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); - if (opt.verbose) - fprintf (out, " %s", - gc_arg_type[gc_arg_type[option->arg_type].fallback].name); - - /* The argument name field. */ - fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); - if (arg_name) - xfree (arg_name); - - /* The default value field. */ - fprintf (out, ":%s", option->default_value ? option->default_value : ""); - - /* The default argument field. */ - fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); - - /* The value field. */ - if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE - && (option->flags & GC_OPT_FLAG_LIST) - && option->value) - /* The special format "1,1,1,1,...,1" is converted to a number - here. */ - fprintf (out, ":%u", (strlen (option->value) + 1) / 2); + if (option->flags & GC_OPT_FLAG_GROUP) + group_option = option; else - fprintf (out, ":%s", option->value ? option->value : ""); + { + if (group_option) + { + list_one_option (group_option, out); + group_option = NULL; + } - /* ADD NEW FIELDS HERE. */ + list_one_option (option, out); + } - putc ('\n', out); option++; } } -- cgit From 8cf4e69141bb11d8fb956d31752293e7bfb5cbcf Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Mon, 8 Mar 2004 17:59:24 +0000 Subject: 2004-03-08 Marcus Brinkmann * gpgconf-comp.c (retrieve_options_from_file): Quote each string in the list, not only the first. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index ba5df4765..9acd30f48 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-03-08 Marcus Brinkmann + + * gpgconf-comp.c (retrieve_options_from_file): Quote each string + in the list, not only the first. + 2004-02-26 Marcus Brinkmann * gpgconf-comp.c (gc_component_list_options): Do not print empty diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5dda4f306..e483675f8 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1172,11 +1172,11 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) while (*(end - 1) == ' ' || *(end - 1) == '\t') end--; *end = '\0'; - /* FIXME: Oh, no! This is so lame! Use realloc and really - append. */ + /* FIXME: Oh, no! This is so lame! Should use realloc and + really append. */ if (list) { - new_list = xasprintf ("%s,%s", list, percent_escape (start)); + new_list = xasprintf ("%s,\"%s", list, percent_escape (start)); xfree (list); list = new_list; } -- cgit From 7ad15ec24a29d76dadc33da8930a3fc7f566903a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 9 Mar 2004 14:34:12 +0000 Subject: Removed special code for RISC OS; we don't want to clutter our code with system dependent stuff. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 9acd30f48..ebdc94eaf 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-03-09 Werner Koch + + * gpgconf-comp.c [_riscos_]: Removed special code for RISC OS; we + don't want to clutter our code with system dependent stuff. + 2004-03-08 Marcus Brinkmann * gpgconf-comp.c (retrieve_options_from_file): Quote each string diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e483675f8..791839a4d 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -42,6 +42,13 @@ /* TODO: Portability - Add gnulib replacements for getline, etc. + +XXX Marcus: Please use the read_line code from dirmngr/src/http.c - it +has been in use for may years and provides the ability to limit the +length of the line and thus thwart DoS (not a issue here but at many +other places). + + Backend: File backend must be able to write out changes !!! Components: Add more components and their options. Robustness: Do more validation. Call programs to do validation for us. @@ -52,8 +59,7 @@ */ -#if defined (__riscos__) \ - || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) +#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )) void gc_error (int status, int errnum, const char *fmt, ...) \ __attribute__ ((format (printf, 3, 4))); #endif -- cgit From 8927b55c28eeab38498165bdea162621d7681523 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 12 Mar 2004 14:29:40 +0000 Subject: 2004-03-12 Marcus Brinkmann * gpgconf-comp.c (gc_component_change_options): Set the filenames of the option's backend, not of the component. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 15 ++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index ebdc94eaf..077115a58 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-03-12 Marcus Brinkmann + + * gpgconf-comp.c (gc_component_change_options): Set the filenames + of the option's backend, not of the component. + 2004-03-09 Werner Koch * gpgconf-comp.c [_riscos_]: Removed special code for RISC OS; we diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 791839a4d..d792d1d75 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2029,7 +2029,8 @@ gc_component_change_options (int component, FILE *in) { /* Go on if we have already seen this backend, or if there is nothing to do. */ - if (src_pathname[option->backend] || !(option->new_flags || option->new_value)) + if (src_pathname[option->backend] + || !(option->new_flags || option->new_value)) { option++; continue; @@ -2037,14 +2038,14 @@ gc_component_change_options (int component, FILE *in) if (gc_backend[option->backend].program) err = change_options_program (component, option->backend, - &src_pathname[component], - &dest_pathname[component], - &orig_pathname[component]); + &src_pathname[option->backend], + &dest_pathname[option->backend], + &orig_pathname[option->backend]); else err = change_options_file (component, option->backend, - &src_pathname[component], - &dest_pathname[component], - &orig_pathname[component]); + &src_pathname[option->backend], + &dest_pathname[option->backend], + &orig_pathname[option->backend]); if (err) break; -- cgit From 2bb4c53e7a99254e1a95810efbb2df0bf8f6bed7 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 12 Mar 2004 14:42:31 +0000 Subject: 2004-03-12 Marcus Brinkmann * gpgconf-comp.c (gc_component_change_options): Set the filenames of the option's backend, not of the component. Also use GC_BACKEND_NR, not GC_COMPONENT_NR. --- tools/ChangeLog | 1 + tools/gpgconf-comp.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 077115a58..1489eb051 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -2,6 +2,7 @@ * gpgconf-comp.c (gc_component_change_options): Set the filenames of the option's backend, not of the component. + Also use GC_BACKEND_NR, not GC_COMPONENT_NR. 2004-03-09 Werner Koch diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index d792d1d75..a55883e55 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2057,7 +2057,7 @@ gc_component_change_options (int component, FILE *in) { int i; - for (i = 0; i < GC_COMPONENT_NR; i++) + for (i = 0; i < GC_BACKEND_NR; i++) { if (src_pathname[i]) { @@ -2089,7 +2089,7 @@ gc_component_change_options (int component, FILE *in) int saved_errno = errno; /* An error occured. */ - for (i = 0; i < GC_COMPONENT_NR; i++) + for (i = 0; i < GC_BACKEND_NR; i++) { if (src_pathname[i]) { -- cgit From a6768b8eca84fb52393393a2c03ca46d5bc28283 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Mar 2004 10:48:13 +0000 Subject: (gc_options_gpg_agent): Implemented. --- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 1489eb051..c8eca3137 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-03-16 Werner Koch + + * gpgconf-comp.c (gc_options_gpg_agent): Implemented. + 2004-03-12 Marcus Brinkmann * gpgconf-comp.c (gc_component_change_options): Set the filenames diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index a55883e55..4785eefb6 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -409,6 +409,57 @@ typedef struct gc_option gc_option_t; /* The options of the GC_COMPONENT_GPG_AGENT component. */ static gc_option_t gc_options_gpg_agent[] = { + /* The configuration file to which we write the changes. */ + { "gpgconf-gpg-agent.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, + + { "Monitor", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the diagnostic output" }, + { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + "gnupg", "verbose", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "be somewhat more quiet", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + + { "Configuration", + GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, + NULL, "Options controlling the configuration" }, + { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "|FILE|read options from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, + + { "Debug", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", "Options useful for debugging" }, + { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "gnupg", "|LEVEL|set the debugging level to LEVEL", + GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, + { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|FILE|write logs to FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, + { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, + + { "Security", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the security" }, + { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, + "gnupg", "|N|expire cached PINs after N seconds", + GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, + { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, + "gnupg", "do not use the PIN cache when signing", + GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, + { "no-grab", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "do not grab keybourd and mouse", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + + GC_OPTION_NULL }; @@ -525,6 +576,14 @@ static gc_option_t gc_options_dirmngr[] = "dirmngr", "|N|do not return more than N items in one query", GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, + { "OCSP", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + NULL, "Configuration for OCSP" }, + { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "|URL|use OCSP responder URL", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + + GC_OPTION_NULL }; -- cgit From 6568059dd647b8d604d669b9ff600cf3b3c78cea Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 16 Mar 2004 19:00:25 +0000 Subject: (gc_options_gpg_agent): Implemented. (gc_options_gpgsm, gc_options_scdaemon): Implemented. (gc_backend_t): Add GC_BACKEND_SCDAEMON. --- tools/ChangeLog | 2 + tools/gpgconf-comp.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 123 insertions(+), 6 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index c8eca3137..9debec445 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,6 +1,8 @@ 2004-03-16 Werner Koch * gpgconf-comp.c (gc_options_gpg_agent): Implemented. + (gc_options_gpgsm, gc_options_scdaemon): Implemented. + (gc_backend_t): Add GC_BACKEND_SCDAEMON. 2004-03-12 Marcus Brinkmann diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 4785eefb6..2839b37cf 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -114,6 +114,9 @@ typedef enum /* The GPG Agent. */ GC_BACKEND_GPG_AGENT, + /* The GnuPG SCDaemon. */ + GC_BACKEND_SCDAEMON, + /* The Aegypten directory manager. */ GC_BACKEND_DIRMNGR, @@ -152,6 +155,7 @@ static struct { "GnuPG", "gpg", "gpgconf-gpg.conf" }, { "GPGSM", "gpgsm", "gpgconf-gpgsm.conf" }, { "GPG Agent", "gpg-agent", "gpgconf-gpg-agent.conf" }, + { "SCDaemon", "scdaemon", "gpgconf-scdaemon.conf" }, { "DirMngr", "dirmngr", "gpgconf-dirmngr.conf" }, { "DirMngr LDAP Server List", NULL, "ldapserverlist-file", "LDAP Server" }, }; @@ -467,6 +471,64 @@ static gc_option_t gc_options_gpg_agent[] = /* The options of the GC_COMPONENT_SCDAEMON component. */ static gc_option_t gc_options_scdaemon[] = { + /* The configuration file to which we write the changes. */ + { "gpgconf-scdaemon.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, + + { "Monitor", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the diagnostic output" }, + { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + "gnupg", "verbose", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "be somewhat more quiet", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + + { "Configuration", + GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, + NULL, "Options controlling the configuration" }, + { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "|FILE|read options from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, + { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "|N|connect to reader at port N", + GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, + { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|NAME|use NAME as ct-API driver", + GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, + { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|NAME|use NAME as PC/SC driver", + GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, + { "disable-opensc", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "do not use the OpenSC layer", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "do not use the internal CCID driver", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + + + { "Debug", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", "Options useful for debugging" }, + { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "gnupg", "|LEVEL|set the debugging level to LEVEL", + GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, + { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|FILE|write logs to FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, + + { "Security", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the security" }, + { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "allow the use of admin card commands", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, + + GC_OPTION_NULL }; @@ -474,6 +536,62 @@ static gc_option_t gc_options_scdaemon[] = /* The options of the GC_COMPONENT_GPGSM component. */ static gc_option_t gc_options_gpgsm[] = { + /* The configuration file to which we write the changes. */ + { "gpgconf-gpgsm.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, + + { "Monitor", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the diagnostic output" }, + { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + "gnupg", "verbose", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "be somewhat more quiet", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + + { "Configuration", + GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, + NULL, "Options controlling the configuration" }, + { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "|FILE|read options from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, + + { "Debug", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", "Options useful for debugging" }, + { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "gnupg", "|LEVEL|set the debugging level to LEVEL", + GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, + { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|FILE|write logs to FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, + { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_UINT32, GC_BACKEND_GPGSM }, + + { "Security", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the security" }, + { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "never consult a CRL", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "check validity using OCSP", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "include-certs", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "|N|number of certificates to include", + GC_ARG_TYPE_INT32, GC_BACKEND_GPGSM }, + { "disable-policy-checks", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "do not check certificate policies", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "auto-issuer-key-retrieve", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "fetch missing issuer certificates", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + GC_OPTION_NULL }; @@ -518,12 +636,9 @@ static gc_option_t gc_options_dirmngr[] = { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, "dirmngr", "Options useful for debugging" }, - { "debug", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, - "dirmngr", "|FLAGS|set the debugging FLAGS", - GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, - { "debug-all", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "set all debugging flags", - GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "dirmngr", "|LEVEL|set the debugging level to LEVEL", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, { "no-detach", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "do not detach from the console", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, -- cgit From 3b2e2e7418b0e83ada626c9699def6085c5953e9 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 23 Mar 2004 12:21:48 +0000 Subject: 2004-03-23 Marcus Brinkmann * gpgconf-comp.c: Include . (gc_backend): Add new member runtime_change. (gpg_agent_runtime_change): New function. (gc_component_change_options): New variable runtime. Initialize it. If an option is changed that has the GC_OPT_FLAG_RUNTIME bit set, also set the corresponding runtime variable. Finally, call the runtime_change callback of the backend if needed. --- tools/ChangeLog | 10 +++++++ tools/gpgconf-comp.c | 73 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 9 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 9debec445..688a22ef1 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,13 @@ +2004-03-23 Marcus Brinkmann + + * gpgconf-comp.c: Include . + (gc_backend): Add new member runtime_change. + (gpg_agent_runtime_change): New function. + (gc_component_change_options): New variable runtime. Initialize + it. If an option is changed that has the GC_OPT_FLAG_RUNTIME bit + set, also set the corresponding runtime variable. Finally, call + the runtime_change callback of the backend if needed. + 2004-03-16 Werner Koch * gpgconf-comp.c (gc_options_gpg_agent): Implemented. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 2839b37cf..b441572cf 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -32,6 +32,7 @@ #include #include #include +#include /* For log_logv(), asctimestamp(), gnupg_get_time (). */ #define JNLIB_NEED_LOG_LOGV @@ -48,8 +49,6 @@ has been in use for may years and provides the ability to limit the length of the line and thus thwart DoS (not a issue here but at many other places). - - Backend: File backend must be able to write out changes !!! Components: Add more components and their options. Robustness: Do more validation. Call programs to do validation for us. Don't use popen, as this will not tell us if the program had a @@ -93,6 +92,9 @@ gc_error (int status, int errnum, const char *fmt, ...) } +/* Forward declaration. */ +void gpg_agent_runtime_change (void); + /* Backend configuration. Backends are used to decide how the default and current value of an option can be determined, and how the option can be changed. To every option in every component belongs @@ -140,6 +142,9 @@ static struct GPGConf. In this case, PROGRAM is NULL. */ char *program; + /* The runtime change callback. */ + void (*runtime_change) (void); + /* The option name for the configuration filename of this backend. This must be an absolute pathname. It can be an option from a different backend (but then ordering of the options might @@ -151,13 +156,15 @@ static struct const char *option_name; } gc_backend[GC_BACKEND_NR] = { - { NULL, NULL, NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", "gpgconf-gpg.conf" }, - { "GPGSM", "gpgsm", "gpgconf-gpgsm.conf" }, - { "GPG Agent", "gpg-agent", "gpgconf-gpg-agent.conf" }, - { "SCDaemon", "scdaemon", "gpgconf-scdaemon.conf" }, - { "DirMngr", "dirmngr", "gpgconf-dirmngr.conf" }, - { "DirMngr LDAP Server List", NULL, "ldapserverlist-file", "LDAP Server" }, + { NULL }, /* GC_BACKEND_ANY dummy entry. */ + { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" }, + { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" }, + { "GPG Agent", "gpg-agent", gpg_agent_runtime_change, + "gpgconf-gpg-agent.conf" }, + { "SCDaemon", "scdaemon", NULL, "gpgconf-scdaemon.conf" }, + { "DirMngr", "dirmngr", NULL, "gpgconf-dirmngr.conf" }, + { "DirMngr LDAP Server List", NULL, NULL, "ldapserverlist-file", + "LDAP Server" }, }; @@ -750,6 +757,40 @@ static struct { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } }; + +/* Engine specific support. */ +void +gpg_agent_runtime_change (void) +{ + char *agent = getenv ("GPG_AGENT_INFO"); + char *pid_str; + unsigned long pid_long; + char *tail; + pid_t pid; + + if (!agent) + return; + + pid_str = strchr (agent, ':'); + if (!pid_str) + return; + + pid_str++; + errno = 0; + pid_long = strtoul (pid_str, &tail, 0); + if (errno || (*tail != ':' && *tail != '\0')) + return; + + pid = (pid_t) pid_long; + + /* Check for overflow. */ + if (pid_long != (unsigned long) pid) + return; + + /* Ignore any errors here. */ + kill (pid, SIGHUP); +} + /* Robust version of dgettext. */ static const char * @@ -2096,6 +2137,7 @@ void gc_component_change_options (int component, FILE *in) { int err = 0; + int runtime[GC_BACKEND_NR]; char *src_pathname[GC_BACKEND_NR]; char *dest_pathname[GC_BACKEND_NR]; char *orig_pathname[GC_BACKEND_NR]; @@ -2107,6 +2149,7 @@ gc_component_change_options (int component, FILE *in) for (backend = 0; backend < GC_BACKEND_NR; backend++) { + runtime[backend] = 0; src_pathname[backend] = NULL; dest_pathname[backend] = NULL; orig_pathname[backend] = NULL; @@ -2169,6 +2212,9 @@ gc_component_change_options (int component, FILE *in) option_check_validity (option, flags, new_value, &new_value_nr); + if (option->flags & GC_OPT_FLAG_RUNTIME) + runtime[option->backend] = 1; + option->new_flags = flags; if (!(flags & GC_OPT_FLAG_DEFAULT)) { @@ -2286,6 +2332,15 @@ gc_component_change_options (int component, FILE *in) } gc_error (1, saved_errno, "could not commit changes"); } + + /* If it all worked, notify the daemons of the changes. */ + if (opt.runtime) + for (backend = 0; backend < GC_BACKEND_NR; backend++) + { + if (runtime[backend] && gc_backend[backend].runtime_change) + (*gc_backend[backend].runtime_change) (); + } + if (line) free (line); } -- cgit From fc584a063df98170b54252722b812c26bac4a3e9 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 23 Mar 2004 12:33:59 +0000 Subject: 2004-03-23 Marcus Brinkmann * gpgconf-comp.c (gc_flag): Add missing flags. --- tools/ChangeLog | 4 +++- tools/gpgconf-comp.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 688a22ef1..1c4b3bdd2 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,12 +1,14 @@ 2004-03-23 Marcus Brinkmann + * gpgconf-comp.c (gc_flag): Add missing flags. + * gpgconf-comp.c: Include . (gc_backend): Add new member runtime_change. (gpg_agent_runtime_change): New function. (gc_component_change_options): New variable runtime. Initialize it. If an option is changed that has the GC_OPT_FLAG_RUNTIME bit set, also set the corresponding runtime variable. Finally, call - the runtime_change callback of the backend if needed. + the runtime_change callback of the backend if needed. 2004-03-16 Werner Koch diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index b441572cf..8d6e223c9 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -336,7 +336,10 @@ static struct { "group" }, { "optional arg" }, { "list" }, - { "runtime" } + { "runtime" }, + { "default" }, + { "default desc" }, + { "no arg desc" } }; -- cgit From d5579da4a3307c3f9e1168ffb9fec4be84989726 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Mar 2004 13:04:34 +0000 Subject: (gc_options_gpg): New. (gc_component_t, gc_component): Add GC_BACKEND_GPG. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 1c4b3bdd2..360efa847 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-03-23 Werner Koch + + * gpgconf-comp.c (gc_options_gpg): New. + (gc_component_t, gc_component): Add GC_BACKEND_GPG. + 2004-03-23 Marcus Brinkmann * gpgconf-comp.c (gc_flag): Add missing flags. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 8d6e223c9..e3990f9c3 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -543,6 +543,52 @@ static gc_option_t gc_options_scdaemon[] = }; +/* The options of the GC_COMPONENT_GPG component. */ +static gc_option_t gc_options_gpg[] = + { + /* The configuration file to which we write the changes. */ + { "gpgconf-gpg.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, + + { "Monitor", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Options controlling the diagnostic output" }, + { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + "gnupg", "verbose", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, + { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "be somewhat more quiet", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, + { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, + NULL, NULL, + GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, + + { "Configuration", + GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, + NULL, "Options controlling the configuration" }, + { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", "|FILE|read options from FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, + + { "Debug", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", "Options useful for debugging" }, + { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + "gnupg", "|LEVEL|set the debugging level to LEVEL", + GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, + { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "|FILE|write logs to FILE", + GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, +/* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */ +/* NULL, NULL, */ +/* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */ + + + GC_OPTION_NULL + }; + + + /* The options of the GC_COMPONENT_GPGSM component. */ static gc_option_t gc_options_gpgsm[] = { @@ -724,6 +770,9 @@ typedef enum /* The Smardcard Daemon. */ GC_COMPONENT_SCDAEMON, + /* The classic GPG for OpenPGP. */ + GC_COMPONENT_GPG + /* GPG for S/MIME. */ GC_COMPONENT_GPGSM, @@ -756,6 +805,7 @@ static struct { { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, + { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } }; -- cgit From 88844c4c41010c75f9d2a5d69bfd9d4970528c13 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Mar 2004 13:11:10 +0000 Subject: add missing comma --- tools/gpgconf-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e3990f9c3..e449d48f2 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -771,7 +771,7 @@ typedef enum GC_COMPONENT_SCDAEMON, /* The classic GPG for OpenPGP. */ - GC_COMPONENT_GPG + GC_COMPONENT_GPG, /* GPG for S/MIME. */ GC_COMPONENT_GPGSM, -- cgit From 333d1a107c587892d9e7583e6f2b97f82dc479ee Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Mar 2004 13:48:46 +0000 Subject: Make it work --- g10/g10.c | 1 + tools/gpgconf-comp.c | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/g10/g10.c b/g10/g10.c index 968163cce..2fbc7e625 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -2965,6 +2965,7 @@ main( int argc, char **argv ) GC_OPT_FLAG_NONE, GC_OPT_FLAG_DEFAULT, GC_OPT_FLAG_NONE ); + printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); } break; diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e449d48f2..fa96a42b7 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -583,6 +583,13 @@ static gc_option_t gc_options_gpg[] = /* NULL, NULL, */ /* GC_ARG_TYPE_UINT32, GC_BACKEND_GPG }, */ + { "Keyserver", + GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, + NULL, "Configuration for Keyservers" }, + { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", "|URL|use keyserver at URL", + GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, + GC_OPTION_NULL }; @@ -764,15 +771,15 @@ static gc_option_t gc_options_dirmngr[] = update GC_COMPONENT below. */ typedef enum { + /* The classic GPG for OpenPGP. */ + GC_COMPONENT_GPG, + /* The GPG Agent. */ GC_COMPONENT_GPG_AGENT, /* The Smardcard Daemon. */ GC_COMPONENT_SCDAEMON, - /* The classic GPG for OpenPGP. */ - GC_COMPONENT_GPG, - /* GPG for S/MIME. */ GC_COMPONENT_GPGSM, @@ -803,9 +810,9 @@ static struct gc_option_t *options; } gc_component[] = { + { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg }, { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, - { "gpg", NULL, "GPG for OpenPGP", gc_options_gpg }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } }; -- cgit From 3b7262e41ebe0ab6e24d0395ec2256246c6e1a4c Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 23 Mar 2004 18:27:37 +0000 Subject: 2004-03-23 Marcus Brinkmann * gpgconf-comp.c (gc_options_dirmngr): Set GC_OPT_FLAG_ARG_OPT for "LDAP Server". (change_options_file): Remove assertion that tests that this flag is not present. Handle an empty string in OPTION->new_value. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 44bb2be58..ed42e5f73 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,10 @@ 2004-03-23 Marcus Brinkmann + * gpgconf-comp.c (gc_options_dirmngr): Set GC_OPT_FLAG_ARG_OPT for + "LDAP Server". + (change_options_file): Remove assertion that tests that this flag + is not present. Handle an empty string in OPTION->new_value. + * gpgconf.c (main): Remove obsolete warning. 2004-03-23 Werner Koch diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index fa96a42b7..da4cfae92 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -743,7 +743,7 @@ static gc_option_t gc_options_dirmngr[] = /* This entry must come after at least one entry for GC_BACKEND_DIRMNGR in this component, so that the entry for "ldapserverlist-file will be initialized before this one. */ - { "LDAP Server", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, NULL, "LDAP server list", GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST }, @@ -1648,7 +1648,6 @@ change_options_file (gc_component_t component, gc_backend_t backend, assert (option); assert (option->active); assert (gc_arg_type[option->arg_type].fallback != GC_ARG_TYPE_NONE); - assert (!(option->flags & GC_OPT_FLAG_ARG_OPT)); /* FIXME. Throughout the function, do better error reporting. */ /* Note that get_config_pathname() calls percent_deescape(), so we @@ -1658,7 +1657,9 @@ change_options_file (gc_component_t component, gc_backend_t backend, orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); arg = option->new_value; - if (arg) + if (arg && arg[0] == '\0') + arg = NULL; + else if (arg) { char *end; -- cgit From 2b1f8df9bdd0535e6c71fb6ed9e32c41364d49b4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Mar 2004 18:43:25 +0000 Subject: Add dirmngr:allow-ocsp --- tools/ChangeLog | 1 + tools/gpgconf-comp.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index ed42e5f73..a9bd5fba5 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -11,6 +11,7 @@ * gpgconf-comp.c (gc_options_gpg): New. (gc_component_t, gc_component): Add GC_BACKEND_GPG. + (gc_options_dirmngr): Add allow-ocsp. 2004-03-23 Marcus Brinkmann diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index da4cfae92..c010e7cfd 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -757,6 +757,9 @@ static gc_option_t gc_options_dirmngr[] = { "OCSP", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, NULL, "Configuration for OCSP" }, + { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "allow sending OCSP requests", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|use OCSP responder URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, -- cgit From 51e2ffaa0ade03e5278fbf9c8d62050083528b12 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 5 Apr 2004 17:25:43 +0000 Subject: Typo fix --- tools/gpgconf-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index c010e7cfd..fa755afe0 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -470,7 +470,7 @@ static gc_option_t gc_options_gpg_agent[] = "gnupg", "do not use the PIN cache when signing", GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, { "no-grab", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, - "gnupg", "do not grab keybourd and mouse", + "gnupg", "do not grab keyboard and mouse", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, -- cgit From 1194f42d5aca06edb8850a93c06b234090228449 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 7 Apr 2004 16:53:55 +0000 Subject: (my_dgettext): Switch the codeset once to utf-8. Allow building with out NLS. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 19 +++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index a9bd5fba5..0a4046cbd 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-04-07 Werner Koch + + * gpgconf-comp.c (my_dgettext): Switch the codeset once to utf-8. + Allow building with out NLS. + 2004-03-23 Marcus Brinkmann * gpgconf-comp.c (gc_options_dirmngr): Set GC_OPT_FLAG_ARG_OPT for diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index fa755afe0..0b56129c1 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -855,16 +855,31 @@ gpg_agent_runtime_change (void) } -/* Robust version of dgettext. */ +/* More or less Robust version of dgettext. It has the sidefeect of + switching the codeset to utf-8 becuase this is what we want to + output. In theory it is posible to keep the orginal code set and + switch back for regular disgnostic output (redefine "_(" for that) + but given the natur of this tool, being something invoked from + other pograms, it does not make much sense. */ static const char * my_dgettext (const char *domain, const char *msgid) { +#ifdef ENABLE_NLS if (domain) { - char *text = dgettext (domain, msgid); + static int switched_codeset; + char *text; + + if (!switched_codeset) + { + bind_textdomain_codeset (PACKAGE_GT, "utf-8"); + switched_codeset = 1; + } + text = dgettext (domain, msgid); return text ? text : msgid; } else +#endif return msgid; } -- cgit From 2c9aac608b25072c823779af56411dcf14bf0ae8 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Tue, 20 Apr 2004 16:02:30 +0000 Subject: 2004-04-20 Marcus Brinkmann * gpgconf-comp.c (gc_options_gpg_agent): Change type of ignore-cache-for-signing option to GC_ARG_TYPE_NONE. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 0a4046cbd..6da70fdda 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-04-20 Marcus Brinkmann + + * gpgconf-comp.c (gc_options_gpg_agent): Change type of + ignore-cache-for-signing option to GC_ARG_TYPE_NONE. + 2004-04-07 Werner Koch * gpgconf-comp.c (my_dgettext): Switch the codeset once to utf-8. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 0b56129c1..8a5c96033 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -468,7 +468,7 @@ static gc_option_t gc_options_gpg_agent[] = GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing", - GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, { "no-grab", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "do not grab keyboard and mouse", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, -- cgit From 99a4774e344676f58a9b94caaa468459b54c22b6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 28 Apr 2004 09:04:03 +0000 Subject: Add --ocsp-signer for the dirmngr backend. --- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 6da70fdda..5fe13021b 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-04-28 Werner Koch + + * gpgconf-comp.c: Add --ocsp-signer for the dirmngr backend. + 2004-04-20 Marcus Brinkmann * gpgconf-comp.c (gc_options_gpg_agent): Change type of diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 8a5c96033..338c43119 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -763,6 +763,9 @@ static gc_option_t gc_options_dirmngr[] = { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|use OCSP responder URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "|FPR|OCSP response signed by FPR", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, GC_OPTION_NULL -- cgit From 8370e202cc74d1cba0166ab727d222c44d6b09c3 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Thu, 29 Apr 2004 19:00:37 +0000 Subject: 2004-04-29 Marcus Brinkmann * gpgconf-comp.c (change_options_program): Turn on utf8-strings in the gpgconf specific part of the config file for the GnuPG backend. --- tools/ChangeLog | 6 ++++++ tools/gpgconf-comp.c | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 5fe13021b..efc78ea9e 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,9 @@ +2004-04-29 Marcus Brinkmann + + * gpgconf-comp.c (change_options_program): Turn on utf8-strings in + the gpgconf specific part of the config file for the GnuPG + backend. + 2004-04-28 Werner Koch * gpgconf-comp.c: Add --ocsp-signer for the dirmngr backend. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 338c43119..089818fd4 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2075,6 +2075,11 @@ change_options_program (gc_component_t component, gc_backend_t backend, Now, dump the changed options (except for those we are going to revert to their default), and write the end marker, possibly followed by the rest of the original file. */ + + /* We have to turn on UTF8 strings for GnuPG. */ + if (backend == GC_BACKEND_GPG) + fprintf (src_file, "utf8-strings\n"); + option = gc_component[component].options; while (option->name) { -- cgit From 93e9f9aedde3ca294eb884edef81adf76e10eb22 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 30 Apr 2004 03:03:34 +0000 Subject: Added more runtime flags for the gpg-agent backend. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index efc78ea9e..529892643 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-04-30 Werner Koch + + * gpgconf-comp.c: Added more runtime flags for the gpg-agent + backend. + 2004-04-29 Marcus Brinkmann * gpgconf-comp.c (change_options_program): Turn on utf8-strings in diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 089818fd4..35ad9b38e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -430,10 +430,10 @@ static gc_option_t gc_options_gpg_agent[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, NULL, "Options controlling the diagnostic output" }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "quiet", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "be somewhat more quiet", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, { "no-greeting", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, @@ -450,7 +450,7 @@ static gc_option_t gc_options_gpg_agent[] = { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, "gnupg", "Options useful for debugging" }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, @@ -469,7 +469,7 @@ static gc_option_t gc_options_gpg_agent[] = { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, - { "no-grab", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, "gnupg", "do not grab keyboard and mouse", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, -- cgit From f93e691d38143ba2b38a95638808e74b4b84ef74 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 30 Apr 2004 03:58:43 +0000 Subject: Allow changing --log-file --- tools/gpgconf-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 35ad9b38e..ce16ce7f4 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -453,7 +453,7 @@ static gc_option_t gc_options_gpg_agent[] = { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|FILE|write logs to FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, -- cgit From 30bbef1a285929422bd99d648592e146cd5418ae Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 3 May 2004 13:37:38 +0000 Subject: * gpg-agent.c: Remove help texts for options lile --lc-ctype. (main): New option --allow-mark-trusted. * trustlist.c (agent_marktrusted): Use it here. * gpg-agent.texi (Agent Options): Add --allow-mark-trusted. * gpgconf-comp.c: Add --allow-mark-trusted for the gpg-agent. --- agent/ChangeLog | 6 ++++++ agent/agent.h | 1 + agent/gpg-agent.c | 33 ++++++++++++++++++++++----------- agent/trustlist.c | 6 +++++- doc/ChangeLog | 4 ++++ doc/gpg-agent.texi | 6 ++++++ tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 3 +++ 8 files changed, 51 insertions(+), 12 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 2f2b1e410..cf4ae79bf 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,9 @@ +2004-05-03 Werner Koch + + * gpg-agent.c: Remove help texts for options lile --lc-ctype. + (main): New option --allow-mark-trusted. + * trustlist.c (agent_marktrusted): Use it here. + 2004-04-30 Werner Koch * protect-tool.c: New option --enable-status-msg. diff --git a/agent/agent.h b/agent/agent.h index a4312e081..99fdc0547 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -58,6 +58,7 @@ struct { int running_detached; /* we are running detached from the tty. */ int ignore_cache_for_signing; + int allow_mark_trusted; int keep_tty; /* don't switch the TTY (for pinentry) on request */ int keep_display; /* don't switch the DISPLAY (for pinentry) on request */ } opt; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 3bf62c26f..ad6ef33ea 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -80,6 +80,7 @@ enum cmd_and_opt_values oDisablePth, oIgnoreCacheForSigning, + oAllowMarkTrusted, oKeepTTY, oKeepDISPLAY, @@ -109,21 +110,26 @@ static ARGPARSE_OPTS opts[] = { { oLogFile, "log-file" ,2, N_("use a log file for the server")}, { oDisablePth, "disable-pth", 0, N_("do not allow multiple connections")}, - { oPinentryProgram, "pinentry-program", 2 , "path to PIN Entry program" }, - { oDisplay, "display", 2, "set the display" }, - { oTTYname, "ttyname", 2, "set the tty terminal node name" }, - { oTTYtype, "ttytype", 2, "set the tty terminal type" }, - { oLCctype, "lc-ctype", 2, "set the tty LC_CTYPE value" }, - { oLCmessages, "lc-messages", 2, "set the tty LC_MESSAGES value" }, + { oPinentryProgram, "pinentry-program", 2 , + N_("|PGM|use PGM as the PIN-Entry program") }, + { oScdaemonProgram, "scdaemon-program", 2 , + N_("|PGM|use PGM as the SCdaemon program") }, - { oScdaemonProgram, "scdaemon-program", 2 , "path to SCdaemon program" }, - { oDefCacheTTL, "default-cache-ttl", 4, - "|N|expire cached PINs after N seconds"}, - { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, - "do not use the PIN cache when signing"}, + { oDisplay, "display", 2, "@" }, + { oTTYname, "ttyname", 2, "@" }, + { oTTYtype, "ttytype", 2, "@" }, + { oLCctype, "lc-ctype", 2, "@" }, + { oLCmessages, "lc-messages", 2, "@" }, { oKeepTTY, "keep-tty", 0, N_("ignore requests to change the TTY")}, { oKeepDISPLAY, "keep-display", 0, N_("ignore requests to change the X display")}, + + { oDefCacheTTL, "default-cache-ttl", 4, + N_("|N|expire cached PINs after N seconds")}, + { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, + N_("do not use the PIN cache when signing")}, + { oAllowMarkTrusted, "allow-mark-trusted", 0, + N_("allow clients to mark keys as \"trusted\"")}, {0} }; @@ -336,6 +342,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) opt.scdaemon_program = NULL; opt.def_cache_ttl = DEFAULT_CACHE_TTL; opt.ignore_cache_for_signing = 0; + opt.allow_mark_trusted = 0; return 1; } @@ -367,6 +374,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; + case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break; + default: return 0; /* not handled */ } @@ -648,6 +657,8 @@ main (int argc, char **argv ) GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); printf ("ignore-cache-for-signing:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); + printf ("allow-mark-trusted:%lu:\n", + GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); agent_exit (0); } diff --git a/agent/trustlist.c b/agent/trustlist.c index 5c3271ac0..19de0708d 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -224,7 +224,7 @@ agent_listtrusted (void *assuan_context) /* Insert the given fpr into our trustdb. We expect FPR to be an all uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'. - This function does first check whether that key has alreay ben put + This function does first check whether that key has alreay been put into the trustdb and returns success in this case. Before a FPR actually gets inserted, the user is asked by means of the pin-entry whether this is actual wants he want to do. @@ -265,6 +265,10 @@ agent_marktrusted (CTRL ctrl, const char *name, const char *fpr, int flag) if (rc != -1) return rc; /* error in the trustdb */ + /* This feature must explicitly been enabled. */ + if (!opt.allow_mark_trusted) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + /* insert a new one */ if (asprintf (&desc, "Please verify that the certificate identified as:%%0A" diff --git a/doc/ChangeLog b/doc/ChangeLog index 39d98b963..a920022d0 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2004-05-03 Werner Koch + + * gpg-agent.texi (Agent Options): Add --allow-mark-trusted. + 2004-02-03 Werner Koch * contrib.texi (Contributors): Updated from the gpg 1.2.3 thanks diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index e199109a4..aad0fbb68 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -238,6 +238,12 @@ seeing what the agent actually does. Don't allow multiple connections. This option is in general not very useful. +@item --allow-mark-trusted +@opindex allow-mark-trusted +Allow clients to mark keys as trusted, i.e. put them into the +@code{trustlist.txt} file. This is by default not allowed to make it +harder for users to inadvertly accept Root-CA keys. + @item --ignore-cache-for-signing @opindex ignore-cache-for-signing This option will let gpg-agent bypass the passphrase cache for all diff --git a/tools/ChangeLog b/tools/ChangeLog index 529892643..fa41aff0a 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-05-03 Werner Koch + + * gpgconf-comp.c: Add --allow-mark-trusted for the gpg-agent. + 2004-04-30 Werner Koch * gpgconf-comp.c: Added more runtime flags for the gpg-agent diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index ce16ce7f4..735e87c86 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -469,6 +469,9 @@ static gc_option_t gc_options_gpg_agent[] = { "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "do not use the PIN cache when signing", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, + { "allow-mark-trusted", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, + "gnupg", "allow clients to mark keys as \"trusted\"", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, { "no-grab", GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, "gnupg", "do not grab keyboard and mouse", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, -- cgit From fb84c86f64019279800e6d92fe85d74b1fd4cf37 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 21 May 2004 13:46:13 +0000 Subject: 2004-05-21 Marcus Brinkmann * gpgconf-comp.c (gc_component_change_options): Move the per-process backup file into a standard location. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index fa41aff0a..61fc7e625 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-05-21 Marcus Brinkmann + + * gpgconf-comp.c (gc_component_change_options): Move the + per-process backup file into a standard location. + 2004-05-03 Werner Koch * gpgconf-comp.c: Add --allow-mark-trusted for the gpg-agent. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 735e87c86..c7bfb0d53 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2431,6 +2431,18 @@ gc_component_change_options (int component, FILE *in) (*gc_backend[backend].runtime_change) (); } + /* Move the per-process backup file into its place. */ + for (backend = 0; backend < GC_BACKEND_NR; backend++) + if (orig_pathname[backend]) + { + char *backup_pathname; + + assert (dest_pathname[backend]); + + backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]); + rename (orig_pathname[backend], backup_pathname); + } + if (line) free (line); } -- cgit From d3c05ee44c2d57aaba501e85a61ef8d3e0b900e0 Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Fri, 21 May 2004 13:55:43 +0000 Subject: 2004-05-21 Marcus Brinkmann * gpgconf-comp.c (gc_options_dirmngr): Remove CRL group, put its only option "max-replies" into LDAP group. (gc_component): Change description of dirmngr to "Directory Manager". --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 61fc7e625..d8e293bc5 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,5 +1,10 @@ 2004-05-21 Marcus Brinkmann + * gpgconf-comp.c (gc_options_dirmngr): Remove CRL group, put its + only option "max-replies" into LDAP group. + (gc_component): Change description of dirmngr to "Directory + Manager". + * gpgconf-comp.c (gc_component_change_options): Move the per-process backup file into a standard location. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index c7bfb0d53..f51be1762 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -749,10 +749,6 @@ static gc_option_t gc_options_dirmngr[] = { "LDAP Server", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, NULL, "LDAP server list", GC_ARG_TYPE_LDAP_SERVER, GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST }, - - { "CRL", - GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration of the CRL" }, { "max-replies", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "|N|do not return more than N items in one query", GC_ARG_TYPE_UINT32, GC_BACKEND_DIRMNGR }, @@ -823,7 +819,7 @@ static struct { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, - { "dirmngr", NULL, "CRL Manager", gc_options_dirmngr } + { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } }; -- cgit From feb40e2c6ec1eb008960fbcbbb683c96110bf8aa Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 14 Jun 2004 08:32:07 +0000 Subject: * xreadline.c: New. Based on the iobuf_read_line function. * no-libgcrypt.c (gcry_realloc, gcry_xmalloc, gcry_xcalloc): New. * gpgconf-comp.c (retrieve_options_from_program) (retrieve_options_from_file, change_options_file) (change_options_program, gc_component_change_options): Replaced getline by read_line and test for allocation failure. --- common/ChangeLog | 4 ++ common/Makefile.am | 1 + common/util.h | 5 +++ common/xreadline.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++ tools/ChangeLog | 9 ++++ tools/gpgconf-comp.c | 62 ++++++++++++--------------- tools/no-libgcrypt.c | 22 ++++++++++ 7 files changed, 183 insertions(+), 36 deletions(-) create mode 100644 common/xreadline.c (limited to 'tools/gpgconf-comp.c') diff --git a/common/ChangeLog b/common/ChangeLog index 2e523618b..a848b8c78 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2004-06-14 Werner Koch + + * xreadline.c: New. Based on the iobuf_read_line function. + 2004-05-12 Werner Koch * util.h (xtrycalloc_secure,xtrymalloc_secure): New. diff --git a/common/Makefile.am b/common/Makefile.am index 4e7fd504c..64b565cd2 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -36,6 +36,7 @@ libcommon_a_SOURCES = \ b64enc.c \ miscellaneous.c \ xasprintf.c \ + xreadline.c \ membuf.c membuf.h \ iobuf.c iobuf.h \ ttyio.c ttyio.h \ diff --git a/common/util.h b/common/util.h index 461e744ad..b9ffe6562 100644 --- a/common/util.h +++ b/common/util.h @@ -99,6 +99,11 @@ int answer_is_yes (const char *s); int answer_is_yes_no_default (const char *s, int def_answer); int answer_is_yes_no_quit (const char *s); +/*-- xreadline.c --*/ +ssize_t read_line (FILE *fp, + char **addr_of_buffer, size_t *length_of_buffer, + size_t *max_length); + /*-- b64enc.c --*/ struct b64state diff --git a/common/xreadline.c b/common/xreadline.c new file mode 100644 index 000000000..85f0af02e --- /dev/null +++ b/common/xreadline.c @@ -0,0 +1,116 @@ +/* xreadline.c - fgets replacement function + * Copyright (C) 1999, 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include + +#include "util.h" + + +/* Same as fgets() but if the provided buffer is too short a larger + one will be allocated. This is similar to getline. A line is + considered a byte stream ending in a LF. + + If MAX_LENGTH is not NULL, it shall point to a value with the + maximum allowed allocation. + + Returns the length of the line. EOF is indicated by a line of + length zero. A truncated line is indicated my setting the value at + MAX_LENGTH to 0. If the returned value is less then 0 not enough + memory was enable and ERRNO is set accordingly. + + If a line has been truncated, the file pointer is moved forward to + the end of the line so that the next read start with tghe next + line. Note that MAX_LENGTH must be re-initialzied in this case.. + + Note: The returned buffer is allocated with enough extra space to + append a CR,LF,Nul + */ +ssize_t +read_line (FILE *fp, + char **addr_of_buffer, size_t *length_of_buffer, + size_t *max_length) +{ + int c; + char *buffer = *addr_of_buffer; + size_t length = *length_of_buffer; + size_t nbytes = 0; + size_t maxlen = max_length? *max_length : 0; + char *p; + + if (!buffer) + { /* No buffer given - allocate a new one. */ + length = 256; + buffer = xtrymalloc (length); + *addr_of_buffer = buffer; + if (!buffer) + { + *length_of_buffer = 0; + if (max_length) + *max_length = 0; + return -1; + } + *length_of_buffer = length; + } + + length -= 3; /* Reserve 3 bytes for CR,LF,EOL. */ + p = buffer; + while ((c = getc (fp)) != EOF) + { + if (nbytes == length) + { /* Enlarge the buffer. */ + if (maxlen && length > maxlen) /* But not beyond our limit. */ + { + /* Skip the rest of the line. */ + while (c != '\n' && (c=getc (fp)) != EOF) + ; + *p++ = '\n'; /* Always append a LF (we reserved some space). */ + nbytes++; + if (max_length) + *max_length = 0; /* Indicate truncation. */ + break; /* the while loop. */ + } + length += 3; /* Adjust for the reserved bytes. */ + length += length < 1024? 256 : 1024; + *addr_of_buffer = xtryrealloc (buffer, length); + if (!*addr_of_buffer) + { + int save_errno = errno; + xfree (buffer); + *length_of_buffer = *max_length = 0; + errno = save_errno; + return -1; + } + buffer = *addr_of_buffer; + *length_of_buffer = length; + length -= 3; + p = buffer + nbytes; + } + *p++ = c; + nbytes++; + if (c == '\n') + break; + } + *p = 0; /* Make sure the line is a string. */ + + return nbytes; +} diff --git a/tools/ChangeLog b/tools/ChangeLog index d8e293bc5..a81a2d301 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,12 @@ +2004-06-14 Werner Koch + + * no-libgcrypt.c (gcry_realloc, gcry_xmalloc, gcry_xcalloc): New. + + * gpgconf-comp.c (retrieve_options_from_program) + (retrieve_options_from_file, change_options_file) + (change_options_program, gc_component_change_options): Replaced + getline by read_line and test for allocation failure. + 2004-05-21 Marcus Brinkmann * gpgconf-comp.c (gc_options_dirmngr): Remove CRL group, put its diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index f51be1762..cc0751d0c 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -42,13 +42,6 @@ /* TODO: - Portability - Add gnulib replacements for getline, etc. - -XXX Marcus: Please use the read_line code from dirmngr/src/http.c - it -has been in use for may years and provides the ability to limit the -length of the line and thus thwart DoS (not a issue here but at many -other places). - Components: Add more components and their options. Robustness: Do more validation. Call programs to do validation for us. Don't use popen, as this will not tell us if the program had a @@ -1252,7 +1245,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) if (!config) gc_error (1, errno, "could not gather active options from %s", cmd_line); - while ((length = getline (&line, &line_len, config)) > 0) + while ((length = read_line (config, &line, &line_len, NULL)) > 0) { gc_option_t *option; char *linep; @@ -1319,7 +1312,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) option->default_value = xstrdup (default_value); } } - if (ferror (config)) + if (length < 0 || ferror (config)) gc_error (1, errno, "error reading from %s", cmd_line); if (fclose (config) && ferror (config)) gc_error (1, errno, "error closing %s", cmd_line); @@ -1334,7 +1327,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) config_pathname); else { - while ((length = getline (&line, &line_len, config)) > 0) + while ((length = read_line (config, &line, &line_len, NULL)) > 0) { char *name; char *value; @@ -1415,14 +1408,13 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend) } } - if (ferror (config)) + if (length < 0 || ferror (config)) gc_error (1, errno, "error reading from %s", config_pathname); if (fclose (config) && ferror (config)) gc_error (1, errno, "error closing %s", config_pathname); } - if (line) - free (line); + xfree (line); } @@ -1451,7 +1443,7 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) else { - while ((length = getline (&line, &line_len, list_file)) > 0) + while ((length = read_line (list_file, &line, &line_len, NULL)) > 0) { char *start; char *end; @@ -1484,15 +1476,14 @@ retrieve_options_from_file (gc_component_t component, gc_backend_t backend) else list = xasprintf ("\"%s", percent_escape (start)); } - if (ferror (list_file)) + if (length < 0 || ferror (list_file)) gc_error (1, errno, "can not read list file %s", list_pathname); } list_option->active = 1; list_option->value = list; - if (line) - free (line); + xfree (line); } @@ -1735,7 +1726,7 @@ change_options_file (gc_component_t component, gc_backend_t backend, if (!dest_file) goto change_file_one_err; - while ((length = getline (&line, &line_len, dest_file)) > 0) + while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) { int disable = 0; char *start; @@ -1823,7 +1814,7 @@ change_options_file (gc_component_t component, gc_backend_t backend, goto change_file_one_err; } } - if (ferror (dest_file)) + if (length < 0 || ferror (dest_file)) goto change_file_one_err; } @@ -1889,17 +1880,18 @@ change_options_file (gc_component_t component, gc_backend_t backend, } if (dest_file) { - while ((length = getline (&line, &line_len, dest_file)) > 0) + while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) { fprintf (src_file, "%s", line); if (ferror (src_file)) goto change_file_one_err; } - if (ferror (dest_file)) + if (length < 0 || ferror (dest_file)) goto change_file_one_err; } - if (line) - free (line); + xfree (line); + line = NULL; + res = fclose (src_file); if (res) { @@ -1920,8 +1912,7 @@ change_options_file (gc_component_t component, gc_backend_t backend, return 0; change_file_one_err: - if (line) - free (line); + xfree (line); res = errno; if (src_file) { @@ -1999,7 +1990,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, if (!dest_file) goto change_one_err; - while ((length = getline (&line, &line_len, dest_file)) > 0) + while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) { int disable = 0; char *start; @@ -2054,7 +2045,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, goto change_one_err; } } - if (ferror (dest_file)) + if (length < 0 || ferror (dest_file)) goto change_one_err; } @@ -2172,17 +2163,18 @@ change_options_program (gc_component_t component, gc_backend_t backend, } if (dest_file) { - while ((length = getline (&line, &line_len, dest_file)) > 0) + while ((length = read_line (dest_file, &line, &line_len, NULL)) > 0) { fprintf (src_file, "%s", line); if (ferror (src_file)) goto change_one_err; } - if (ferror (dest_file)) + if (length < 0 || ferror (dest_file)) goto change_one_err; } - if (line) - free (line); + xfree (line); + line = NULL; + res = fclose (src_file); if (res) { @@ -2203,8 +2195,7 @@ change_options_program (gc_component_t component, gc_backend_t backend, return 0; change_one_err: - if (line) - free (line); + xfree (line); res = errno; if (src_file) { @@ -2241,7 +2232,7 @@ gc_component_change_options (int component, FILE *in) orig_pathname[backend] = NULL; } - while ((length = getline (&line, &line_len, in)) > 0) + while ((length = read_line (in, &line, &line_len, NULL)) > 0) { char *linep; unsigned long flags = 0; @@ -2439,6 +2430,5 @@ gc_component_change_options (int component, FILE *in) rename (orig_pathname[backend], backup_pathname); } - if (line) - free (line); + xfree (line); } diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index b5342732d..0fabec90d 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -38,6 +38,12 @@ out_of_core (void) } +void * +gcry_malloc (size_t n) +{ + return malloc (n); +} + void * gcry_xmalloc (size_t n) { @@ -47,6 +53,13 @@ gcry_xmalloc (size_t n) return p; } + +void * +gcry_realloc (void *a, size_t n) +{ + return realloc (a, n); +} + void * gcry_xrealloc (void *a, size_t n) { @@ -56,6 +69,14 @@ gcry_xrealloc (void *a, size_t n) return p; } + + +void * +gcry_calloc (size_t n, size_t m) +{ + return calloc (n, m); +} + void * gcry_xcalloc (size_t n, size_t m) { @@ -65,6 +86,7 @@ gcry_xcalloc (size_t n, size_t m) return p; } + char * gcry_xstrdup (const char *string) { -- cgit From e4ce12abd176106e41c37a7ffbdb26ebd3a5e884 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 29 Sep 2004 16:16:47 +0000 Subject: * gpgsm.texi (Configuration Options): Add --log-file. * gpgconf-comp.c: Made the entries fro GROUPs translatable. Include i18n.h. (my_dgettext): Hack to use the gnupg2 domain. --- doc/ChangeLog | 2 ++ doc/gpgsm.texi | 4 ++- tools/ChangeLog | 6 +++++ tools/addgnupghome | 4 +-- tools/gpgconf-comp.c | 72 +++++++++++++++++++++++++++++++--------------------- 5 files changed, 56 insertions(+), 32 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/doc/ChangeLog b/doc/ChangeLog index 6373b0339..db72a2020 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,7 @@ 2004-09-29 Werner Koch + * gpgsm.texi (Configuration Options): Add --log-file. + * gpg-agent.texi (Invoking GPG-AGENT): Add a few words about the expected pinentry filename. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 0f2167184..05c351cd8 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -266,7 +266,9 @@ a running dirmngr can't be connected. @opindex no-secmem-warning Don't print a warning when the so called "secure memory" can't be used. - +@item --log-file @var{file} +@opindex log-file +When running in server mode, append all logging output to @var{file}. @end table diff --git a/tools/ChangeLog b/tools/ChangeLog index 841fb0c98..befb1bf3c 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,9 @@ +2004-09-29 Werner Koch + + * gpgconf-comp.c: Made the entries fro GROUPs translatable. + Include i18n.h. + (my_dgettext): Hack to use the gnupg2 domain. + 2004-08-09 Moritz Schulte * gpgsm-gencert.sh: New file. diff --git a/tools/addgnupghome b/tools/addgnupghome index 37a427bf2..fb032b674 100755 --- a/tools/addgnupghome +++ b/tools/addgnupghome @@ -1,5 +1,5 @@ -# !/bin/sh -*- sh -*- -# Add a new .gnupg home directory for a list of users +#!/bin/sh +# Add a new .gnupg home directory for a list of users -*- sh -*- # # Copyright 2004 Free Software Foundation, Inc. # diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index cc0751d0c..b140db76e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -23,8 +23,6 @@ #include #include #include -/* FIXME use gettext.h */ -#include #include #include #include @@ -37,9 +35,11 @@ /* For log_logv(), asctimestamp(), gnupg_get_time (). */ #define JNLIB_NEED_LOG_LOGV #include "util.h" +#include "i18n.h" #include "gpgconf.h" + /* TODO: Components: Add more components and their options. @@ -361,12 +361,19 @@ struct gc_option /* A gettext domain in which the following description can be found. If this is NULL, then DESC is not translated. Valid for groups - and options. */ + and options. + + Note that we try to keep the description of groups within the + gnupg domain. */ const char *desc_domain; /* A gettext description for this group or option. If it starts with a '|', then the string up to the next '|' describes the - argument, and the description follows the second '|'. */ + argument, and the description follows the second '|'. + + In general enclosing these description in N_() is not required + because the description should be identical to the one in the + help menu of the respective program. */ const char *desc; /* The following fields are only valid for options. */ @@ -422,7 +429,7 @@ static gc_option_t gc_options_gpg_agent[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, + "gnupg", N_("Options controlling the diagnostic output") }, { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, @@ -435,14 +442,14 @@ static gc_option_t gc_options_gpg_agent[] = { "Configuration", GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, + "gnupg", N_("Options controlling the configuration") }, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, + "gnupg", N_("Options useful for debugging") }, { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, @@ -455,7 +462,7 @@ static gc_option_t gc_options_gpg_agent[] = { "Security", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, + "gnupg", N_("Options controlling the security") }, { "default-cache-ttl", GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "|N|expire cached PINs after N seconds", GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT }, @@ -483,7 +490,7 @@ static gc_option_t gc_options_scdaemon[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, + "gnupg", N_("Options controlling the diagnostic output") }, { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, @@ -496,7 +503,7 @@ static gc_option_t gc_options_scdaemon[] = { "Configuration", GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, + "gnupg", N_("Options controlling the configuration") }, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, @@ -519,7 +526,7 @@ static gc_option_t gc_options_scdaemon[] = { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, + "gnupg", N_("Options useful for debugging") }, { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, @@ -529,7 +536,7 @@ static gc_option_t gc_options_scdaemon[] = { "Security", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, + "gnupg", N_("Options controlling the security") }, { "allow-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "allow the use of admin card commands", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, @@ -548,7 +555,7 @@ static gc_option_t gc_options_gpg[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, + "gnupg", N_("Options controlling the diagnostic output") }, { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, @@ -561,14 +568,14 @@ static gc_option_t gc_options_gpg[] = { "Configuration", GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, + "gnupg", N_("Options controlling the configuration") }, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, + "gnupg", N_("Options useful for debugging") }, { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, @@ -581,7 +588,7 @@ static gc_option_t gc_options_gpg[] = { "Keyserver", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration for Keyservers" }, + "gnupg", N_("Configuration for Keyservers") }, { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "|URL|use keyserver at URL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, @@ -601,7 +608,7 @@ static gc_option_t gc_options_gpgsm[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, + "gnupg", N_("Options controlling the diagnostic output") }, { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, @@ -614,14 +621,14 @@ static gc_option_t gc_options_gpgsm[] = { "Configuration", GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, + "gnupg", N_("Options controlling the configuration") }, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "gnupg", "Options useful for debugging" }, + "gnupg", N_("Options useful for debugging") }, { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, @@ -634,7 +641,7 @@ static gc_option_t gc_options_gpgsm[] = { "Security", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the security" }, + "gnupg", N_("Options controlling the security") }, { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "never consult a CRL", GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, @@ -664,7 +671,7 @@ static gc_option_t gc_options_dirmngr[] = { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the diagnostic output" }, + "gnupg", N_("Options controlling the diagnostic output") }, { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, "dirmngr", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, @@ -677,7 +684,7 @@ static gc_option_t gc_options_dirmngr[] = { "Format", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the format of the output" }, + "gnupg", N_("Options controlling the format of the output") }, { "sh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "sh-style command output", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, @@ -687,14 +694,14 @@ static gc_option_t gc_options_dirmngr[] = { "Configuration", GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT, - NULL, "Options controlling the configuration" }, + "gnupg", N_("Options controlling the configuration") }, { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "dirmngr", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - "dirmngr", "Options useful for debugging" }, + "gnupg", N_("Options useful for debugging") }, { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, "dirmngr", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, @@ -713,7 +720,7 @@ static gc_option_t gc_options_dirmngr[] = { "Enforcement", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Options controlling the interactivity and enforcement" }, + "gnupg", N_("Options controlling the interactivity and enforcement") }, { "batch", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "run without asking a user", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, @@ -723,7 +730,7 @@ static gc_option_t gc_options_dirmngr[] = { "LDAP", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, - NULL, "Configuration of LDAP servers to use" }, + "gnupg", N_("Configuration of LDAP servers to use") }, { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "add new servers discovered in CRL distribution points" " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, @@ -748,7 +755,7 @@ static gc_option_t gc_options_dirmngr[] = { "OCSP", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, - NULL, "Configuration for OCSP" }, + "gnupg", N_("Configuration for OCSP") }, { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "allow sending OCSP requests", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, @@ -850,8 +857,8 @@ gpg_agent_runtime_change (void) } -/* More or less Robust version of dgettext. It has the sidefeect of - switching the codeset to utf-8 becuase this is what we want to +/* More or less Robust version of dgettext. It has the side effect of + switching the codeset to utf-8 because this is what we want to output. In theory it is posible to keep the orginal code set and switch back for regular disgnostic output (redefine "_(" for that) but given the natur of this tool, being something invoked from @@ -870,6 +877,13 @@ my_dgettext (const char *domain, const char *msgid) bind_textdomain_codeset (PACKAGE_GT, "utf-8"); switched_codeset = 1; } + + /* Note: This is a hack to actually use the gnupg2 domain as + long we are in a transition phase where gnupg 1.x and 1.9 may + coexist. */ + if (!strcmp (domain, "gnupg")) + domain = PACKAGE_GT; + text = dgettext (domain, msgid); return text ? text : msgid; } -- cgit From a90acadd51081fcb69460cb2222ed4be20e903d3 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 1 Oct 2004 12:53:09 +0000 Subject: * gpgconf-comp.c (my_dgettext): Also switch codeset and directory for the other used domains (i.e. dirmngr). * gpgconf.c (main): Fixed translation markers. --- po/de.po | 98 ++++++++++++++++++++++++++++------------------------ sm/gpgsm.c | 2 +- tools/ChangeLog | 7 ++++ tools/gpgconf-comp.c | 15 +++++--- tools/gpgconf.c | 7 ++-- 5 files changed, 76 insertions(+), 53 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/po/de.po b/po/de.po index 3c4d90a44..77ce206c0 100644 --- a/po/de.po +++ b/po/de.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: gnupg2 1.9.10\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-09-30 15:22+0200\n" -"PO-Revision-Date: 2004-09-30 15:23+0200\n" +"POT-Creation-Date: 2004-10-01 14:24+0200\n" +"PO-Revision-Date: 2004-10-01 14:27+0200\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -41,7 +41,7 @@ msgstr "ausf #: agent/gpg-agent.c:102 kbx/kbxutil.c:82 scd/scdaemon.c:98 sm/gpgsm.c:316 msgid "be somewhat more quiet" -msgstr "etwas weniger Aussageb erzeugen" +msgstr "Etwas weniger Ausgaben erzeugen" #: agent/gpg-agent.c:103 scd/scdaemon.c:99 msgid "sh-style command output" @@ -121,30 +121,30 @@ msgstr "" "Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n" "Verwaltung von geheimen Schlüssel für GnuPG\n" -#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:608 +#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:603 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "ungültige Debugebene `%s' angegeben\n" -#: agent/gpg-agent.c:446 agent/protect-tool.c:1050 kbx/kbxutil.c:436 -#: scd/scdaemon.c:357 scd/sc-investigate.c:181 sm/gpgsm.c:731 +#: agent/gpg-agent.c:446 agent/protect-tool.c:1050 kbx/kbxutil.c:431 +#: scd/scdaemon.c:357 scd/sc-investigate.c:181 sm/gpgsm.c:726 #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" "Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n" -#: agent/gpg-agent.c:519 scd/scdaemon.c:437 sm/gpgsm.c:829 +#: agent/gpg-agent.c:519 scd/scdaemon.c:437 sm/gpgsm.c:824 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n" #: agent/gpg-agent.c:524 agent/gpg-agent.c:998 scd/scdaemon.c:442 -#: sm/gpgsm.c:833 +#: sm/gpgsm.c:828 #, c-format msgid "option file `%s': %s\n" msgstr "Konfigurationsdatei `%s': %s\n" -#: agent/gpg-agent.c:532 scd/scdaemon.c:450 sm/gpgsm.c:840 +#: agent/gpg-agent.c:532 scd/scdaemon.c:450 sm/gpgsm.c:835 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden aus `%s' gelesen\n" @@ -412,7 +412,7 @@ msgstr "Den OpenSC basierten Kartenzugriff nicht nutzen" #: scd/scdaemon.c:126 msgid "allow the use of admin card commands" -msgstr "Erlaube die Benuztung von \"Admin\" Kommandos" +msgstr "Erlaube die Benutzung von \"Admin\" Kommandos" #: scd/scdaemon.c:171 msgid "Usage: scdaemon [options] (-h for help)" @@ -569,23 +569,23 @@ msgstr "keine" msgid "[none]" msgstr "[keine]" -#: sm/certdump.c:490 +#: sm/certdump.c:493 msgid "[Error - No name]" msgstr "[Fehler - Kein Name]" -#: sm/certdump.c:499 +#: sm/certdump.c:507 msgid "[Error - unknown encoding]" msgstr "[Fehler - Unbekannte Kodierung]" -#: sm/certdump.c:503 +#: sm/certdump.c:511 msgid "[Error - invalid encoding]" msgstr "[Fehler - Ungültige Kodierung]" -#: sm/certdump.c:508 +#: sm/certdump.c:516 msgid "[Error - invalid DN]" msgstr "[Fehler - Ungültiger DN]" -#: sm/certdump.c:655 +#: sm/certdump.c:677 #, c-format msgid "" "Please enter the passphrase to unlock the secret key for:\n" @@ -907,7 +907,7 @@ msgstr "Eingabedaten sind im PEM Format" #: sm/gpgsm.c:269 msgid "assume input is in base-64 format" -msgstr "Eingabedaten sin im Basis-64 Format" +msgstr "Eingabedaten sind im Basis-64 Format" #: sm/gpgsm.c:271 msgid "assume input is in binary format" @@ -1009,6 +1009,10 @@ msgstr "|HOST|Benutze HOST als Schl msgid "|NAME|set terminal charset to NAME" msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen" +#: sm/gpgsm.c:338 +msgid "|LEVEL|set the debugging level to LEVEL" +msgstr "|STRING|Die Debugstufe auf STING setzen" + #: sm/gpgsm.c:345 msgid "|FD|write status info to this FD" msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben" @@ -1078,50 +1082,50 @@ msgstr "" "\n" "Unterstützte Algorithmen:\n" -#: sm/gpgsm.c:579 +#: sm/gpgsm.c:574 msgid "usage: gpgsm [options] " msgstr "Gebrauch: gpgsm [Optionen] " -#: sm/gpgsm.c:645 +#: sm/gpgsm.c:640 msgid "conflicting commands\n" msgstr "Widersprechende Kommandos\n" -#: sm/gpgsm.c:661 +#: sm/gpgsm.c:656 #, c-format msgid "can't encrypt to `%s': %s\n" msgstr "Verschlüsseln für `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:736 +#: sm/gpgsm.c:731 #, c-format msgid "libksba is too old (need %s, have %s)\n" msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" -#: sm/gpgsm.c:1183 +#: sm/gpgsm.c:1178 msgid "WARNING: program may create a core file!\n" msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" -#: sm/gpgsm.c:1195 +#: sm/gpgsm.c:1190 msgid "WARNING: running with faked system time: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " -#: sm/gpgsm.c:1221 +#: sm/gpgsm.c:1216 msgid "selected cipher algorithm is invalid\n" msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" -#: sm/gpgsm.c:1229 +#: sm/gpgsm.c:1224 msgid "selected digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: sm/gpgsm.c:1259 +#: sm/gpgsm.c:1254 #, c-format msgid "can't sign using `%s': %s\n" msgstr "Signieren mit `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:1423 +#: sm/gpgsm.c:1418 msgid "this command has not yet been implemented\n" msgstr "Diee Kommando wurde noch nicht implementiert\n" -#: sm/gpgsm.c:1646 sm/gpgsm.c:1679 +#: sm/gpgsm.c:1641 sm/gpgsm.c:1674 #, c-format msgid "can't open `%s': %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" @@ -1330,54 +1334,58 @@ msgstr "" "Syntax: gpgconf {Optionen]\n" "Verwalte Konfigurationsoptionen für Programme des GnuPG Systems\n" -#: tools/gpgconf.c:180 +#: tools/gpgconf.c:175 msgid "usage: gpgconf [options] " msgstr "Gebrauch: gpgconf [Optionen] " -#: tools/gpgconf.c:181 +#: tools/gpgconf.c:176 msgid "Need one component argument" msgstr "Benötige ein Komponenten Argument" -#: tools/gpgconf.c:190 +#: tools/gpgconf.c:185 msgid "Component not found" msgstr "Komponente nicht gefunden" -#: tools/gpgconf-comp.c:432 tools/gpgconf-comp.c:493 tools/gpgconf-comp.c:558 -#: tools/gpgconf-comp.c:611 tools/gpgconf-comp.c:674 +#: tools/gpgconf-comp.c:435 tools/gpgconf-comp.c:496 tools/gpgconf-comp.c:561 +#: tools/gpgconf-comp.c:614 tools/gpgconf-comp.c:677 msgid "Options controlling the diagnostic output" msgstr "Optionen zur Einstellung Diagnoseausgaben" -#: tools/gpgconf-comp.c:445 tools/gpgconf-comp.c:506 tools/gpgconf-comp.c:571 -#: tools/gpgconf-comp.c:624 tools/gpgconf-comp.c:697 +#: tools/gpgconf-comp.c:448 tools/gpgconf-comp.c:509 tools/gpgconf-comp.c:574 +#: tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:700 msgid "Options controlling the configuration" msgstr "Optionen zur Einstellung der Konfiguration" -#: tools/gpgconf-comp.c:452 tools/gpgconf-comp.c:529 tools/gpgconf-comp.c:578 -#: tools/gpgconf-comp.c:631 tools/gpgconf-comp.c:704 +#: tools/gpgconf-comp.c:455 tools/gpgconf-comp.c:532 tools/gpgconf-comp.c:581 +#: tools/gpgconf-comp.c:634 tools/gpgconf-comp.c:707 msgid "Options useful for debugging" -msgstr "Nützliche Optionen zum Debuggen" +msgstr "Nützliche Optionen zum Debuggen" + +#: tools/gpgconf-comp.c:460 +msgid "|FILE|write server mode logs to FILE" +msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI" -#: tools/gpgconf-comp.c:465 tools/gpgconf-comp.c:539 tools/gpgconf-comp.c:644 +#: tools/gpgconf-comp.c:468 tools/gpgconf-comp.c:542 tools/gpgconf-comp.c:647 msgid "Options controlling the security" msgstr "Optionen zur Einstellung der Sicherheit" -#: tools/gpgconf-comp.c:591 +#: tools/gpgconf-comp.c:594 msgid "Configuration for Keyservers" -msgstr "Konfiguration der Schlüsselserver" +msgstr "Konfiguration der Schlüsselserver" -#: tools/gpgconf-comp.c:687 +#: tools/gpgconf-comp.c:690 msgid "Options controlling the format of the output" msgstr "Optionen zum Einstellen der Ausgabeformate" -#: tools/gpgconf-comp.c:723 +#: tools/gpgconf-comp.c:726 msgid "Options controlling the interactivity and enforcement" -msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung" +msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung" -#: tools/gpgconf-comp.c:733 +#: tools/gpgconf-comp.c:736 msgid "Configuration of LDAP servers to use" msgstr "Konfiguration der zu nutzenden LDAP-Server" -#: tools/gpgconf-comp.c:758 +#: tools/gpgconf-comp.c:761 msgid "Configuration for OCSP" msgstr "Konfiguration zu OCSP" diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 6e2bbe742..0f620c091 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -335,7 +335,7 @@ static ARGPARSE_OPTS opts[] = { { oOptions, "options" , 2, N_("read options from file")}, { oDebug, "debug" ,4|16, "@"}, - { oDebugLevel, "debug-level" ,2, "@"}, + { oDebugLevel, "debug-level" ,2, N_("|LEVEL|set the debugging level to LEVEL")}, { oDebugAll, "debug-all" ,0, "@"}, { oDebugWait, "debug-wait" ,1, "@"}, { oDebugAllowCoreDump, "debug-allow-core-dump", 0, "@" }, diff --git a/tools/ChangeLog b/tools/ChangeLog index 1eefac53a..c18562f01 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,10 @@ +2004-10-01 Werner Koch + + * gpgconf-comp.c (my_dgettext): Also switch codeset and directory + for the other used domains (i.e. dirmngr). + + * gpgconf.c (main): Fixed translation markers. + 2004-09-30 Werner Koch * gpgconf.c (i18n_init): Always use LC_ALL. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index b140db76e..e69b177e4 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -364,7 +364,10 @@ struct gc_option and options. Note that we try to keep the description of groups within the - gnupg domain. */ + gnupg domain. + + IMPORTANT: If you add a new domain please make sure to add a code + set switching call to the function my_dgettext further below. */ const char *desc_domain; /* A gettext description for this group or option. If it starts @@ -454,7 +457,7 @@ static gc_option_t gc_options_gpg_agent[] = "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG_AGENT }, { "log-file", GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", + "gnupg", N_("|FILE|write server mode logs to FILE"), GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, NULL, NULL, @@ -760,7 +763,7 @@ static gc_option_t gc_options_dirmngr[] = "dirmngr", "allow sending OCSP requests", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|URL|use OCSP responder URL", + "dirmngr", "|URL|use OCSP responder at URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, { "ocsp-signer", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|FPR|OCSP response signed by FPR", @@ -874,8 +877,12 @@ my_dgettext (const char *domain, const char *msgid) if (!switched_codeset) { - bind_textdomain_codeset (PACKAGE_GT, "utf-8"); switched_codeset = 1; + bind_textdomain_codeset (PACKAGE_GT, "utf-8"); + + bindtextdomain ("dirmngr", LOCALEDIR); + bind_textdomain_codeset ("dirmngr", "utf-8"); + } /* Note: This is a hack to actually use the gnupg2 domain as diff --git a/tools/gpgconf.c b/tools/gpgconf.c index e3e1b9f1a..dd505e99d 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -172,8 +172,9 @@ main (int argc, char **argv) case aChangeOptions: if (!fname) { - fputs (N_("usage: gpgconf [options] "), stderr); - fputs (N_("Need one component argument"), stderr); + fputs (_("usage: gpgconf [options] "), stderr); + putc ('\n',stderr); + fputs (_("Need one component argument"), stderr); putc ('\n',stderr); exit (2); } @@ -182,7 +183,7 @@ main (int argc, char **argv) int idx = gc_component_find (fname); if (idx < 0) { - fputs (N_("Component not found"), stderr); + fputs (_("Component not found"), stderr); putc ('\n', stderr); exit (1); } -- cgit From 545ddc6f3d7d79e48bd72f10efefe18b7585865b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 1 Oct 2004 16:51:18 +0000 Subject: Made all strings for --log-file read the same. --- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index c18562f01..ccfd39293 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-10-01 Werner Koch + + * gpgconf-comp.c: Made all strings for --log-file read the same. + 2004-10-01 Werner Koch * gpgconf-comp.c (my_dgettext): Also switch codeset and directory diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e69b177e4..67623ccfd 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -534,7 +534,7 @@ static gc_option_t gc_options_scdaemon[] = "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", + "gnupg", N_("|FILE|write server mode logs to FILE"), GC_ARG_TYPE_PATHNAME, GC_BACKEND_SCDAEMON }, { "Security", @@ -583,7 +583,7 @@ static gc_option_t gc_options_gpg[] = "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", + "gnupg", N_("|FILE|write server mode logs to FILE"), GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG }, /* { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, */ /* NULL, NULL, */ @@ -636,7 +636,7 @@ static gc_option_t gc_options_gpgsm[] = "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "gnupg", "|FILE|write logs to FILE", + "gnupg", N_("|FILE|write server mode logs to FILE"), GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, { "faked-system-time", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, NULL, NULL, @@ -712,7 +712,7 @@ static gc_option_t gc_options_dirmngr[] = "dirmngr", "do not detach from the console", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, - "dirmngr", "|FILE|write logs to FILE", + "dirmngr", N_("|FILE|write server mode logs to FILE"), GC_ARG_TYPE_PATHNAME, GC_BACKEND_DIRMNGR }, { "debug-wait", GC_OPT_FLAG_NONE, GC_LEVEL_INVISIBLE, NULL, NULL, -- cgit From c7b97075aa213a7ac54b8c56679719679816b3fa Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 Nov 2004 17:09:51 +0000 Subject: * b64enc.c: Include stdio.h and string.h * gpgsm.c: New option --prefer-system-dirmngr. * call-dirmngr.c (start_dirmngr): Implement this option. * gpgconf-comp.c : Add the proxy options. : Add --prefer-system-daemon. --- TODO | 11 ++--------- common/ChangeLog | 4 ++++ common/b64enc.c | 2 ++ doc/ChangeLog | 4 ++++ doc/debugging.texi | 23 +++++++++++++++++++---- doc/gpg-agent.texi | 2 +- doc/gpgsm.texi | 6 ++++++ jnlib/ChangeLog | 9 +++++++++ jnlib/logging.c | 10 +++++++--- sm/ChangeLog | 5 +++++ sm/call-dirmngr.c | 50 ++++++++++++++++++++++++++++++++------------------ sm/gpgsm.c | 7 ++++++- sm/gpgsm.h | 1 + tools/ChangeLog | 9 +++++++++ tools/gpgconf-comp.c | 24 +++++++++++++++++++++++- tools/watchgnupg.c | 2 +- 16 files changed, 131 insertions(+), 38 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/TODO b/TODO index a80dfa453..138f9bade 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,8 @@ might want to have an agent context for each service request * sm/certlist.c ** ocspSigning usage is not fully implemented We should review the entire CRL and OCSP validation system. + Okay. This has been fixed in dirmngr when running it in system + daemon mode. * sm/decrypt.c ** replace leading zero in integer hack by a cleaner solution @@ -93,12 +95,3 @@ might want to have an agent context for each service request This needs support in libksba/src/cert.c as well as in sm/*.c. Need test certs as well. Same goes for CRL authorityKeyIdentifier. -** Dirmngr: name subordination (nameRelativeToCRLIssuer) - is not yet supported by Dirmngr. - -** Dirmngr: CRL DP URI - The CRL DP shall use an URI for LDAP without a host name. The host - name shall be looked by using the DN in the URI. We don't implement - this yet. Solution is to have a mapping DN->host in our ldapservers - configuration file. - diff --git a/common/ChangeLog b/common/ChangeLog index f0e7bf67a..d5ded50c9 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2004-11-23 Werner Koch + + * b64enc.c: Include stdio.h and string.h + 2004-08-18 Werner Koch * simple-pwquery.c (simple_pwquery): Handle gpg-error style return diff --git a/common/b64enc.c b/common/b64enc.c index edcf6e3ad..5b7a42ab3 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -19,7 +19,9 @@ */ #include +#include #include +#include #include #include diff --git a/doc/ChangeLog b/doc/ChangeLog index 4262865a5..9a9e213a3 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,7 @@ +2004-11-05 Werner Koch + + * debugging.texi (Common Problems): Curses pinentry problem. + 2004-10-22 Werner Koch * tools.texi (Helper Tools): Document gpgsm-gencert.sh. diff --git a/doc/debugging.texi b/doc/debugging.texi index 9406ba567..b9ae06e2b 100644 --- a/doc/debugging.texi +++ b/doc/debugging.texi @@ -5,7 +5,7 @@ @node Debugging @chapter How to solve problems -Everone knows that software often does not do what it should do and thus +Everyone knows that software often does not do what it should do and thus there is a need to track down problems. We call this debugging in a reminiscent to the moth jamming a relay in a Mark II box back in 1947. @@ -87,9 +87,24 @@ in a standard way and directly available from @command{gpgsm}. @itemize @bullet @item Error code @samp{Not supported} from Dirmngr - Most likely the option @option{enable-ocsp} is active for gpgsm - but Dirmngr's OCSP feature has not been enabled using - @option{allow-ocsp} in @file{dirmngr.conf}. +Most likely the option @option{enable-ocsp} is active for gpgsm +but Dirmngr's OCSP feature has not been enabled using +@option{allow-ocsp} in @file{dirmngr.conf}. + +@item The Curses based Pinentry does not work + +The far most common reason for this is that the environment variable +@code{GPG_TTY} has not been set correctly. Make sure that it has been +set to a real tty devce and not just to @samp{/dev/tty}; +i.e. @samp{GPG_TTY=tty} is plainly wrong; what you want is +@samp{GPG_TTY=`tty`} --- note the back ticks. Also make sure that +this environment variable gets exported, that is you should follow up +the setting with an @samp{export GPG_TTY} (assuming a Bourne style +shell). Even for GUI based Pinentries; you should have set +@code{GPG_TTY}. See the section on installing the @program{gpg-agent} +on how to do it. + + @end itemize diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index f361cbf6b..cccbef02a 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -43,7 +43,7 @@ fi @end smallexample @noindent -You should aleays add the following lines to your @code{.bashrc} or +You should aleways add the following lines to your @code{.bashrc} or whatever initialization file is used for all shell invocations: @smallexample diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 94e6936ad..beedab7b7 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -262,6 +262,12 @@ default value is @file{/usr/sbin/dirmngr}. This is only used as a fallback when the environment variable @code{DIRMNGR_INFO} is not set or a running dirmngr can't be connected. +@item --prefer-system-dirmngr +@opindex prefer-system-dirmngr +If a system wide @command{dirmngr} is running in daemon mode, first try +to connect to this one. Fallback to a pipe based server if this does +not work. + @item --no-secmem-warning @opindex no-secmem-warning Don't print a warning when the so called "secure memory" can't be used. diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index 3c2d6d84a..517cfb73f 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,12 @@ +2004-11-22 Werner Koch + + * logging.c (log_test_fd): Add test on LOGSTREAM. Reported by + Barry Schwartz. + +2004-11-18 Werner Koch + + * logging.c: Explicitly include sys/stat.h for the S_I* constants. + 2004-10-21 Werner Koch * logging.c (do_logv): Use set_log_stream to setup a default. diff --git a/jnlib/logging.c b/jnlib/logging.c index 7a5e1552e..5397a1184 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -411,9 +412,12 @@ log_get_prefix (unsigned int *flags) int log_test_fd (int fd) { - int tmp = fileno (logstream); - if ( tmp != -1 && tmp == fd) - return 1; + if (logstream) + { + int tmp = fileno (logstream); + if ( tmp != -1 && tmp == fd) + return 1; + } if (log_socket != -1 && log_socket == fd) return 1; return 0; diff --git a/sm/ChangeLog b/sm/ChangeLog index 6dd5a28f3..acfa7f3bd 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,8 @@ +2004-11-23 Werner Koch + + * gpgsm.c: New option --prefer-system-dirmngr. + * call-dirmngr.c (start_dirmngr): Implement this option. + 2004-10-22 Werner Koch * certreqgen.c (gpgsm_genkey): Remove the NEW from the certificate diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 849b8a04c..c70f56580 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -35,6 +35,8 @@ #include "i18n.h" #include "keydb.h" +/* The name of the socket for a system daemon. */ +#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket" struct membuf { size_t len; @@ -145,6 +147,7 @@ start_dirmngr (void) int rc; char *infostr, *p; ASSUAN_CONTEXT ctx; + int try_default = 0; if (dirmngr_ctx) return 0; /* fixme: We need a context for each thread or serialize @@ -153,6 +156,12 @@ start_dirmngr (void) to take care of the implicit option sending caching. */ infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); + if (opt.prefer_system_dirmngr && !force_pipe_server + &&(!infostr || !*infostr)) + { + infostr = DEFAULT_SOCKET_NAME; + try_default = 1; + } if (!infostr || !*infostr) { const char *pgmname; @@ -197,26 +206,31 @@ start_dirmngr (void) int pid; infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) + if (!try_default && *infostr) { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("dirmngr protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); + if ( !(p = strchr (infostr, ':')) || p == infostr) + { + log_error (_("malformed DIRMNGR_INFO environment variable\n")); + xfree (infostr); + force_pipe_server = 1; + return start_dirmngr (); + } + *p++ = 0; + pid = atoi (p); + while (*p && *p != ':') + p++; + prot = *p? atoi (p+1) : 0; + if (prot != 1) + { + log_error (_("dirmngr protocol version %d is not supported\n"), + prot); + xfree (infostr); + force_pipe_server = 1; + return start_dirmngr (); + } } + else + pid = -1; rc = assuan_socket_connect (&ctx, infostr, pid); xfree (infostr); diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 0f620c091..c9ce8fd9f 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -107,6 +107,7 @@ enum cmd_and_opt_values { oLCctype, oLCmessages, + oPreferSystemDirmngr, oDirmngrProgram, oProtectToolProgram, oFakedSystemTime, @@ -272,7 +273,8 @@ static ARGPARSE_OPTS opts[] = { { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - + { oPreferSystemDirmngr,"prefer-system-dirmngr", 0, + N_("use system's dirmngr if available")}, { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, { oForceCRLRefresh, "force-crl-refresh", 0, "@"}, @@ -1047,6 +1049,7 @@ main ( int argc, char **argv) case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; + case oPreferSystemDirmngr: opt.prefer_system_dirmngr = 1; break; case oProtectToolProgram: opt.protect_tool_program = pargs.r.ret_str; break; @@ -1333,6 +1336,8 @@ main ( int argc, char **argv) GC_OPT_FLAG_NONE ); printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE ); + printf ("prefer-system-dirmngr:%lu:\n", + GC_OPT_FLAG_NONE ); } break; diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 18f50e9fe..faa6e8b5c 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -55,6 +55,7 @@ struct { char *lc_messages; const char *dirmngr_program; + int prefer_system_dirmngr; /* Prefer using a system wide drimngr. */ const char *protect_tool_program; char *outfile; /* name of output file */ diff --git a/tools/ChangeLog b/tools/ChangeLog index 18412753c..9158d7ca5 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,12 @@ +2004-11-23 Werner Koch + + * gpgconf-comp.c : Add the proxy options. + : Add --prefer-system-daemon. + +2004-11-11 Werner Koch + + * watchgnupg.c (main): Fixed test for read error. + 2004-10-22 Werner Koch * Makefile.am (bin_SCRIPTS): Add gpgsm-gencert.sh diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 67623ccfd..ec606ea2b 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -628,6 +628,9 @@ static gc_option_t gc_options_gpgsm[] = { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, + { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "use system's dirmngr if available", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, @@ -731,10 +734,29 @@ static gc_option_t gc_options_dirmngr[] = "dirmngr", "force loading of outdated CRLs", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "HTTP", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", N_("Configuration for HTTP servers") }, + { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "inhibit the use of HTTP", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "|URL|redirect all HTTP requests to URL", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "LDAP", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, "gnupg", N_("Configuration of LDAP servers to use") }, - { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "inhibit the use of LDAP", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "|HOST|use HOST for LDAP queries", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "do not use fallback hosts with --ldap-proxy", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "add new servers discovered in CRL distribution points" " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 7f79f2f18..50f9d7274 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -354,7 +354,7 @@ main (int argc, char **argv) int n; n = read (client->fd, line, sizeof line - 1); - if (n == 1) + if (n < 0) { int save_errno = errno; print_line (client, NULL); /* flush */ -- cgit From 7d8f27e4224c47864842c790eaff3c65474fbf01 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Nov 2004 10:43:53 +0000 Subject: Add --ignore-http-dp and --ignore-ldap-dp. --- tools/ChangeLog | 5 +++++ tools/gpgconf-comp.c | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 9158d7ca5..201a496a8 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-11-24 Werner Koch + + * gpgconf-comp.c : Add --ignore-http-dp and + --ignore-ldap-dp. + 2004-11-23 Werner Koch * gpgconf-comp.c : Add the proxy options. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index ec606ea2b..d2eac7dd9 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -740,6 +740,9 @@ static gc_option_t gc_options_dirmngr[] = { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "inhibit the use of HTTP", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore HTTP CRL distribution points", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|redirect all HTTP requests to URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, @@ -750,6 +753,9 @@ static gc_option_t gc_options_dirmngr[] = { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "inhibit the use of LDAP", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore LDAP CRL distribution points", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "|HOST|use HOST for LDAP queries", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, -- cgit From 0b135bc6d481dc5dab549d1a357f725add7b9756 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 24 Nov 2004 14:50:20 +0000 Subject: Add dirmngr options to gpgconf and updated the DE translation --- doc/debugging.texi | 2 +- po/de.po | 216 ++++++++++++++++++++++++++------------------------- tools/ChangeLog | 4 +- tools/gpgconf-comp.c | 3 + 4 files changed, 118 insertions(+), 107 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/doc/debugging.texi b/doc/debugging.texi index b9ae06e2b..49ab70bde 100644 --- a/doc/debugging.texi +++ b/doc/debugging.texi @@ -101,7 +101,7 @@ i.e. @samp{GPG_TTY=tty} is plainly wrong; what you want is this environment variable gets exported, that is you should follow up the setting with an @samp{export GPG_TTY} (assuming a Bourne style shell). Even for GUI based Pinentries; you should have set -@code{GPG_TTY}. See the section on installing the @program{gpg-agent} +@code{GPG_TTY}. See the section on installing the @command{gpg-agent} on how to do it. diff --git a/po/de.po b/po/de.po index 16d945418..1c85954d8 100644 --- a/po/de.po +++ b/po/de.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: gnupg2 1.9.10\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-10-22 15:02+0200\n" -"PO-Revision-Date: 2004-10-22 15:02+0200\n" +"POT-Creation-Date: 2004-11-24 15:41+0100\n" +"PO-Revision-Date: 2004-11-24 15:43+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -34,12 +34,12 @@ msgstr "Im Server Modus ausf msgid "run in daemon mode (background)" msgstr "Im Daemon Modus ausführen" -#: agent/gpg-agent.c:101 kbx/kbxutil.c:81 scd/scdaemon.c:97 sm/gpgsm.c:315 +#: agent/gpg-agent.c:101 kbx/kbxutil.c:81 scd/scdaemon.c:97 sm/gpgsm.c:317 #: tools/gpgconf.c:62 msgid "verbose" msgstr "ausführlich" -#: agent/gpg-agent.c:102 kbx/kbxutil.c:82 scd/scdaemon.c:98 sm/gpgsm.c:316 +#: agent/gpg-agent.c:102 kbx/kbxutil.c:82 scd/scdaemon.c:98 sm/gpgsm.c:318 msgid "be somewhat more quiet" msgstr "Etwas weniger Ausgaben erzeugen" @@ -63,7 +63,7 @@ msgstr "Im Vordergrund laufen lassen" msgid "do not grab keyboard and mouse" msgstr "Tastatur und Maus nicht \"grabben\"" -#: agent/gpg-agent.c:112 scd/scdaemon.c:108 sm/gpgsm.c:318 +#: agent/gpg-agent.c:112 scd/scdaemon.c:108 sm/gpgsm.c:320 msgid "use a log file for the server" msgstr "Logausgaben in eine Datei umlenken" @@ -100,12 +100,12 @@ msgid "allow clients to mark keys as \"trusted\"" msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: sm/gpgsm.c:487 tools/gpgconf.c:85 msgid "Please report bugs to <" msgstr "Fehlerberichte bitte an <" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: sm/gpgsm.c:487 tools/gpgconf.c:85 msgid ">.\n" msgstr ">.\n" @@ -121,30 +121,30 @@ msgstr "" "Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n" "Verwaltung von geheimen Schlüssel für GnuPG\n" -#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:603 +#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:605 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "ungültige Debugebene `%s' angegeben\n" #: agent/gpg-agent.c:448 agent/protect-tool.c:1050 kbx/kbxutil.c:431 -#: scd/scdaemon.c:357 sm/gpgsm.c:726 +#: scd/scdaemon.c:357 sm/gpgsm.c:728 #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" "Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n" -#: agent/gpg-agent.c:521 scd/scdaemon.c:437 sm/gpgsm.c:824 +#: agent/gpg-agent.c:521 scd/scdaemon.c:437 sm/gpgsm.c:826 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n" #: agent/gpg-agent.c:526 agent/gpg-agent.c:1000 scd/scdaemon.c:442 -#: sm/gpgsm.c:828 +#: sm/gpgsm.c:830 #, c-format msgid "option file `%s': %s\n" msgstr "Konfigurationsdatei `%s': %s\n" -#: agent/gpg-agent.c:534 scd/scdaemon.c:450 sm/gpgsm.c:835 +#: agent/gpg-agent.c:534 scd/scdaemon.c:450 sm/gpgsm.c:837 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden aus `%s' gelesen\n" @@ -327,12 +327,12 @@ msgstr "Vom Benutzer abgebrochen\n" msgid "problem with the agent\n" msgstr "Problem mit dem Agenten\n" -#: jnlib/logging.c:621 +#: jnlib/logging.c:625 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n" -#: kbx/kbxutil.c:68 sm/gpgsm.c:226 tools/gpgconf.c:53 +#: kbx/kbxutil.c:68 sm/gpgsm.c:227 tools/gpgconf.c:53 msgid "" "@Commands:\n" " " @@ -340,7 +340,7 @@ msgstr "" "@Kommandos:\n" " " -#: kbx/kbxutil.c:76 sm/gpgsm.c:261 tools/gpgconf.c:59 +#: kbx/kbxutil.c:76 sm/gpgsm.c:262 tools/gpgconf.c:59 msgid "" "@\n" "Options:\n" @@ -350,7 +350,7 @@ msgstr "" "Optionen:\n" " " -#: kbx/kbxutil.c:83 sm/gpgsm.c:323 tools/gpgconf.c:64 +#: kbx/kbxutil.c:83 sm/gpgsm.c:325 tools/gpgconf.c:64 msgid "do not make any changes" msgstr "Keine Änderungen durchführen" @@ -382,7 +382,7 @@ msgstr "" "Syntax: kbxutil [Optionen] [Dateien]\n" "Anlistem exportieren und Importieren von KeyBox Dateien\n" -#: scd/scdaemon.c:101 sm/gpgsm.c:335 +#: scd/scdaemon.c:101 sm/gpgsm.c:337 msgid "read options from file" msgstr "Konfigurationsoptionen aus Datei lesen" @@ -529,20 +529,20 @@ msgstr "Kein aktiver gpg-agent - es wird einer gestarted\n" msgid "can't connect to the agent - trying fall back\n" msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n" -#: sm/call-dirmngr.c:164 +#: sm/call-dirmngr.c:173 msgid "no running dirmngr - starting one\n" msgstr "Kein aktiver Dirmngr - es wird einer gestartet\n" -#: sm/call-dirmngr.c:202 +#: sm/call-dirmngr.c:213 msgid "malformed DIRMNGR_INFO environment variable\n" msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n" -#: sm/call-dirmngr.c:214 +#: sm/call-dirmngr.c:225 #, c-format msgid "dirmngr protocol version %d is not supported\n" msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n" -#: sm/call-dirmngr.c:225 +#: sm/call-dirmngr.c:239 msgid "can't connect to the dirmngr - trying fall back\n" msgstr "" "Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird " @@ -788,239 +788,243 @@ msgstr "Schwacher Schl msgid "no valid recipients given\n" msgstr "Keine gültigen Empfänger angegeben\n" -#: sm/gpgsm.c:228 +#: sm/gpgsm.c:229 msgid "|[FILE]|make a signature" msgstr "|[DATEI]|Erzeuge eine Signatur" -#: sm/gpgsm.c:229 +#: sm/gpgsm.c:230 msgid "|[FILE]|make a clear text signature" msgstr "|[DATEI]|Erzeuge eine Klartextsignatur" -#: sm/gpgsm.c:230 +#: sm/gpgsm.c:231 msgid "make a detached signature" msgstr "Erzeuge eine abgetrennte Signatur" -#: sm/gpgsm.c:231 +#: sm/gpgsm.c:232 msgid "encrypt data" msgstr "Verschlüssele die Daten" -#: sm/gpgsm.c:232 +#: sm/gpgsm.c:233 msgid "encryption only with symmetric cipher" msgstr "Verschlüsselung nur mit symmetrischem Algrithmus" -#: sm/gpgsm.c:233 +#: sm/gpgsm.c:234 msgid "decrypt data (default)" msgstr "Enschlüssele die Daten" -#: sm/gpgsm.c:234 +#: sm/gpgsm.c:235 msgid "verify a signature" msgstr "Überprüfen einer Signatur" -#: sm/gpgsm.c:236 +#: sm/gpgsm.c:237 msgid "list keys" msgstr "Schlüssel anzeigen" -#: sm/gpgsm.c:237 +#: sm/gpgsm.c:238 msgid "list external keys" msgstr "Externe Schlüssel anzeigen" -#: sm/gpgsm.c:238 +#: sm/gpgsm.c:239 msgid "list secret keys" msgstr "Geheime Schlüssel anzeigen" -#: sm/gpgsm.c:239 +#: sm/gpgsm.c:240 msgid "list certificate chain" msgstr "Schlüssel mit Zertifikatekette anzeigen" -#: sm/gpgsm.c:241 +#: sm/gpgsm.c:242 msgid "list keys and fingerprints" msgstr "Schlüssel und Fingerprint anzeigen" -#: sm/gpgsm.c:242 +#: sm/gpgsm.c:243 msgid "generate a new key pair" msgstr "Neues Schlüsselpaar erzeugen" -#: sm/gpgsm.c:243 +#: sm/gpgsm.c:244 msgid "remove key from the public keyring" msgstr "Schlüssel aus dem öffentlichen Schlüsselbund löschen" -#: sm/gpgsm.c:244 +#: sm/gpgsm.c:245 msgid "export keys to a key server" msgstr "Schlüssen an eine Schlüsselserver exportieren" -#: sm/gpgsm.c:245 +#: sm/gpgsm.c:246 msgid "import keys from a key server" msgstr "Schlüssel von einem Schlüsselserver importieren" -#: sm/gpgsm.c:246 +#: sm/gpgsm.c:247 msgid "import certificates" msgstr "Zertifikate importieren" -#: sm/gpgsm.c:247 +#: sm/gpgsm.c:248 msgid "export certificates" msgstr "Zertifikate exportieren" -#: sm/gpgsm.c:248 +#: sm/gpgsm.c:249 msgid "register a smartcard" msgstr "Smartcard registrieren" -#: sm/gpgsm.c:249 +#: sm/gpgsm.c:250 msgid "run in server mode" msgstr "Im Server Modus ausführen" -#: sm/gpgsm.c:250 +#: sm/gpgsm.c:251 msgid "pass a command to the dirmngr" msgstr "Das Kommand an den Dirmngr durchreichen" -#: sm/gpgsm.c:252 +#: sm/gpgsm.c:253 msgid "invoke gpg-protect-tool" msgstr "Rufe das gpg-protect-tool auf" -#: sm/gpgsm.c:253 +#: sm/gpgsm.c:254 msgid "change a passphrase" msgstr "Das Mantra (Passphrase) ändern" -#: sm/gpgsm.c:263 +#: sm/gpgsm.c:264 msgid "create ascii armored output" msgstr "Ausgabe mit ASCII Hülle wird erzeugt" -#: sm/gpgsm.c:265 +#: sm/gpgsm.c:266 msgid "create base-64 encoded output" msgstr "Ausgabe im Basis-64 format erzeugen" -#: sm/gpgsm.c:267 +#: sm/gpgsm.c:268 msgid "assume input is in PEM format" msgstr "Eingabedaten sind im PEM Format" -#: sm/gpgsm.c:269 +#: sm/gpgsm.c:270 msgid "assume input is in base-64 format" msgstr "Eingabedaten sind im Basis-64 Format" -#: sm/gpgsm.c:271 +#: sm/gpgsm.c:272 msgid "assume input is in binary format" msgstr "Eingabedaten sind im Binärformat" -#: sm/gpgsm.c:273 +#: sm/gpgsm.c:274 msgid "|NAME|encrypt for NAME" msgstr "|NAME|Verschlüsseln für NAME" -#: sm/gpgsm.c:276 +#: sm/gpgsm.c:277 +msgid "use system's dirmngr if available" +msgstr "Benutze den System Dirmngr when verfügbar" + +#: sm/gpgsm.c:278 msgid "never consult a CRL" msgstr "Niemals eine CRL konsultieren" -#: sm/gpgsm.c:281 +#: sm/gpgsm.c:283 msgid "check validity using OCSP" msgstr "Die Gültigkeit mittels OCSP prüfen" -#: sm/gpgsm.c:284 +#: sm/gpgsm.c:286 msgid "|N|number of certificates to include" msgstr "|N|Sende N Zertifikate mit" -#: sm/gpgsm.c:287 +#: sm/gpgsm.c:289 msgid "|FILE|take policy information from FILE" msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen" -#: sm/gpgsm.c:290 +#: sm/gpgsm.c:292 msgid "do not check certificate policies" msgstr "Zertikikatrichtlinien nicht überprüfen" -#: sm/gpgsm.c:294 +#: sm/gpgsm.c:296 msgid "fetch missing issuer certificates" msgstr "Fehlende Zertifikate automatisch holen" -#: sm/gpgsm.c:298 +#: sm/gpgsm.c:300 msgid "|NAME|use NAME as default recipient" msgstr "|NAME|Benutze NAME als voreingestellten Empfänger" -#: sm/gpgsm.c:300 +#: sm/gpgsm.c:302 msgid "use the default key as default recipient" msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger" -#: sm/gpgsm.c:306 +#: sm/gpgsm.c:308 msgid "use this user-id to sign or decrypt" msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln" -#: sm/gpgsm.c:309 +#: sm/gpgsm.c:311 msgid "|N|set compress level N (0 disables)" msgstr "|N|Benutze Komprimierungsstufe N" -#: sm/gpgsm.c:311 +#: sm/gpgsm.c:313 msgid "use canonical text mode" msgstr "Kanonischen Textmodus benutzen" -#: sm/gpgsm.c:314 tools/gpgconf.c:61 +#: sm/gpgsm.c:316 tools/gpgconf.c:61 msgid "use as output file" msgstr "als Ausgabedatei benutzen" -#: sm/gpgsm.c:317 +#: sm/gpgsm.c:319 msgid "don't use the terminal at all" msgstr "Das Terminal überhaupt nicht benutzen" -#: sm/gpgsm.c:320 +#: sm/gpgsm.c:322 msgid "force v3 signatures" msgstr "Version 3 Signaturen erzwingen" -#: sm/gpgsm.c:321 +#: sm/gpgsm.c:323 msgid "always use a MDC for encryption" msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen" -#: sm/gpgsm.c:326 +#: sm/gpgsm.c:328 msgid "batch mode: never ask" msgstr "Stapelverarbeitungs Modus: Nie nachfragen" -#: sm/gpgsm.c:327 +#: sm/gpgsm.c:329 msgid "assume yes on most questions" msgstr "\"Ja\" auf die meisten Anfragen annehmen" -#: sm/gpgsm.c:328 +#: sm/gpgsm.c:330 msgid "assume no on most questions" msgstr "\"Nein\" auf die meisten Anfragen annehmen" -#: sm/gpgsm.c:330 +#: sm/gpgsm.c:332 msgid "add this keyring to the list of keyrings" msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen" -#: sm/gpgsm.c:331 +#: sm/gpgsm.c:333 msgid "add this secret keyring to the list" msgstr "Diese geheimen Keyring in die Liste aufnehmen" -#: sm/gpgsm.c:332 +#: sm/gpgsm.c:334 msgid "|NAME|use NAME as default secret key" msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel" -#: sm/gpgsm.c:333 +#: sm/gpgsm.c:335 msgid "|HOST|use this keyserver to lookup keys" msgstr "|HOST|Benutze HOST als Schlüsselserver" -#: sm/gpgsm.c:334 +#: sm/gpgsm.c:336 msgid "|NAME|set terminal charset to NAME" msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen" -#: sm/gpgsm.c:338 +#: sm/gpgsm.c:340 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|NAME|Die Debugstufe auf NAME setzen" -#: sm/gpgsm.c:345 +#: sm/gpgsm.c:347 msgid "|FD|write status info to this FD" msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben" -#: sm/gpgsm.c:352 +#: sm/gpgsm.c:354 msgid "|FILE|load extension module FILE" msgstr "|DATEI|Das Erweiterungsmodul DATEI laden" -#: sm/gpgsm.c:358 +#: sm/gpgsm.c:360 msgid "|NAME|use cipher algorithm NAME" msgstr "|NAME|Den Verschlüsselungsalgrithmus NAME benutzen" -#: sm/gpgsm.c:360 +#: sm/gpgsm.c:362 msgid "|NAME|use message digest algorithm NAME" msgstr "|NAME|Den Hashalgorithmus NAME benutzen" -#: sm/gpgsm.c:362 +#: sm/gpgsm.c:364 msgid "|N|use compress algorithm N" msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen" -#: sm/gpgsm.c:370 +#: sm/gpgsm.c:372 msgid "" "@\n" "(See the man page for a complete listing of all commands and options)\n" @@ -1028,7 +1032,7 @@ msgstr "" "@\n" "(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n" -#: sm/gpgsm.c:373 +#: sm/gpgsm.c:375 msgid "" "@\n" "Examples:\n" @@ -1048,11 +1052,11 @@ msgstr "" " --list-keys [Namen] Schlüssel anzeigenn\n" " --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\\n\n" -#: sm/gpgsm.c:488 +#: sm/gpgsm.c:490 msgid "Usage: gpgsm [options] [files] (-h for help)" msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)" -#: sm/gpgsm.c:491 +#: sm/gpgsm.c:493 msgid "" "Syntax: gpgsm [options] [files]\n" "sign, check, encrypt or decrypt using the S/MIME protocol\n" @@ -1061,7 +1065,7 @@ msgstr "" "Gebrauch: gpgsm [Optionen] [Dateien]\n" "Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n" -#: sm/gpgsm.c:498 +#: sm/gpgsm.c:500 msgid "" "\n" "Supported algorithms:\n" @@ -1069,50 +1073,50 @@ msgstr "" "\n" "Unterstützte Algorithmen:\n" -#: sm/gpgsm.c:574 +#: sm/gpgsm.c:576 msgid "usage: gpgsm [options] " msgstr "Gebrauch: gpgsm [Optionen] " -#: sm/gpgsm.c:640 +#: sm/gpgsm.c:642 msgid "conflicting commands\n" msgstr "Widersprechende Kommandos\n" -#: sm/gpgsm.c:656 +#: sm/gpgsm.c:658 #, c-format msgid "can't encrypt to `%s': %s\n" msgstr "Verschlüsseln für `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:731 +#: sm/gpgsm.c:733 #, c-format msgid "libksba is too old (need %s, have %s)\n" msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" -#: sm/gpgsm.c:1178 +#: sm/gpgsm.c:1181 msgid "WARNING: program may create a core file!\n" msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" -#: sm/gpgsm.c:1190 +#: sm/gpgsm.c:1193 msgid "WARNING: running with faked system time: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " -#: sm/gpgsm.c:1216 +#: sm/gpgsm.c:1219 msgid "selected cipher algorithm is invalid\n" msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" -#: sm/gpgsm.c:1224 +#: sm/gpgsm.c:1227 msgid "selected digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: sm/gpgsm.c:1254 +#: sm/gpgsm.c:1257 #, c-format msgid "can't sign using `%s': %s\n" msgstr "Signieren mit `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:1418 +#: sm/gpgsm.c:1423 msgid "this command has not yet been implemented\n" msgstr "Diee Kommando wurde noch nicht implementiert\n" -#: sm/gpgsm.c:1641 sm/gpgsm.c:1674 +#: sm/gpgsm.c:1646 sm/gpgsm.c:1679 #, c-format msgid "can't open `%s': %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" @@ -1334,26 +1338,26 @@ msgid "Component not found" msgstr "Komponente nicht gefunden" #: tools/gpgconf-comp.c:435 tools/gpgconf-comp.c:496 tools/gpgconf-comp.c:561 -#: tools/gpgconf-comp.c:614 tools/gpgconf-comp.c:677 +#: tools/gpgconf-comp.c:614 tools/gpgconf-comp.c:680 msgid "Options controlling the diagnostic output" msgstr "Optionen zur Einstellung Diagnoseausgaben" #: tools/gpgconf-comp.c:448 tools/gpgconf-comp.c:509 tools/gpgconf-comp.c:574 -#: tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:700 +#: tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:703 msgid "Options controlling the configuration" msgstr "Optionen zur Einstellung der Konfiguration" #: tools/gpgconf-comp.c:455 tools/gpgconf-comp.c:532 tools/gpgconf-comp.c:581 -#: tools/gpgconf-comp.c:634 tools/gpgconf-comp.c:707 +#: tools/gpgconf-comp.c:637 tools/gpgconf-comp.c:710 msgid "Options useful for debugging" msgstr "Nützliche Optionen zum Debuggen" #: tools/gpgconf-comp.c:460 tools/gpgconf-comp.c:537 tools/gpgconf-comp.c:586 -#: tools/gpgconf-comp.c:639 tools/gpgconf-comp.c:715 +#: tools/gpgconf-comp.c:642 tools/gpgconf-comp.c:718 msgid "|FILE|write server mode logs to FILE" msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI" -#: tools/gpgconf-comp.c:468 tools/gpgconf-comp.c:542 tools/gpgconf-comp.c:647 +#: tools/gpgconf-comp.c:468 tools/gpgconf-comp.c:542 tools/gpgconf-comp.c:650 msgid "Options controlling the security" msgstr "Optionen zur Einstellung der Sicherheit" @@ -1361,19 +1365,23 @@ msgstr "Optionen zur Einstellung der Sicherheit" msgid "Configuration for Keyservers" msgstr "Konfiguration der Schlüsselserver" -#: tools/gpgconf-comp.c:690 +#: tools/gpgconf-comp.c:693 msgid "Options controlling the format of the output" msgstr "Optionen zum Einstellen der Ausgabeformate" -#: tools/gpgconf-comp.c:726 +#: tools/gpgconf-comp.c:729 msgid "Options controlling the interactivity and enforcement" msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung" -#: tools/gpgconf-comp.c:736 +#: tools/gpgconf-comp.c:739 +msgid "Configuration for HTTP servers" +msgstr "Konfiguration für HTTP Server" + +#: tools/gpgconf-comp.c:752 msgid "Configuration of LDAP servers to use" msgstr "Konfiguration der zu nutzenden LDAP-Server" -#: tools/gpgconf-comp.c:761 +#: tools/gpgconf-comp.c:789 msgid "Configuration for OCSP" msgstr "Konfiguration zu OCSP" diff --git a/tools/ChangeLog b/tools/ChangeLog index 201a496a8..ac8d54a47 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,7 +1,7 @@ 2004-11-24 Werner Koch - * gpgconf-comp.c : Add --ignore-http-dp and - --ignore-ldap-dp. + * gpgconf-comp.c : Add --ignore-http-dp, --ignore-ldap-dp + and --ignore-ocsp-service-url. 2004-11-23 Werner Koch diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index d2eac7dd9..8873cdf13 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -790,6 +790,9 @@ static gc_option_t gc_options_dirmngr[] = { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "allow sending OCSP requests", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-ocsp-servic-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore certificate contained OCSP service URLs", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|use OCSP responder at URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, -- cgit From 801ab885224b7d85aa11cb9f239f33cb420d3159 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 13 Dec 2004 15:49:56 +0000 Subject: VArious hacks to make it at least build under W32. * stringhelp.c (w32_strerror) [W32]: New. * w32-pth.c, w32-pth.h: Added real code written by Timo Schulz. Not finished, though. * gpgconf-comp.c : Fixed typo. --- agent/call-scd.c | 6 ++++++ agent/findkey.c | 6 +++++- agent/gpg-agent.c | 48 +++++++++++++++++++++++++++++++++++++++--------- common/simple-pwquery.c | 2 ++ jnlib/ChangeLog | 2 ++ jnlib/stringhelp.c | 46 +++++++++++++++++++++++++++++++++++++--------- jnlib/stringhelp.h | 5 +++++ jnlib/w32-afunix.h | 1 + jnlib/w32-pth.h | 8 +++++++- sm/call-agent.c | 2 +- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 2 +- 12 files changed, 110 insertions(+), 22 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/agent/call-scd.c b/agent/call-scd.c index 2427d8ca3..575986dc9 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -34,7 +34,9 @@ #include #include #include +#ifndef HAVE_W32_SYSTEM #include +#endif #ifdef USE_GNU_PTH # include #endif @@ -213,6 +215,7 @@ start_scd (ctrl_t ctrl) /* We better do a sanity check now to see whether it has accidently died. */ +#ifndef HAVE_W32_SYSTEM /* fixme */ pid = assuan_get_pid (scd_ctx); if (pid != (pid_t)(-1) && pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) @@ -221,6 +224,7 @@ start_scd (ctrl_t ctrl) scd_ctx = NULL; } else +#endif return 0; } @@ -275,10 +279,12 @@ start_scd (ctrl_t ctrl) simply as a pipe server. */ if (ctrl->connection_fd != -1) { +#ifndef HAVE_W32_SYSTEM char buf[100]; sprintf (buf, "OPTION event-signal=%d", SIGUSR2); assuan_transact (scd_ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); +#endif } return 0; diff --git a/agent/findkey.c b/agent/findkey.c index 9866b54b9..b54528295 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -76,7 +76,11 @@ agent_write_private_key (const unsigned char *grip, The mode parameter to open is what fopen uses. It will be combined with the process' umask automatically. */ fd = open (fname, O_CREAT | O_EXCL | O_RDWR, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + S_IRUSR | S_IWUSR +#ifndef HAVE_W32_SYSTEM + | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH +#endif + ); if (fd < 0) fp = 0; else diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 92af49b7a..6801839aa 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -29,9 +29,11 @@ #include #include #include -#include #include +#ifndef HAVE_W32_SYSTEM +#include #include +#endif #include #include #ifdef USE_GNU_PTH @@ -40,11 +42,13 @@ #define JNLIB_NEED_LOG_LOGV #include "agent.h" -#include /* malloc hooks */ +#include /* Malloc hooks */ #include "i18n.h" #include "sysutils.h" - +#ifdef HAVE_W32_SYSTEM +#include "../jnlib/w32-afunix.h" +#endif enum cmd_and_opt_values { aNull = 0, @@ -175,7 +179,9 @@ static void create_directories (void); static void handle_connections (int listen_fd); /* Pth wrapper function definitions. */ +#ifndef HAVE_W32_SYSTEM GCRY_THREAD_OPTION_PTH_IMPL; +#endif #endif /*USE_GNU_PTH*/ static void check_for_running_agent (void); @@ -432,14 +438,14 @@ main (int argc, char **argv ) /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ -#ifdef USE_GNU_PTH +#if defined(USE_GNU_PTH) && !defined(HAVE_W32_SYSTEM) err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); if (err) { log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } -#endif /*USE_GNU_PTH*/ +#endif /*USE_GNU_PTH && !HAVE_W32_SYSTEM*/ /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library. */ @@ -707,10 +713,12 @@ main (int argc, char **argv ) } /* Make sure that we have a default ttyname. */ +#ifndef HAVE_W32_SYSTEM if (!default_ttyname && ttyname (1)) default_ttyname = xstrdup (ttyname (1)); if (!default_ttytype && getenv ("TERM")) default_ttytype = xstrdup (getenv ("TERM")); +#endif if (pipe_server) { /* this is the simple pipe based server */ @@ -720,6 +728,7 @@ main (int argc, char **argv ) ; /* NOTREACHED */ else { /* Regular server mode */ +#ifndef HAVE_W32_SYSTEM int fd; pid_t pid; int len; @@ -888,18 +897,21 @@ main (int argc, char **argv ) #ifdef USE_GNU_PTH if (!disable_pth) { +#ifndef HAVE_W32_SYSTEM /* FIXME */ struct sigaction sa; sa.sa_handler = SIG_IGN; sigemptyset (&sa.sa_mask); sa.sa_flags = 0; sigaction (SIGPIPE, &sa, NULL); +#endif handle_connections (fd); } else #endif /*!USE_GNU_PTH*/ /* setup signals */ { +#ifndef HAVE_W32_SYSTEM /* FIXME */ struct sigaction oact, nact; nact.sa_handler = cleanup_sh; @@ -915,10 +927,11 @@ main (int argc, char **argv ) nact.sa_handler = SIG_IGN; sigaction (SIGPIPE, &nact, NULL); sigaction (SIGINT, &nact, NULL); - +#endif start_command_handler (fd, -1); } close (fd); +#endif } return 0; @@ -1029,9 +1042,15 @@ create_private_keys_directory (const char *home) fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL); if (stat (fname, &statbuf) && errno == ENOENT) { +#ifdef HAVE_W32_SYSTEM /*FIXME: Setup proper permissions. */ + if (!CreateDirectory (fname, NULL)) + log_error (_("can't create directory `%s': %s\n"), + fname, w32_strerror (-1) ); +#else if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR )) log_error (_("can't create directory `%s': %s\n"), - fname, strerror(errno) ); + fname, strerror (errno) ); +#endif else if (!opt.quiet) log_info (_("directory `%s' created\n"), fname); } @@ -1063,9 +1082,15 @@ create_directories (void) || (*defhome != '~' && !strcmp (home, defhome) ) ) { +#ifdef HAVE_W32_SYSTEM + if (!CreateDirectory (home, NULL)) + log_error (_("can't create directory `%s': %s\n"), + home, w32_strerror (-1) ); +#else if (mkdir (home, S_IRUSR|S_IWUSR|S_IXUSR )) log_error (_("can't create directory `%s': %s\n"), - home, strerror(errno) ); + home, strerror (errno) ); +#endif else { if (!opt.quiet) @@ -1096,6 +1121,7 @@ handle_signal (int signo) { switch (signo) { +#ifndef HAVE_W32_SYSTEM case SIGHUP: log_info ("SIGHUP received - " "re-reading configuration and flushing cache\n"); @@ -1134,7 +1160,7 @@ handle_signal (int signo) cleanup (); agent_exit (0); break; - +#endif default: log_info ("signal %d received - no action defined\n", signo); } @@ -1178,6 +1204,7 @@ handle_connections (int listen_fd) pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); pth_attr_set (tattr, PTH_ATTR_NAME, "gpg-agent"); +#ifndef HAVE_W32_SYSTEM /* fixme */ sigemptyset (&sigs ); sigaddset (&sigs, SIGHUP); sigaddset (&sigs, SIGUSR1); @@ -1185,6 +1212,9 @@ handle_connections (int listen_fd) sigaddset (&sigs, SIGINT); sigaddset (&sigs, SIGTERM); ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +#else + ev = NULL; +#endif for (;;) { diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index fab6306fa..1e8eae63b 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -182,8 +182,10 @@ agent_send_all_options (int fd) } dft_ttyname = getenv ("GPG_TTY"); +#ifndef HAVE_W32_SYSTEM if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) dft_ttyname = ttyname (0); +#endif if (dft_ttyname && *dft_ttyname) { if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index b33b7842f..f27ef87b6 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,5 +1,7 @@ 2004-12-13 Werner Koch + * stringhelp.c (w32_strerror) [W32]: New. + * w32-pth.c, w32-pth.h: Added real code written by Timo Schulz. Not finished, though. diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index 568152fdd..5a3b41528 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -1,5 +1,6 @@ /* stringhelp.c - standard string helper functions - * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -23,14 +24,17 @@ #include #include #include +#ifdef HAVE_W32_SYSTEM +#include +#endif #include "libjnlib-config.h" #include "utf8conv.h" #include "stringhelp.h" -/**************** - * look for the substring SUB in buffer and return a pointer to that +/* + * Look for the substring SUB in buffer and return a pointer to that * substring in BUF or NULL if not found. * Comparison is case-insensitive. */ @@ -72,11 +76,12 @@ ascii_memistr( const char *buf, size_t buflen, const char *sub ) return NULL ; } -/**************** - * Wie strncpy(), aber es werden maximal n-1 zeichen kopiert und ein - * '\0' angehängt. Ist n = 0, so geschieht nichts, ist Destination - * gleich NULL, so wird via jnlib_xmalloc Speicher besorgt, ist dann nicht - * genügend Speicher vorhanden, so bricht die funktion ab. +/* This function is similar to strncpy(). However it won't copy more + than N - 1 characters and makes sure that a '\0' is appended. With + N given as 0, nothing will happen. With DEST given as NULL, memory + will be allocated using jnlib_xmalloc (i.e. if it runs out of core + the function terminates). Returns DES or a pointer to the + allocated memory. */ char * mem2str( char *dest , const void *src , size_t n ) @@ -452,8 +457,29 @@ sanitize_buffer (const unsigned char *p, size_t n, int delim) return buffer; } + /**************************************************** - ******** locale insensitive ctype functions ******** + ********** W32 specific functions **************** + ****************************************************/ + +#ifdef HAVE_W32_SYSTEM +const char * +w32_strerror (int ec) +{ + static char strerr[256]; + + if (ec == -1) + ec = (int)GetLastError (); + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, DIM (strerr)-1, NULL); + return strerr; +} +#endif /*HAVE_W32_SYSTEM*/ + + +/**************************************************** + ******** Locale insensitive ctype functions ******** ****************************************************/ /* FIXME: replace them by a table lookup and macros */ int @@ -626,3 +652,5 @@ memicmp( const char *a, const char *b, size_t n ) return 0; } #endif + + diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index fe5786e59..412da3a0e 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -49,6 +49,11 @@ size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); char *sanitize_buffer (const unsigned char *p, size_t n, int delim); +#ifdef HAVE_W32_SYSTEM +const char *w32_strerror (int ec); +#endif + + const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); int ascii_isupper (int c); int ascii_islower (int c); diff --git a/jnlib/w32-afunix.h b/jnlib/w32-afunix.h index 1319de5e6..367832299 100644 --- a/jnlib/w32-afunix.h +++ b/jnlib/w32-afunix.h @@ -23,6 +23,7 @@ #include #include +#include #include #define DIRSEP_C '\\' diff --git a/jnlib/w32-pth.h b/jnlib/w32-pth.h index efb17d255..bb010ae99 100644 --- a/jnlib/w32-pth.h +++ b/jnlib/w32-pth.h @@ -53,7 +53,7 @@ enum /* Mutex values. */ #define PTH_MUTEX_INITIALIZED (1<<0) #define PTH_MUTEX_LOCKED (1<<1) -#define PTH_MUTEX_INIT {{NULL, NULL}, PTH_MUTEX_INITIALIZED, NULL, 0} +#define PTH_MUTEX_INIT {PTH_MUTEX_INITIALIZED} #define PTH_KEY_INIT (1<<0) @@ -235,6 +235,12 @@ pth_event_t pth_event (unsigned long spec, ...); +/* Backward compatibility (Pth < 1.5.0). */ +#define pth_event_occurred(ev) \ + ( pth_event_status(ev) == PTH_STATUS_OCCURRED \ + || pth_event_status(ev) == PTH_STATUS_FAILED ) + + /*-- pth_util.c --*/ /* void sigemptyset (struct sigset_s * ss); */ diff --git a/sm/call-agent.c b/sm/call-agent.c index 2e8c75496..3ea1c4565 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -113,7 +113,7 @@ start_agent (ctrl_t ctrl) no_close_list[i++] = fileno (stderr); no_close_list[i] = -1; - /* connect to the agent and perform initial handshaking */ + /* Connect to the agent and perform initial handshaking. */ rc = assuan_pipe_connect (&ctx, opt.agent_program, (char**)argv, no_close_list); } diff --git a/tools/ChangeLog b/tools/ChangeLog index ac8d54a47..cb341ad4f 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2004-12-13 Werner Koch + + * gpgconf-comp.c : Fixed typo. + 2004-11-24 Werner Koch * gpgconf-comp.c : Add --ignore-http-dp, --ignore-ldap-dp diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 8873cdf13..5d78df86d 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -790,7 +790,7 @@ static gc_option_t gc_options_dirmngr[] = { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "allow sending OCSP requests", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, - { "ignore-ocsp-servic-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + { "ignore-ocsp-service-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "ignore certificate contained OCSP service URLs", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, -- cgit From 69967b04125e53811182a01d2700984469117339 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 15 Dec 2004 14:15:54 +0000 Subject: A whole bunch of changes to allow building for W32. --- ChangeLog | 10 ++ Makefile.am | 8 +- acinclude.m4 | 22 ++-- agent/ChangeLog | 13 +++ agent/call-scd.c | 2 +- agent/gpg-agent.c | 16 +-- agent/protect-tool.c | 20 +++- common/ChangeLog | 15 +++ common/asshelp.c | 119 ++++++++++----------- common/exechelp.c | 276 +++++++++++++++++++++++++++++++++++++++++++++--- common/iobuf.c | 4 +- common/simple-pwquery.c | 6 +- common/sysutils.h | 7 ++ common/ttyname.c | 32 ++++++ common/util.h | 4 +- common/w32reg.c | 5 +- configure.ac | 30 +----- g10/call-agent.c | 2 + jnlib/ChangeLog | 4 + jnlib/logging.c | 7 +- m4/ksba.m4 | 2 +- scd/ChangeLog | 11 ++ scd/Makefile.am | 14 ++- scd/apdu.c | 7 +- scd/command.c | 5 + scd/scdaemon.c | 40 ++++++- sm/ChangeLog | 10 ++ sm/Makefile.am | 8 +- sm/gpgsm.c | 15 ++- tools/ChangeLog | 10 ++ tools/Makefile.am | 5 +- tools/gpgconf-comp.c | 18 ++++ 32 files changed, 589 insertions(+), 158 deletions(-) create mode 100644 common/ttyname.c (limited to 'tools/gpgconf-comp.c') diff --git a/ChangeLog b/ChangeLog index d290c9481..95cf87d25 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2004-12-15 Werner Koch + + * Makefile.am (SUBDIRS) [W32]: Do not build in tests/. + + * acinclude.m4: Add proper macro name quoting for use with + automake 1.9. + + * configure.ac: Add replacement check for ttyname. + Removed support for a included zlib. + 2004-12-06 Werner Koch * configure.ac (have_w32_system): New. Disable Pth checks for W32. diff --git a/Makefile.am b/Makefile.am index 08d025abf..e6cbde893 100644 --- a/Makefile.am +++ b/Makefile.am @@ -53,8 +53,14 @@ else scd = endif +if HAVE_W32_SYSTEM +tests = +else +tests = tests +endif + SUBDIRS = m4 intl jnlib common ${kbx} \ - ${gpg} ${sm} ${agent} ${scd} tools po doc tests + ${gpg} ${sm} ${agent} ${scd} tools po doc ${tests} dist-hook: @set -e; \ diff --git a/acinclude.m4 b/acinclude.m4 index f6bbae78e..5f742b279 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -20,7 +20,7 @@ dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME) dnl Check whether a typedef exists and create a #define $2 if it exists dnl -AC_DEFUN(GNUPG_CHECK_TYPEDEF, +AC_DEFUN([GNUPG_CHECK_TYPEDEF], [ AC_MSG_CHECKING(for $1 typedef) AC_CACHE_VAL(gnupg_cv_typedef_$1, [AC_TRY_COMPILE([#define _GNU_SOURCE 1 @@ -38,7 +38,7 @@ AC_DEFUN(GNUPG_CHECK_TYPEDEF, dnl GNUPG_CHECK_GNUMAKE dnl -AC_DEFUN(GNUPG_CHECK_GNUMAKE, +AC_DEFUN([GNUPG_CHECK_GNUMAKE], [ if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then : @@ -55,7 +55,7 @@ AC_DEFUN(GNUPG_CHECK_GNUMAKE, dnl GNUPG_CHECK_FAQPROG dnl -AC_DEFUN(GNUPG_CHECK_FAQPROG, +AC_DEFUN([GNUPG_CHECK_FAQPROG], [ AC_MSG_CHECKING(for faqprog.pl) if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then working_faqprog=yes @@ -82,7 +82,7 @@ dnl fi dnl GNUPG_CHECK_DOCBOOK_TO_TEXI dnl -AC_DEFUN(GNUPG_CHECK_DOCBOOK_TO_TEXI, +AC_DEFUN([GNUPG_CHECK_DOCBOOK_TO_TEXI], [ AC_CHECK_PROG(DOCBOOK_TO_TEXI, docbook2texi, yes, no) AC_MSG_CHECKING(for sgml to texi tools) @@ -101,7 +101,7 @@ AC_DEFUN(GNUPG_CHECK_DOCBOOK_TO_TEXI, dnl GNUPG_CHECK_ENDIAN dnl define either LITTLE_ENDIAN_HOST or BIG_ENDIAN_HOST dnl -define(GNUPG_CHECK_ENDIAN, +AC_DEFUN([GNUPG_CHECK_ENDIAN], [ tmp_assumed_endian=big if test "$cross_compiling" = yes; then @@ -158,7 +158,7 @@ define(GNUPG_CHECK_ENDIAN, # Check for the getsockopt SO_PEERCRED -AC_DEFUN(GNUPG_SYS_SO_PEERCRED, +AC_DEFUN([GNUPG_SYS_SO_PEERCRED], [ AC_MSG_CHECKING(for SO_PEERCRED) AC_CACHE_VAL(gnupg_cv_sys_so_peercred, [AC_TRY_COMPILE([#include ], @@ -183,7 +183,7 @@ AC_DEFUN(GNUPG_SYS_SO_PEERCRED, # either be "yes" or "no" and decided on the default value for # build_NAME and whether --enable-NAME or --disable-NAME is shown with # ./configure --help -AC_DEFUN(GNUPG_BUILD_PROGRAM, +AC_DEFUN([GNUPG_BUILD_PROGRAM], [build_$1=$2 m4_if([$2],[yes],[ AC_ARG_ENABLE([$1], AC_HELP_STRING([--disable-$1], @@ -210,7 +210,7 @@ AC_DEFUN(GNUPG_BUILD_PROGRAM, # If the version is sufficient, HAVE_PTH will be set to yes. # # Taken form the m4 macros which come with Pth -AC_DEFUN(GNUPG_PTH_VERSION_CHECK, +AC_DEFUN([GNUPG_PTH_VERSION_CHECK], [ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'` _req_version="ifelse([$1],,1.2.0,$1)" @@ -253,7 +253,7 @@ AC_DEFUN(GNUPG_PTH_VERSION_CHECK, # mlock is there a macro using memlk() dnl GNUPG_CHECK_MLOCK dnl -define(GNUPG_CHECK_MLOCK, +AC_DEFUN([GNUPG_CHECK_MLOCK], [ AC_CHECK_FUNCS(mlock) if test "$ac_cv_func_mlock" = "no"; then AC_CHECK_HEADERS(sys/mman.h) @@ -343,7 +343,7 @@ define(GNUPG_CHECK_MLOCK, dnl Stolen from gcc dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead dnl of the usual 2. -AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG, +AC_DEFUN([GNUPG_FUNC_MKDIR_TAKES_ONE_ARG], [AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h) AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg, [AC_TRY_COMPILE([ @@ -371,7 +371,7 @@ dnl AM_PATH_OPENSC([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for OpenSC and define OPENSC_CFLAGS and OPENSC_LIBS dnl -AC_DEFUN(AM_PATH_OPENSC, +AC_DEFUN([AM_PATH_OPENSC], [ AC_ARG_WITH(opensc-prefix, AC_HELP_STRING([--with-opensc-prefix=PFX], [prefix where OpenSC is installed (optional)]), diff --git a/agent/ChangeLog b/agent/ChangeLog index e0bf52b45..3669b0e43 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,16 @@ +2004-12-15 Werner Koch + + * gpg-agent.c [W32]: Various hacks to make it work. + + * findkey.c (agent_write_private_key) [W32]: Adjust open call. + + * call-scd.c (start_scd) [W32]: Don't check whether the daemon + didn't died. To hard to do under Windows. + (start_scd) [W32]: Disable sending of the event signal option. + + * protect-tool.c (read_file, export_p12_file) [W32]: Use setmode + to get stdout and stin into binary mode. + 2004-12-05 Moritz Schulte * query.c (start_pinentry): Allow CTRL be NULL. diff --git a/agent/call-scd.c b/agent/call-scd.c index 575986dc9..828040772 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -215,7 +215,7 @@ start_scd (ctrl_t ctrl) /* We better do a sanity check now to see whether it has accidently died. */ -#ifndef HAVE_W32_SYSTEM /* fixme */ +#ifndef HAVE_W32_SYSTEM pid = assuan_get_pid (scd_ctx); if (pid != (pid_t)(-1) && pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 0a483ac48..307d43d36 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -33,7 +33,7 @@ #ifndef HAVE_W32_SYSTEM #include #include -#endif +#endif /*HAVE_W32_SYSTEM*/ #include #include #ifdef USE_GNU_PTH @@ -438,17 +438,18 @@ main (int argc, char **argv ) /* Libgcrypt requires us to register the threading model first. Note that this will also do the pth_init. */ -#if defined(USE_GNU_PTH) && !defined(HAVE_W32_SYSTEM) +#ifdef USE_GNU_PTH +# ifdef HAVE_W32_SYSTEM + pth_init (); +# else /*!HAVE_W32_SYSTEM*/ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); if (err) { log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } -#endif /*USE_GNU_PTH && !HAVE_W32_SYSTEM*/ -#ifdef HAVE_W32_SYSTEM - pth_init (); -#endif +# endif/*!HAVE_W32_SYSTEM*/ +#endif /*USE_GNU_PTH*/ /* Check that the libraries are suitable. Do it here because the option parsing may need services of the library. */ @@ -716,12 +717,11 @@ main (int argc, char **argv ) } /* Make sure that we have a default ttyname. */ -#ifndef HAVE_W32_SYSTEM if (!default_ttyname && ttyname (1)) default_ttyname = xstrdup (ttyname (1)); if (!default_ttytype && getenv ("TERM")) default_ttytype = xstrdup (getenv ("TERM")); -#endif + if (pipe_server) { /* this is the simple pipe based server */ diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 286adde54..ef8a50916 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -35,6 +35,9 @@ #ifdef HAVE_LANGINFO_CODESET #include #endif +#ifdef HAVE_DOSISH_SYSTEM +#include /* for setmode() */ +#endif #define JNLIB_NEED_LOG_LOGV #include "agent.h" @@ -262,6 +265,9 @@ read_file (const char *fname, size_t *r_length) size_t nread, bufsize = 0; fp = stdin; +#ifdef HAVE_DOSISH_SYSTEM + setmode ( fileno(fp) , O_BINARY ); +#endif buf = NULL; buflen = 0; #define NCHUNK 8192 @@ -975,6 +981,9 @@ export_p12_file (const char *fname) if (!key) return; +#ifdef HAVE_DOSISH_SYSTEM + setmode ( fileno (stdout) , O_BINARY ); +#endif fwrite (key, keylen, 1, stdout); xfree (key); } @@ -1056,12 +1065,12 @@ main (int argc, char **argv ) gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); -#ifdef __MINGW32__ +#ifdef HAVE_W32_SYSTEM opt_homedir = read_w32_registry_string ( NULL, "Software\\GNU\\GnuPG", "HomeDir" ); -#else +#else /*!HAVE_W32_SYSTEM*/ opt_homedir = getenv ("GNUPGHOME"); -#endif +#endif /*!HAVE_W32_SYSTEM*/ if (!opt_homedir || !*opt_homedir) opt_homedir = GNUPG_DEFAULT_HOMEDIR; @@ -1213,9 +1222,10 @@ get_passphrase (int promptno) if (!pw) { if (err) - log_error ("error while asking for the passphrase\n"); + log_error (_("error while asking for the passphrase: %s\n"), + gpg_strerror (err)); else - log_info ("cancelled\n"); + log_info (_("cancelled\n")); agent_exit (0); } diff --git a/common/ChangeLog b/common/ChangeLog index afdded6d9..3115ad897 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,18 @@ +2004-12-15 Werner Koch + + * sysutils.h [W32]: Prototypes for registry functions. + * w32reg.c: Include sysutils.h + + * simple-pwquery.c [W32]: Dummy code to allow a build. + + * exechelp.c [W32]: Implemented for W32 . + + * ttyname.c: New. + + * asshelp.c (send_one_option): New. + (send_pinentry_environment): Cleaned up and made sure that empty + values are not send. + 2004-12-07 Werner Koch * asshelp.c (send_pinentry_environment) [W32]: Do not use ttyname. diff --git a/common/asshelp.c b/common/asshelp.c index 751412e6c..243d6b9e7 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -32,8 +32,32 @@ #include "asshelp.h" -/* Send the assuan command pertaining to the pinenry environment. The - OPT_* arguments are optional and may be used to overide the + +static gpg_error_t +send_one_option (assuan_context_t ctx, const char *name, const char *value) +{ + gpg_error_t err; + char *optstr; + + if (!value || !*value) + err = 0; /* Avoid sending empty strings. */ + else if (asprintf (&optstr, "OPTION %s=%s", name, value ) < 0) + err = gpg_error_from_errno (errno); + else + { + assuan_error_t ae; + + ae = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); + err = ae? map_assuan_err (ae) : 0; + free (optstr); + } + + return err; +} + + +/* Send the assuan commands pertaining to the pinenry environment. The + OPT_* arguments are optional and may be used to override the defaults taken from the current locale. */ gpg_error_t send_pinentry_environment (assuan_context_t ctx, @@ -43,62 +67,49 @@ send_pinentry_environment (assuan_context_t ctx, const char *opt_lc_ctype, const char *opt_lc_messages) { - int rc = 0; + gpg_error_t err = 0; char *dft_display = NULL; char *dft_ttyname = NULL; char *dft_ttytype = NULL; char *old_lc = NULL; char *dft_lc = NULL; + /* Send the DISPLAY variable. */ dft_display = getenv ("DISPLAY"); if (opt_display || dft_display) { - char *optstr; - if (asprintf (&optstr, "OPTION display=%s", - opt_display ? opt_display : dft_display) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); + err = send_one_option (ctx, "display", + opt_display ? opt_display : dft_display); + if (err) + return err; } + + /* Send the name of the TTY. */ if (!opt_ttyname) { dft_ttyname = getenv ("GPG_TTY"); -#ifdef HAVE_DOSISH_SYSTEM - if (!dft_ttyname || !*dft_ttyname ) - dft_ttyname = "/dev/tty"; /* Use a fake. */ -#else if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) dft_ttyname = ttyname (0); -#endif } if (opt_ttyname || dft_ttyname) { - char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", - opt_ttyname ? opt_ttyname : dft_ttyname) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); + err = send_one_option (ctx, "ttyname", + opt_ttyname ? opt_ttyname : dft_ttyname); + if (err) + return err; } + + /* Send the type of the TTY. */ dft_ttytype = getenv ("TERM"); if (opt_ttytype || (dft_ttyname && dft_ttytype)) { - char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", - opt_ttyname ? opt_ttytype : dft_ttytype) < 0) - return gpg_error_from_errno (errno); - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - return map_assuan_err (rc); + err = send_one_option (ctx, "ttytype", + opt_ttyname ? opt_ttytype : dft_ttytype); + if (err) + return err; } + + /* Send the value for LC_CTYPE. */ #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) old_lc = setlocale (LC_CTYPE, NULL); if (old_lc) @@ -111,18 +122,8 @@ send_pinentry_environment (assuan_context_t ctx, #endif if (opt_lc_ctype || (dft_ttyname && dft_lc)) { - char *optstr; - if (asprintf (&optstr, "OPTION lc-ctype=%s", - opt_lc_ctype ? opt_lc_ctype : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } + err = send_one_option (ctx, "lc-ctype", + opt_lc_ctype ? opt_lc_ctype : dft_lc); } #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) if (old_lc) @@ -131,8 +132,10 @@ send_pinentry_environment (assuan_context_t ctx, free (old_lc); } #endif - if (rc) - return rc; + if (err) + return err; + + /* Send the value for LC_MESSAGES. */ #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) old_lc = setlocale (LC_MESSAGES, NULL); if (old_lc) @@ -145,18 +148,8 @@ send_pinentry_environment (assuan_context_t ctx, #endif if (opt_lc_messages || (dft_ttyname && dft_lc)) { - char *optstr; - if (asprintf (&optstr, "OPTION lc-messages=%s", - opt_lc_messages ? opt_lc_messages : dft_lc) < 0) - rc = gpg_error_from_errno (errno); - else - { - rc = assuan_transact (ctx, optstr, NULL, NULL, NULL, NULL, NULL, - NULL); - free (optstr); - if (rc) - rc = map_assuan_err (rc); - } + err = send_one_option (ctx, "display", + opt_lc_messages ? opt_lc_messages : dft_lc); } #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) if (old_lc) @@ -165,7 +158,9 @@ send_pinentry_environment (assuan_context_t ctx, free (old_lc); } #endif + if (err) + return err; - return rc; + return 0; } diff --git a/common/exechelp.c b/common/exechelp.c index 206e16d51..0a9cb824f 100644 --- a/common/exechelp.c +++ b/common/exechelp.c @@ -30,8 +30,7 @@ #ifdef USE_GNU_PTH #include #endif -#ifdef _WIN32 -#else +#ifndef HAVE_W32_SYSTEM #include #endif @@ -39,6 +38,9 @@ #include "i18n.h" #include "exechelp.h" +/* Define to 1 do enable debugging. */ +#define DEBUG_W32_SPAWN 1 + #ifdef _POSIX_OPEN_MAX #define MAX_OPEN_FDS _POSIX_OPEN_MAX @@ -57,6 +59,105 @@ #endif +#ifdef HAVE_W32_SYSTEM +/* We assume that a HANDLE can be represented by an int which should + be true for all i386 systems (HANDLE is defined as void *) and + these are the only systems for which Windows is available. Further + we assume that -1 denotes an invalid handle. */ +# define fd_to_handle(a) ((HANDLE)(a)) +# define handle_to_fd(a) ((int)(a)) +# define pid_to_handle(a) ((HANDLE)(a)) +# define handle_to_pid(a) ((int)(a)) +#endif + + +#ifdef HAVE_W32_SYSTEM +/* Build a command line for use with W32's CreateProcess. On success + CMDLINE gets the address of a newly allocated string. */ +static gpg_error_t +build_w32_commandline (const char *pgmname, const char **argv, char **cmdline) +{ + int i, n; + const char *s; + char *buf, *p; + + *cmdline = NULL; + n = strlen (pgmname); + for (i=0; (s=argv[i]); i++) + { + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + } + n++; + + buf = p = xtrymalloc (n); + if (!buf) + return gpg_error_from_errno (errno); + + /* fixme: PGMNAME may not contain spaces etc. */ + p = stpcpy (p, pgmname); + for (i=0; argv[i]; i++) + { + if (!*argv[i]) /* Empty string. */ + p = stpcpy (p, " \"\""); + else if (strpbrk (argv[i], " \t\n\v\f\"")) + { + p = stpcpy (p, " \""); + for (s=argv[i]; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (stpcpy (p, " "), argv[i]); + } + + *cmdline= buf; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +/* Create pipe where the write end is inheritable. */ +static int +create_inheritable_pipe (int filedes[2]) +{ + HANDLE r, w, h; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + if (!CreatePipe (&r, &w, &sec_attr, 0)) + return -1; + + if (!DuplicateHandle (GetCurrentProcess(), w, + GetCurrentProcess(), &h, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + { + log_error ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; + } + CloseHandle (w); + w = h; + + filedes[0] = handle_to_fd (r); + filedes[1] = handle_to_fd (w); + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + /* Fork and exec the PGMNAME, connect the file descriptor of INFILE to stdin, write the output to OUTFILE, return a new stream in @@ -73,10 +174,121 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], void (*preexec)(void), FILE **statusfile, pid_t *pid) { -#ifdef _WIN32 - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#ifdef HAVE_W32_SYSTEM + gpg_error_t err; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int cr_flags; + char *cmdline; + int fd, fdout, rp[2]; -#else /* !_WIN32 */ + /* Setup return values. */ + *statusfile = NULL; + *pid = (pid_t)(-1); + fflush (infile); + rewind (infile); + fd = _get_osfhandle (fileno (infile)); + fdout = _get_osfhandle (fileno (outfile)); + if (fd == -1 || fdout == -1) + log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Build the command line. */ + err = build_w32_commandline (pgmname, argv, &cmdline); + if (err) + return err; + + /* Create a pipe. */ + if (create_inheritable_pipe (rp)) + { + err = gpg_error (GPG_ERR_GENERAL); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + xfree (cmdline); + return err; + } + + /* Start the process. Note that we can't run the PREEXEC function + because this would change our own environment. */ + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + si.hStdInput = fd_to_handle (fd); + si.hStdOutput = fd_to_handle (fdout); + si.hStdError = fd_to_handle (rp[1]); + + cr_flags = (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED); + log_debug ("CreateProcess, path=`%s' cmdline=`%s'", pgmname, cmdline); + if (!CreateProcess (pgmname, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + TRUE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); + xfree (cmdline); + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + return gpg_error (GPG_ERR_GENERAL); + } + xfree (cmdline); + cmdline = NULL; + + /* Close the other end of the pipe. */ + CloseHandle (fd_to_handle (rp[1])); + + log_debug ("CreateProcess ready: hProcess=%p hThread=%p" + " dwProcessID=%d dwThreadId=%d\n", + pi.hProcess, pi.hThread, + (int) pi.dwProcessId, (int) pi.dwThreadId); + + /* Process ha been created suspended; resume it now. */ + ResumeThread (pi.hThread); + CloseHandle (pi.hThread); + + { + int x; + + x = _open_osfhandle (rp[0], 0); + if (x == -1) + log_error ("failed to translate osfhandle %p\n", (void*)rp[0] ); + else + { + log_debug ("_open_osfhandle %p yields %d\n", (void*)fd, x ); + *statusfile = fdopen (x, "r"); + } + } + if (!*statusfile) + { + err = gpg_error_from_errno (errno); + log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err)); + CloseHandle (pi.hProcess); + return err; + } + + *pid = handle_to_pid (pi.hProcess); + return 0; + +#else /* !HAVE_W32_SYSTEM */ gpg_error_t err; int fd, fdout, rp[2]; @@ -87,8 +299,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], fd = fileno (infile); fdout = fileno (outfile); if (fd == -1 || fdout == -1) - log_fatal ("no file descriptor for file passed" - " to gnupg_spawn_process: %s\n", strerror (errno) ); + log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); if (pipe (rp) == -1) { @@ -170,7 +381,7 @@ gnupg_spawn_process (const char *pgmname, const char *argv[], } return 0; -#endif /* !_WIN32 */ +#endif /* !HAVE_W32_SYSTEM */ } @@ -183,10 +394,51 @@ gnupg_wait_process (const char *pgmname, pid_t pid) { gpg_err_code_t ec; -#ifdef _WIN32 - ec = GPG_ERR_NOT_IMPLEMENTED; +#ifdef HAVE_W32_SYSTEM + HANDLE proc = fd_to_handle (pid); + int code; + DWORD exc; + + if (pid == (pid_t)(-1)) + return gpg_error (GPG_ERR_INV_VALUE); + + /* FIXME: We should do a pth_waitpid here. However this has not yet + been implemented. A special W32 pth system call would even be + better. */ + code = WaitForSingleObject (proc, INFINITE); + switch (code) + { + case WAIT_FAILED: + log_error (_("waiting for process %d to terminate failed: %s\n"), + (int)pid, w32_strerror (-1)); + ec = GPG_ERR_GENERAL; + break; + + case WAIT_OBJECT_0: + if (!GetExitCodeProcess (proc, &exc)) + { + log_error (_("error getting exit code of process %d: %s\n"), + (int)pid, w32_strerror (-1) ); + ec = GPG_ERR_GENERAL; + } + else if (exc) + { + log_error (_("error running `%s': exit status %d\n"), + pgmname, (int)exc ); + ec = GPG_ERR_GENERAL; + } + else + ec = 0; + break; + + default: + log_error ("WaitForSingleObject returned unexpected " + "code %d for pid %d\n", code, (int)pid ); + ec = GPG_ERR_GENERAL; + break; + } -#else /* !_WIN32 */ +#else /* !HAVE_W32_SYSTEM */ int i, status; if (pid == (pid_t)(-1)) @@ -222,7 +474,7 @@ gnupg_wait_process (const char *pgmname, pid_t pid) } else ec = 0; -#endif /* !_WIN32 */ +#endif /* !HAVE_W32_SYSTEM */ return gpg_err_make (GPG_ERR_SOURCE_DEFAULT, ec); diff --git a/common/iobuf.c b/common/iobuf.c index 4d735397e..52a388514 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1096,7 +1096,7 @@ iobuf_cancel (iobuf_t a) if (s && *s) { #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - remove_name = m_strdup (s); + remove_name = xstrdup (s); #else remove (s); #endif @@ -1267,7 +1267,7 @@ iobuf_sockopen (int fd, const char *mode) size_t len; a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); - scx = m_alloc (sizeof *scx + 25); + scx = xmalloc (sizeof *scx + 25); scx->sock = fd; scx->print_only_name = 1; sprintf (scx->fname, "[sock %d]", fd); diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 1e8eae63b..e7f992a88 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -31,7 +31,7 @@ #include #include #include -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM #include #else #include @@ -182,10 +182,8 @@ agent_send_all_options (int fd) } dft_ttyname = getenv ("GPG_TTY"); -#ifndef HAVE_W32_SYSTEM if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) dft_ttyname = ttyname (0); -#endif if (dft_ttyname && *dft_ttyname) { if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) @@ -261,7 +259,7 @@ agent_send_all_options (int fd) static int agent_open (int *rfd) { -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM return SPWQ_NO_AGENT; /* FIXME */ #else int rc; diff --git a/common/sysutils.h b/common/sysutils.h index 66f714acd..9df292031 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -27,5 +27,12 @@ int enable_core_dumps (void); const unsigned char *get_session_marker (size_t *rlen); int check_permissions (const char *path,int extension,int checkonly); +#ifdef HAVE_W32_SYSTEM +/*-- w32reg.c --*/ +char *read_w32_registry_string( const char *root, + const char *dir, const char *name ); +int write_w32_registry_string(const char *root, const char *dir, + const char *name, const char *value); +#endif /*HAVE_W32_SYSTEM*/ #endif /*GNUPG_COMMON_SYSUTILS_H*/ diff --git a/common/ttyname.c b/common/ttyname.c new file mode 100644 index 000000000..822beef99 --- /dev/null +++ b/common/ttyname.c @@ -0,0 +1,32 @@ +/* ttyname.c - Replacement for ttyname. + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +/* This one is a simple dummy and suitable for Dosish systems. */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include + +char * +ttyname (int fd) +{ + return NULL; +} diff --git a/common/util.h b/common/util.h index fad7d38cc..0b9357d3a 100644 --- a/common/util.h +++ b/common/util.h @@ -147,7 +147,9 @@ int asprintf (char **result, const char *format, ...) JNLIB_GCC_A_PRINTF(2,3); #ifndef HAVE_STRSEP char *strsep (char **stringp, const char *delim); #endif - +#ifndef HAVE_TTYNAME +char *ttyname (int fd); +#endif /*-- some macros to replace ctype ones and avoid locale problems --*/ #define spacep(p) (*(p) == ' ' || *(p) == '\t') diff --git a/common/w32reg.c b/common/w32reg.c index 19fb613e7..a85ac7348 100644 --- a/common/w32reg.c +++ b/common/w32reg.c @@ -19,7 +19,7 @@ */ #include -#if defined (_WIN32) || defined (__CYGWIN32__) +#ifdef HAVE_W32_SYSTEM /* This module is only used in this environment */ #include @@ -29,6 +29,7 @@ #include #include "util.h" +#include "sysutils.h" static HKEY get_root_key(const char *root) @@ -169,4 +170,4 @@ write_w32_registry_string(const char *root, const char *dir, return 0; } -#endif /* __MINGW32__ || __CYGWIN32__ */ +#endif /*HAVE_W32_SYSTEM*/ diff --git a/configure.ac b/configure.ac index 481e52c52..facbfe416 100644 --- a/configure.ac +++ b/configure.ac @@ -218,12 +218,6 @@ if test "$use_exec" = yes ; then AC_MSG_RESULT($enableval) fi -AC_MSG_CHECKING([whether the included zlib is requested]) -AC_ARG_WITH(included-zlib, - [ --with-included-zlib use the zlib code included here], -[g10_force_zlib=yes], [g10_force_zlib=no] ) -AC_MSG_RESULT($g10_force_zlib) - dnl dnl Check whether we want to use Linux capabilities dnl @@ -799,6 +793,7 @@ AC_REPLACE_FUNCS(fseeko ftello) AC_REPLACE_FUNCS(isascii) AC_REPLACE_FUNCS(putc_unlocked) AC_REPLACE_FUNCS(strsep) +AC_REPLACE_FUNCS(ttyname) @@ -923,14 +918,10 @@ fi dnl Do we have zlib? Must do it here because Solaris failed dnl when compiling a conftest (due to the "-lz" from LIBS). -use_local_zlib=yes -if test "$g10_force_zlib" = "yes"; then - : -else - _cppflags="${CPPFLAGS}" - _ldflags="${LDFLAGS}" +_cppflags="${CPPFLAGS}" +_ldflags="${LDFLAGS}" - AC_ARG_WITH(zlib, +AC_ARG_WITH(zlib, [ --with-zlib=DIR use libz in DIR],[ if test -d "$withval"; then CPPFLAGS="${CPPFLAGS} -I$withval/include" @@ -938,23 +929,12 @@ else fi ]) - AC_CHECK_HEADER(zlib.h, +AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, deflateInit2_, - use_local_zlib=no LIBS="$LIBS -lz", CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) -fi -if test "$use_local_zlib" = yes ; then - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) - AC_CONFIG_LINKS(zlib.h:zlib/zlib.h zconf.h:zlib/zconf.h ) - ZLIBS="../zlib/libzlib.a" -else - AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) - ZLIBS= -fi -AC_SUBST(ZLIBS) # See wether we want to run the long test suite. diff --git a/g10/call-agent.c b/g10/call-agent.c index f93132fde..473b38236 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -171,6 +171,8 @@ start_agent (void) if (rc) return map_assuan_err (rc); +#warning put this code into common/asshelp.c + dft_display = getenv ("DISPLAY"); if (opt.display || dft_display) { diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index 2eaa7916f..71512715b 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,7 @@ +2004-12-15 Werner Koch + + * logging.c [W32]: Don't include unavailable headers. + 2004-12-14 Werner Koch * w32-pth.c (_pth_strerror): Renamed to ... diff --git a/jnlib/logging.c b/jnlib/logging.c index 960d816eb..781f03e6d 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -35,16 +35,13 @@ #include #include #include -#ifndef _WIN32 +#ifndef HAVE_W32_SYSTEM #include #include -#endif +#endif /*!HAVE_W32_SYSTEM*/ #include #include #include -#ifdef __MINGW32__ -# include -#endif #define JNLIB_NEED_LOG_LOGV 1 diff --git a/m4/ksba.m4 b/m4/ksba.m4 index c59ac8024..99017c39e 100644 --- a/m4/ksba.m4 +++ b/m4/ksba.m4 @@ -14,7 +14,7 @@ dnl AM_PATH_KSBA([MINIMUM-VERSION, dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS dnl -AC_DEFUN(AM_PATH_KSBA, +AC_DEFUN([AM_PATH_KSBA], [ AC_ARG_WITH(ksba-prefix, AC_HELP_STRING([--with-ksba-prefix=PFX], [prefix where KSBA is installed (optional)]), diff --git a/scd/ChangeLog b/scd/ChangeLog index 628055e80..fe3b3f6c4 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,14 @@ +2004-12-15 Werner Koch + + * scdaemon.c [W32]: Various hacks to make it run under W32. + + * command.c (scd_update_reader_status_file) [W32]: Don't use kill. + + * apdu.c [W32]: Disable use of pcsc_wrapper. + + * Makefile.am (scdaemon_LDADD): Reorder libs. + (sc_copykeys_LDADD): Add libassuan because it is needed for W32. + 2004-12-06 Werner Koch * Makefile.am (pkglib_PROGRAMS): Build only for W32. diff --git a/scd/Makefile.am b/scd/Makefile.am index 43bee4889..fba006c5a 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -19,7 +19,7 @@ ## Process this file with automake to produce Makefile.in bin_PROGRAMS = scdaemon sc-copykeys -if HAVE_W32_SYSTEM +if ! HAVE_W32_SYSTEM pkglib_PROGRAMS = pcsc-wrapper endif @@ -53,10 +53,8 @@ scdaemon_SOURCES = \ scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommon.a \ - $(LIBGCRYPT_LIBS) $(pth_libs) \ - $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ - $(LIBUSB_LIBS) $(OPENSC_LIBS) -lgpg-error @LIBINTL@ \ - @DL_LIBS@ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(pth_libs) $(LIBASSUAN_LIBS) \ + $(LIBUSB_LIBS) $(OPENSC_LIBS) -lgpg-error $(LIBINTL) $(DL_LIBS) sc_copykeys_SOURCES = \ sc-copykeys.c scdaemon.h \ @@ -70,10 +68,10 @@ sc_copykeys_SOURCES = \ sc_copykeys_LDADD = \ ../jnlib/libjnlib.a ../common/libcommon.a \ ../common/libsimple-pwquery.a \ - $(LIBGCRYPT_LIBS) $(pth_libs) \ - $(KSBA_LIBS) $(LIBUSB_LIBS) $(OPENSC_LIBS) \ + $(LIBGCRYPT_LIBS) $(pth_libs) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ + $(LIBUSB_LIBS) $(OPENSC_LIBS) \ -lgpg-error @LIBINTL@ @DL_LIBS@ pcsc_wrapper_SOURCES = pcsc-wrapper.c -pcsc_wrapper_LDADD = @DL_LIBS@ +pcsc_wrapper_LDADD = $(DL_LIBS) pcsc_wrapper_CFLAGS = diff --git a/scd/apdu.c b/scd/apdu.c index f4b32d141..9120616de 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -65,11 +65,16 @@ #include "dynload.h" #include "ccid-driver.h" + +/* To to conflicting use of threading libraries we usually can't link + against libpcsclite. Instead we use a wrapper program. */ #ifdef USE_GNU_PTH +#ifndef HAVE_W32_SYSTEM #define NEED_PCSC_WRAPPER 1 #endif +#endif - + #define MAX_READER 4 /* Number of readers we support concurrently. */ diff --git a/scd/command.c b/scd/command.c index 6fa100ff9..b99fffc09 100644 --- a/scd/command.c +++ b/scd/command.c @@ -1260,8 +1260,13 @@ scd_update_reader_status_file (void) int signo = primary_connection->server_local->event_signal; log_info ("client pid is %d, sending signal %d\n", pid, signo); + +#ifdef HAVE_W32_SYSTEM +#warning Need to implement a notification service +#else if (pid != (pid_t)(-1) && pid && signo > 0) kill (pid, signo); +#endif } } } diff --git a/scd/scdaemon.c b/scd/scdaemon.c index b54a63816..135f0973a 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -29,8 +29,10 @@ #include #include #include +#ifndef HAVE_W32_SYSTEM #include #include +#endif /*HAVE_W32_SYSTEM*/ #include #include #ifdef USE_GNU_PTH @@ -47,6 +49,9 @@ #include "i18n.h" #include "sysutils.h" #include "app-common.h" +#ifdef HAVE_W32_SYSTEM +#include "../jnlib/w32-afunix.h" +#endif enum cmd_and_opt_values @@ -131,7 +136,12 @@ static ARGPARSE_OPTS opts[] = { }; +/* The card dirver we use by default for PC/SC. */ +#ifdef HAVE_W32_SYSTEM +#define DEFAULT_PCSC_DRIVER "winscard.dll" +#else #define DEFAULT_PCSC_DRIVER "libpcsclite.so" +#endif static volatile int caught_fatal_sig = 0; @@ -148,8 +158,10 @@ static char socket_name[128]; #ifndef HAVE_OPENSC #ifdef USE_GNU_PTH +#ifndef HAVE_W32_SYSTEM /* Pth wrapper function definitions. */ GCRY_THREAD_OPTION_PTH_IMPL; +#endif static void *ticker_thread (void *arg); #endif /*USE_GNU_PTH*/ @@ -341,12 +353,16 @@ main (int argc, char **argv ) Note that this will also do the pth_init. */ #ifndef HAVE_OPENSC #ifdef USE_GNU_PTH +# ifdef HAVE_W32_SYSTEM + pth_init (); +# else /*!HAVE_W32_SYSTEM*/ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); if (err) { log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", gpg_strerror (err)); } +# endif /*!HAVE_W32_SYSTEM*/ #endif /*USE_GNU_PTH*/ #endif /*!HAVE_OPENSC*/ @@ -649,12 +665,15 @@ main (int argc, char **argv ) if (!p) BUG (); *p = 0;; + +#ifndef HAVE_W32_SYSTEM if (!mkdtemp(socket_name)) { log_error ("can't create directory `%s': %s\n", socket_name, strerror(errno) ); exit (1); } +#endif *p = '/'; if (strchr (socket_name, ':') ) @@ -669,7 +688,11 @@ main (int argc, char **argv ) } +#ifdef HAVE_W32_SYSTEM + fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); +#else fd = socket (AF_UNIX, SOCK_STREAM, 0); +#endif if (fd == -1) { log_error ("can't create socket: %s\n", strerror(errno) ); @@ -682,7 +705,13 @@ main (int argc, char **argv ) len = (offsetof (struct sockaddr_un, sun_path) + strlen(serv_addr.sun_path) + 1); - if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1) + if ( +#ifdef HAVE_W32_SYSTEM + _w32_sock_bind +#else + bind +#endif + (fd, (struct sockaddr*)&serv_addr, len) == -1) { log_error ("error binding socket to `%s': %s\n", serv_addr.sun_path, strerror (errno) ); @@ -702,6 +731,7 @@ main (int argc, char **argv ) fflush (NULL); +#ifndef HAVE_W32_SYSTEM pid = fork (); if (pid == (pid_t)-1) { @@ -800,6 +830,8 @@ main (int argc, char **argv ) exit (1); } +#endif /*!HAVE_W32_SYSTEM*/ + scd_command_handler (fd); close (fd); @@ -846,6 +878,7 @@ handle_signal (int signo) { switch (signo) { +#ifndef HAVE_W32_SYSTEM case SIGHUP: log_info ("SIGHUP received - " "re-reading configuration and resetting cards\n"); @@ -882,6 +915,7 @@ handle_signal (int signo) cleanup (); scd_exit (0); break; +#endif /*!HAVE_W32_SYSTEM*/ default: log_info ("signal %d received - no action defined\n", signo); @@ -901,6 +935,7 @@ ticker_thread (void *dummy_arg) sigset_t sigs; int signo; +#ifndef HAVE_W32_SYSTEM /* fixme */ sigemptyset (&sigs ); sigaddset (&sigs, SIGHUP); sigaddset (&sigs, SIGUSR1); @@ -908,6 +943,9 @@ ticker_thread (void *dummy_arg) sigaddset (&sigs, SIGINT); sigaddset (&sigs, SIGTERM); sigs_ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +#else + sigs_ev = NULL; +#endif for (;;) { diff --git a/sm/ChangeLog b/sm/ChangeLog index c1e445e4e..096c4ca8e 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,13 @@ +2004-12-15 Werner Koch + + * misc.c (setup_pinentry_env) [W32]: Don't use it. + + * gpgsm.c (main) [W32]: Init Pth because we need it for the socket + operations and to resolve libassuan symbols. + (run_protect_tool) [W32]: Disable it. + + * Makefile.am (gpgsm_LDADD): Move LIBASSUAN_LIBS more to the end. + 2004-12-07 Werner Koch * Makefile.am (gpgsm_LDADD): Put libassuan before jnlib because diff --git a/sm/Makefile.am b/sm/Makefile.am index ff4524fc7..9136eb920 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -51,9 +51,9 @@ gpgsm_SOURCES = \ certreqgen.c -gpgsm_LDADD = $(LIBASSUAN_LIBS) ../jnlib/libjnlib.a ../kbx/libkeybox.a \ - ../common/libcommon.a \ - $(LIBGCRYPT_LIBS) $(KSBA_LIBS) -lgpg-error \ - $(LIBINTL) +gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ + ../common/libcommon.a \ + $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) -lgpg-error \ + $(LIBINTL) diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 0feca2608..f79375da7 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef USE_GNU_PTH +# include +#endif #include "gpgsm.h" #include @@ -736,6 +739,11 @@ main ( int argc, char **argv) NEED_KSBA_VERSION, ksba_check_version (NULL) ); } +#ifdef HAVE_W32_SYSTEM + pth_init (); +#endif + + gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); may_coredump = disable_core_dumps (); @@ -746,7 +754,8 @@ main ( int argc, char **argv) i18n_init(); opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/ -#ifdef __MINGW32__ + +#ifdef HAVE_W32_SYSTEM opt.homedir = read_w32_registry_string ( NULL, "Software\\GNU\\GnuPG", "HomeDir" ); #else @@ -1688,7 +1697,7 @@ open_fwrite (const char *filename) static void run_protect_tool (int argc, char **argv) { -#ifndef _WIN32 +#ifndef HAVE_W32_SYSTEM const char *pgm; char **av; int i; @@ -1707,6 +1716,6 @@ run_protect_tool (int argc, char **argv) av[i] = NULL; execv (pgm, av); log_error ("error executing `%s': %s\n", pgm, strerror (errno)); -#endif +#endif /*HAVE_W32_SYSTEM*/ gpgsm_exit (2); } diff --git a/tools/ChangeLog b/tools/ChangeLog index cb341ad4f..34e985947 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,13 @@ +2004-12-15 Werner Koch + + * Makefile.am (bin_PROGRAMS) [W32]: Do not build watchgnupg. + + * gpgconf-comp.c (gpg_agent_runtime_change) [W32]: No way yet to + send a signal. Disable. + (change_options_file, change_options_program) [W32]: No link(2), + so we disable it. + (gc_component_change_options): Use rename instead of link. + 2004-12-13 Werner Koch * gpgconf-comp.c : Fixed typo. diff --git a/tools/Makefile.am b/tools/Makefile.am index 2378df813..112c77e7c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -32,7 +32,10 @@ sbin_SCRIPTS = addgnupghome bin_SCRIPTS = gpgsm-gencert.sh -bin_PROGRAMS = gpgconf watchgnupg +bin_PROGRAMS = gpgconf +if !HAVE_W32_SYSTEM +bin_PROGRAMS += watchgnupg +endif gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5d78df86d..fe696301c 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -861,6 +861,7 @@ static struct void gpg_agent_runtime_change (void) { +#ifndef HAVE_W32_SYSTEM char *agent = getenv ("GPG_AGENT_INFO"); char *pid_str; unsigned long pid_long; @@ -888,6 +889,7 @@ gpg_agent_runtime_change (void) /* Ignore any errors here. */ kill (pid, SIGHUP); +#endif /*!HAVE_W32_SYSTEM*/ } @@ -1741,7 +1743,12 @@ change_options_file (gc_component_t component, gc_backend_t backend, arg = NULL; } +#if HAVE_W32_SYSTEM + res = 0; +#warning no backups for W32 yet - need to write a copy function +#else res = link (dest_filename, orig_filename); +#endif if (res < 0 && errno != ENOENT) return -1; if (res < 0) @@ -2005,7 +2012,12 @@ change_options_program (gc_component_t component, gc_backend_t backend, src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); +#if HAVE_W32_SYSTEM + res = 0; +#warning no backups for W32 yet - need to write a copy function +#else res = link (dest_filename, orig_filename); +#endif if (res < 0 && errno != ENOENT) return -1; if (res < 0) @@ -2418,12 +2430,18 @@ gc_component_change_options (int component, FILE *in) err = rename (src_pathname[i], dest_pathname[i]); else { +#ifdef HAVE_W32_SYSTEM + /* FIXME: Won't work becuase W32 doesn't silently + overwrite. */ + err = rename (src_pathname[i], dest_pathname[i]); +#else /*!HAVE_W32_SYSTEM*/ /* This is a bit safer than rename() because we expect DEST_PATHNAME not to be there. If it happens to be there, this will fail. */ err = link (src_pathname[i], dest_pathname[i]); if (!err) unlink (src_pathname[i]); +#endif /*!HAVE_W32_SYSTEM*/ } if (err) break; -- cgit From 01f3f2515834876e2131d077e34c3cae4f9a2dc0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 21 Dec 2004 19:05:15 +0000 Subject: * preset-passphrase.c (preset_passphrase): Handle --passphrase. * Makefile.am (gpg_preset_passphrase_LDADD): Reorder libs so that pwquery may use stuff from jnlib. Conditionally add -lwsock2 (gpg_protect_tool_LDADD): Ditto. * preset-passphrase.c (main): Use default_homedir(). (main) [W32]: Initialize sockets. * simple-pwquery.c (agent_open) [W32]: Implement for W32. (readline) [W32]: Use recv instead of read. (writen) [W32]: Use send instead of write. (my_stpcpy): Define a stpcpy replacement so that this file continues to be self-contained. (agent_send_all_options) [W32]: Don't call ttyname. * gnupg-badge-openpgp.eps, gnupg-badge-openpgp.jpg: New * gnupg.texi: Add a logo. * sysnotes.texi: New. * gpgsm.c (main): Use default_homedir(). (main) [W32]: Default to disabled CRL checks. * gpgconf-comp.c (get_config_pathname) [DOSISH]: Detect absolute pathnames with a drive letter. --- agent/ChangeLog | 29 +- agent/Makefile.am | 18 +- agent/agent.h | 1 + agent/cache.c | 9 +- agent/command.c | 61 +- agent/gpg-agent.c | 5 + agent/preset-passphrase.c | 293 ++ common/ChangeLog | 14 + common/simple-pwquery.c | 124 +- common/simple-pwquery.h | 3 + doc/ChangeLog | 6 + doc/Makefile.am | 7 +- doc/gnupg-badge-openpgp.eps | 7798 +++++++++++++++++++++++++++++++++++++++++++ doc/gnupg-badge-openpgp.jpg | Bin 0 -> 63450 bytes doc/gnupg.texi | 10 + doc/gpg-agent.texi | 2 +- doc/gpgsm.texi | 2 +- doc/scdaemon.texi | 2 +- doc/sysnotes.texi | 107 + doc/tools.texi | 504 ++- jnlib/w32-afunix.c | 7 +- sm/ChangeLog | 1 + sm/gpgsm.c | 3 + tools/ChangeLog | 5 + tools/gpgconf-comp.c | 6 + 25 files changed, 8986 insertions(+), 31 deletions(-) create mode 100644 agent/preset-passphrase.c create mode 100644 doc/gnupg-badge-openpgp.eps create mode 100644 doc/gnupg-badge-openpgp.jpg create mode 100644 doc/sysnotes.texi (limited to 'tools/gpgconf-comp.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index cf3569264..d835c8e60 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,8 +1,33 @@ +2004-12-21 Werner Koch + + * preset-passphrase.c (preset_passphrase): Handle --passphrase. + + * Makefile.am (gpg_preset_passphrase_LDADD): Reorder libs so that + pwquery may use stuff from jnlib. Conditionally add -lwsock2 + (gpg_protect_tool_LDADD): Ditto. + + * preset-passphrase.c (main): Use default_homedir(). + (main) [W32]: Initialize sockets. + +2004-12-21 Marcus Brinkmann + + * Makefile.am (libexec_PROGRAMS): Add gpg-preset-passphrase. + (gpg_preset_passphrase_SOURCES, gpg_preset_passphrase_LDADD): New + targets. + * agent.h (opt): New member allow_cache_passphrase. + * cache.c (housekeeping): Check if R->ttl is not negative. + (agent_put_cache): Allow ttl to be negative. + * command.c (parse_hexstring): Allow something to follow the + hexstring. + (cmd_cache_passphrase): New function. + (register_commands): Add it. + * gpg-agent.c: Handle --allow-preset-passphrase. + * preset-passphrase.c: New file. + 2004-12-21 Werner Koch * gpg-agent.c (main): Use default_homedir(). - * protect-tool.c (main): Ditto. - + * protect-tool.c (main): Ditto. 2004-12-20 Werner Koch diff --git a/agent/Makefile.am b/agent/Makefile.am index 6f3ea70d2..4cedbe74e 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -19,7 +19,7 @@ ## Process this file with automake to produce Makefile.in bin_PROGRAMS = gpg-agent -libexec_PROGRAMS = gpg-protect-tool +libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl @@ -53,8 +53,20 @@ gpg_protect_tool_SOURCES = \ protect.c \ minip12.c minip12.h -gpg_protect_tool_LDADD = ../jnlib/libjnlib.a \ - ../common/libcommon.a ../common/libsimple-pwquery.a \ +gpg_protect_tool_LDADD = ../common/libsimple-pwquery.a \ + ../jnlib/libjnlib.a ../common/libcommon.a \ $(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@ +if HAVE_W32_SYSTEM +gpg_protect_tool_LDADD += -lwsock32 +endif +gpg_preset_passphrase_SOURCES = \ + preset-passphrase.c + +gpg_preset_passphrase_LDADD = ../common/libsimple-pwquery.a \ + ../jnlib/libjnlib.a ../common/libcommon.a \ + $(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@ +if HAVE_W32_SYSTEM +gpg_preset_passphrase_LDADD += -lwsock32 +endif diff --git a/agent/agent.h b/agent/agent.h index 241b37b05..7d6bf9f47 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -63,6 +63,7 @@ struct { int ignore_cache_for_signing; int allow_mark_trusted; + int allow_preset_passphrase; int keep_tty; /* don't switch the TTY (for pinentry) on request */ int keep_display; /* don't switch the DISPLAY (for pinentry) on request */ } opt; diff --git a/agent/cache.c b/agent/cache.c index 8017b1414..b6762edd0 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -39,7 +39,7 @@ struct cache_item_s { ITEM next; time_t created; time_t accessed; - int ttl; /* max. lifetime given in seonds */ + int ttl; /* max. lifetime given in seonds, -1 one means infinite */ int lockcount; struct secret_data_s *pw; char key[1]; @@ -88,7 +88,8 @@ housekeeping (void) /* first expire the actual data */ for (r=thecache; r; r = r->next) { - if (!r->lockcount && r->pw && r->accessed + r->ttl < current) + if (!r->lockcount && r->pw + && r->ttl >= 0 && r->accessed + r->ttl < current) { if (DBG_CACHE) log_debug (" expired `%s' (%ds after last access)\n", @@ -118,7 +119,7 @@ housekeeping (void) Expire old and unused entries after 30 minutes */ for (rprev=NULL, r=thecache; r; ) { - if (!r->pw && r->accessed + 60*30 < current) + if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current) { if (r->lockcount) { @@ -194,7 +195,7 @@ agent_put_cache (const char *key, const char *data, int ttl) log_debug ("agent_put_cache `%s'\n", key); housekeeping (); - if (ttl < 1) + if (ttl == 1) ttl = opt.def_cache_ttl; if (!ttl) return 0; diff --git a/agent/command.c b/agent/command.c index 9fc08e211..dc8a4a158 100644 --- a/agent/command.c +++ b/agent/command.c @@ -141,7 +141,7 @@ parse_hexstring (ASSUAN_CONTEXT ctx, const char *string, size_t *len) /* parse the hash value */ for (p=string, n=0; hexdigitp (p); p++, n++) ; - if (*p) + if (*p != ' ' && *p != '\t' && *p) return set_error (Parameter_Error, "invalid hexstring"); if ((n&1)) return set_error (Parameter_Error, "odd number of digits"); @@ -741,6 +741,64 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line) return map_to_assuan_status (rc); } +/* PRESET_PASSPHRASE + + Set the cached passphrase/PIN for the key identified by the keygrip + to passwd for the given time, where -1 means infinite and 0 means + the default (currently only a timeout of -1 is allowed, which means + to never expire it). If passwd is not provided, ask for it via the + pinentry module. */ +static int +cmd_preset_passphrase (ASSUAN_CONTEXT ctx, char *line) +{ + int rc; + unsigned char grip[20]; + char *grip_clear = NULL; + char *passphrase = NULL; + int ttl; + + if (!opt.allow_preset_passphrase) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + rc = parse_keygrip (ctx, line, grip); + if (rc) + return rc; + + /* FIXME: parse_keygrip should return a tail pointer. */ + grip_clear = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + return map_to_assuan_status (gpg_error (GPG_ERR_MISSING_VALUE)); + *line = '\0'; + line++; + while (*line && (*line == ' ' || *line == '\t')) + line++; + + /* Currently, only infinite timeouts are allowed. */ + ttl = -1; + if (line[0] != '-' || line[1] != '1') + return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED)); + line++; + line++; + while (!(*line != ' ' && *line != '\t')) + line++; + + /* If there is a passphrase, use it. Currently, a passphrase is + required. */ + if (*line) + passphrase = line; + else + return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED)); + + rc = agent_put_cache (grip_clear, passphrase, ttl); + + if (rc) + log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc)); + + return map_to_assuan_status (rc); +} + /* SCD @@ -837,6 +895,7 @@ register_commands (ASSUAN_CONTEXT ctx) { "PKDECRYPT", cmd_pkdecrypt }, { "GENKEY", cmd_genkey }, { "GET_PASSPHRASE", cmd_get_passphrase }, + { "PRESET_PASSPHRASE", cmd_preset_passphrase }, { "CLEAR_PASSPHRASE", cmd_clear_passphrase }, { "GET_CONFIRMATION", cmd_get_confirmation }, { "LISTTRUSTED", cmd_listtrusted }, diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 2c3d834a5..e76623f75 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -89,6 +89,7 @@ enum cmd_and_opt_values oIgnoreCacheForSigning, oAllowMarkTrusted, + oAllowPresetPassphrase, oKeepTTY, oKeepDISPLAY }; @@ -141,6 +142,8 @@ static ARGPARSE_OPTS opts[] = { N_("do not use the PIN cache when signing")}, { oAllowMarkTrusted, "allow-mark-trusted", 0, N_("allow clients to mark keys as \"trusted\"")}, + { oAllowPresetPassphrase, "allow-preset-passphrase", 0, + N_("allow presetting passphrase")}, {0} }; @@ -392,6 +395,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break; + case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break; + default: return 0; /* not handled */ } diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c new file mode 100644 index 000000000..6a9f07a3e --- /dev/null +++ b/agent/preset-passphrase.c @@ -0,0 +1,293 @@ +/* preset-passphrase.c - A tool to preset a passphrase. + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LOCALE_H +#include +#endif +#ifdef HAVE_LANGINFO_CODESET +#include +#endif +#ifdef HAVE_DOSISH_SYSTEM +#include /* for setmode() */ +#endif +#ifdef HAVE_W32_SYSTEM +#include /* To initialize the sockets. fixme */ +#endif + +#define JNLIB_NEED_LOG_LOGV +#include "agent.h" +#include "minip12.h" +#include "simple-pwquery.h" +#include "i18n.h" +#include "sysutils.h" + + +enum cmd_and_opt_values +{ aNull = 0, + oVerbose = 'v', + oPassphrase = 'P', + + oPreset = 'c', + oForget = 'f', + + oNoVerbose = 500, + + oHomedir, + +aTest }; + + +static const char *opt_homedir; +static const char *opt_passphrase; + +static ARGPARSE_OPTS opts[] = { + + { 301, NULL, 0, N_("@Options:\n ") }, + + { oVerbose, "verbose", 0, "verbose" }, + { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" }, + { oPreset, "preset", 256, "preset passphrase"}, + { oForget, "forget", 256, "forget passphrase"}, + + { oHomedir, "homedir", 2, "@" }, + {0} +}; + + +static const char * +my_strusage (int level) +{ + const char *p; + switch (level) + { + case 11: p = "gpg-preset-passphrase (GnuPG)"; + break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); + break; + case 1: + case 40: + p = _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"); + break; + case 41: + p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n" + "Password cache maintenance\n"); + break; + + default: p = NULL; + } + return p; +} + + + +static void +i18n_init (void) +{ +#ifdef USE_SIMPLE_GETTEXT + set_gettext_file( PACKAGE_GT ); +#else +#ifdef ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE_GT, LOCALEDIR); + textdomain (PACKAGE_GT); +#endif +#endif +} + + +static gpg_error_t +map_spwq_error (int err) +{ + switch (err) + { + case 0: + return 0; + case SPWQ_OUT_OF_CORE: + return gpg_error_from_errno (ENOMEM); + case SPWQ_IO_ERROR: + return gpg_error_from_errno (EIO); + case SPWQ_PROTOCOL_ERROR: + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); + case SPWQ_ERR_RESPONSE: + return gpg_error (GPG_ERR_INV_RESPONSE); + case SPWQ_NO_AGENT: + return gpg_error (GPG_ERR_NO_AGENT); + case SPWQ_SYS_ERROR: + return gpg_error_from_errno (errno); + case SPWQ_GENERAL_ERROR: + default: + return gpg_error (GPG_ERR_GENERAL); + } +} + + +static void +preset_passphrase (const char *keygrip) +{ + int rc; + char *line; + /* FIXME: Use secure memory. */ + char passphrase[500]; + + if (!opt_passphrase) + { + rc = read (0, passphrase, sizeof (passphrase) - 1); + if (rc < 0) + { + log_error ("reading passphrase failed: %s\n", + gpg_strerror (gpg_error_from_errno (errno))); + return; + } + passphrase[rc] = '\0'; + line = strchr (passphrase, '\n'); + if (line) + { + line--; + if (line > passphrase && line[-1] == '\r') + line--; + *line = '\0'; + } + + /* FIXME: How to handle empty passwords? */ + } + + rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip, + opt_passphrase? opt_passphrase : passphrase); + if (rc < 0) + { + log_error ("caching passphrase failed: %s\n", + gpg_strerror (gpg_error_from_errno (errno))); + return; + } + if (!opt_passphrase) + wipememory (passphrase, sizeof (passphrase)); + + rc = map_spwq_error (simple_query (line)); + if (rc) + { + log_error ("caching passphrase failed: %s\n", gpg_strerror (rc)); + return; + } + + wipememory (line, strlen (line)); + free (line); +} + + +static void +forget_passphrase (const char *keygrip) +{ + int rc; + char *line; + + rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip); + if (rc < 0) + { + log_error ("clearing passphrase failed: %s\n", + gpg_strerror (gpg_error_from_errno (errno))); + return; + } + free (line); +} + + +int +main (int argc, char **argv) +{ + ARGPARSE_ARGS pargs; + int cmd = 0; + const char *keygrip = NULL; + + set_strusage (my_strusage); + log_set_prefix ("gpg-preset-passphrase", 1); + + /* Try to auto set the character set. */ + set_native_charset (NULL); + +#ifdef HAVE_W32_SYSTEM + /* Fixme: Need to initialize the Windows sockets: This should be + moved to another place and we should make sure that it won't get + doen twice, like when Pth is used too. */ + { + WSADATA wsadat; + WSAStartup (0x202, &wsadat); + } +#endif + + i18n_init (); + + opt_homedir = default_homedir (); + + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 1; /* (do not remove the args) */ + while (arg_parse (&pargs, opts) ) + { + switch (pargs.r_opt) + { + case oVerbose: opt.verbose++; break; + case oHomedir: opt_homedir = pargs.r.ret_str; break; + + case oPreset: cmd = oPreset; break; + case oForget: cmd = oForget; break; + case oPassphrase: opt_passphrase = pargs.r.ret_str; break; + + default : pargs.err = 2; break; + } + } + if (log_get_errorcount(0)) + exit(2); + + if (argc == 1) + keygrip = *argv; + else + usage (1); + + if (cmd == oPreset) + preset_passphrase (keygrip); + else if (cmd == oForget) + forget_passphrase (keygrip); + else + log_error ("one of the options --preset or --forget must be given\n"); + + agent_exit (0); + return 8; /*NOTREACHED*/ +} + + +void +agent_exit (int rc) +{ + rc = rc? rc : log_get_errorcount(0)? 2 : 0; + exit (rc); +} diff --git a/common/ChangeLog b/common/ChangeLog index 6a381b300..3e060258a 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,17 @@ +2004-12-21 Werner Koch + + * simple-pwquery.c (agent_open) [W32]: Implement for W32. + (readline) [W32]: Use recv instead of read. + (writen) [W32]: Use send instead of write. + (my_stpcpy): Define a stpcpy replacement so that this file + continues to be self-contained. + (agent_send_all_options) [W32]: Don't call ttyname. + +2004-12-21 Marcus Brinkmann + + * simple-pwquery.h (simple_query): Add prototype. + * simple-pwquery.c (simple_query): New function. + 2004-12-21 Werner Koch * signal.c (got_fatal_signal, got_usr_signal) diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index e7f992a88..0b70ddecc 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -1,5 +1,5 @@ /* simple-pwquery.c - A simple password query cleint for gpg-agent - * Copyright (C) 2002 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -40,6 +40,10 @@ #ifdef HAVE_LOCALE_H #include #endif +#ifdef HAVE_W32_SYSTEM +#include "../jnlib/w32-afunix.h" +#endif + #define SIMPLE_PWQUERY_IMPLEMENTATION 1 #include "simple-pwquery.h" @@ -63,6 +67,25 @@ #endif + + + + +#ifndef HAVE_STPCPY +static char * +my_stpcpy(char *a,const char *b) +{ + while( *b ) + *a++ = *b++; + *a = 0; + + return (char*)a; +} +#define stpcpy(a,b) my_stpcpy((a), (b)) +#endif + + + /* Write NBYTES of BUF to file descriptor FD. */ static int writen (int fd, const void *buf, size_t nbytes) @@ -72,7 +95,11 @@ writen (int fd, const void *buf, size_t nbytes) while (nleft > 0) { - nwritten = write( fd, buf, nleft ); +#ifdef HAVE_W32_SYSTEM + nwritten = send (fd, buf, nleft, 0); +#else + nwritten = write (fd, buf, nleft); +#endif if (nwritten < 0) { if (errno == EINTR) @@ -102,7 +129,11 @@ readline (int fd, char *buf, size_t buflen) while (nleft > 0) { +#ifdef HAVE_W32_SYSTEM + int n = recv (fd, buf, nleft, 0); +#else int n = read (fd, buf, nleft); +#endif if (n < 0) { if (errno == EINTR) @@ -182,8 +213,10 @@ agent_send_all_options (int fd) } dft_ttyname = getenv ("GPG_TTY"); +#ifndef HAVE_W32_SYSTEM if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) dft_ttyname = ttyname (0); +#endif if (dft_ttyname && *dft_ttyname) { if ((rc=agent_send_option (fd, "ttyname", dft_ttyname))) @@ -259,9 +292,6 @@ agent_send_all_options (int fd) static int agent_open (int *rfd) { -#ifdef HAVE_W32_SYSTEM - return SPWQ_NO_AGENT; /* FIXME */ -#else int rc; int fd; char *infostr, *p; @@ -286,7 +316,7 @@ agent_open (int *rfd) strcpy (p, infostr); infostr = p; - if ( !(p = strchr ( infostr, ':')) || p == infostr + if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr || (p-infostr)+1 >= sizeof client_addr.sun_path ) { #ifdef SPWQ_USE_LOGGING @@ -296,7 +326,7 @@ agent_open (int *rfd) } *p++ = 0; - while (*p && *p != ':') + while (*p && *p != PATHSEP_C) p++; prot = *p? atoi (p+1) : 0; if ( prot != 1) @@ -306,8 +336,13 @@ agent_open (int *rfd) #endif return SPWQ_PROTOCOL_ERROR; } - - if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) + +#ifdef HAVE_W32_SYSTEM + fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0); +#else + fd = socket (AF_UNIX, SOCK_STREAM, 0); +#endif + if (fd == -1) { #ifdef SPWQ_USE_LOGGING log_error ("can't create socket: %s\n", strerror(errno) ); @@ -321,7 +356,12 @@ agent_open (int *rfd) len = (offsetof (struct sockaddr_un, sun_path) + strlen(client_addr.sun_path) + 1); - if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1) +#ifdef HAVE_W32_SYSTEM + rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len ); +#else + rc = connect (fd, (struct sockaddr*)&client_addr, len ); +#endif + if (rc == -1) { #ifdef SPWQ_USE_LOGGING log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno)); @@ -353,12 +393,11 @@ agent_open (int *rfd) *rfd = fd; return 0; -#endif } /* Copy text to BUFFER and escape as required. Return a pointer to - the end of the new buffer. NOte that BUFFER must be large enough + the end of the new buffer. Note that BUFFER must be large enough to keep the entire text; allocataing it 3 times the size of TEXT is sufficient. */ static char * @@ -505,3 +544,64 @@ simple_pwquery (const char *cacheid, spwq_free (pw); return result; } + + +/* Perform the simple query QUERY (which must be new-line and 0 + terminated) and return the error code. */ +int +simple_query (const char *query) +{ + int fd = -1; + int nread; + char response[500]; + int rc; + + rc = agent_open (&fd); + if (rc) + goto leave; + + rc = writen (fd, query, strlen (query)); + if (rc) + goto leave; + + /* get response */ + nread = readline (fd, response, 499); + if (nread < 0) + { + rc = -nread; + goto leave; + } + if (nread < 3) + { + rc = SPWQ_PROTOCOL_ERROR; + goto leave; + } + + if (response[0] == 'O' && response[1] == 'K') + /* OK, do nothing. */; + else if ((nread > 7 && !memcmp (response, "ERR 111", 7) + && (response[7] == ' ' || response[7] == '\n') ) + || ((nread > 4 && !memcmp (response, "ERR ", 4) + && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) ) + { + /* 111 is the old Assuan code for canceled which might still + be in use by old installations. 99 is GPG_ERR_CANCELED as + used by modern gpg-agents; 0xffff is used to mask out the + error source. */ +#ifdef SPWQ_USE_LOGGING + log_info (_("canceled by user\n") ); +#endif + } + else + { +#ifdef SPWQ_USE_LOGGING + log_error (_("problem with the agent\n")); +#endif + rc = SPWQ_ERR_RESPONSE; + } + + leave: + if (fd != -1) + close (fd); + return rc; +} diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index 5947c42b5..c7ebf9401 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -57,6 +57,9 @@ char *simple_pwquery (const char *cacheid, const char *description, int *errorcode); +/* Perform the simple query QUERY (which must be new-line and 0 + terminated) and return the error code. */ +int simple_query (const char *query); #define SPWQ_OUT_OF_CORE 1 #define SPWQ_IO_ERROR 2 diff --git a/doc/ChangeLog b/doc/ChangeLog index 9a9e213a3..41d6b811b 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,9 @@ +2004-12-21 Werner Koch + + * gnupg-badge-openpgp.eps, gnupg-badge-openpgp.jpg: New + * gnupg.texi: Add a logo. + * sysnotes.texi: New. + 2004-11-05 Werner Koch * debugging.texi (Common Problems): Curses pinentry problem. diff --git a/doc/Makefile.am b/doc/Makefile.am index d44765a2e..988bbf849 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2002 Free Software Foundation, Inc. +# Copyright (C) 2002, 2004 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -18,11 +18,14 @@ ## Process this file with automake to produce Makefile.in +EXTRA_DIST = gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg + info_TEXINFOS = gnupg.texi gnupg_TEXINFOS = \ gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi \ - tools.texi debugging.texi glossary.texi contrib.texi gpl.texi + tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \ + sysnotes.texi DISTCLEANFILES = gnupg.tmp gnupg.ops diff --git a/doc/gnupg-badge-openpgp.eps b/doc/gnupg-badge-openpgp.eps new file mode 100644 index 000000000..8edbaa617 --- /dev/null +++ b/doc/gnupg-badge-openpgp.eps @@ -0,0 +1,7798 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%Creator: GIMP PostScript file plugin V 1.10 by Peter Kirchgessner +%%Title: /home/wk/gnupg-badge-openpgp.eps +%%CreationDate: Thu May 4 10:58:15 2000 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%Pages: 1 +%%BoundingBox: 14 14 250 250 +%%EndComments +%%BeginProlog +% Use own dictionary to avoid conflicts +10 dict begin +%%EndProlog +%%Page: 1 1 +% Translate for offset +14.173228 14.173228 translate +% Translate to begin of first scanline +0.000000 235.680000 translate +235.680000 -235.680000 scale +% Image geometry +491 491 8 +% Transformation matrix +[ 491 0 0 491 0 0 ] +% Strings to hold RGB-samples per scanline +/rstr 491 string def +/gstr 491 string def +/bstr 491 string def +{currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop} +{currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop} +true 3 +%%BeginData: 538041 ASCII Bytes +colorimage +JcFO*s8Mfn"T8)mr;QTn!<2ut"TA>srVl]o#6">np\=R`kPk_ar;-9cq"j^aoEFs_q>:*fjo>>Z +!W;rhs8W'#rVlirq>^Kos8;oos87HJgAc[~> +JcFL)!<2urs8;lpqu?]qrr!0&q>UBnrVuoss8N#ss8W)rs82fqr;c`nq%EAjmd0/tgXXWn_SEgo +ZEUO:YkkX)Y8FOM['mHQ\\5o'cI:M)kN_R0q"aXYrr;urrrE&prrW/srqlWsr;HWprr2p#rr<#t +rpKg]rdk+4s*t~> +JcFa0"T.i_q"sO[s8Dro!;?Bir;R!!qYU6is8Mrr+8l!3q=saWna,K$j58S8^UCAGU7%7*Kn+Sq +EGoZ/AGTg9@38uiAnYmnDfpM`Ng?H@\\QG^Knq>5aCk5Tr~> +JcFR+s8E)trr2`nrr2co"T8;us8W)trr;usr;Qcqp\u$-q"*n9hqQc6eC2mtg>:ZBhV[8OjQ63p +)<0W6i8EMMhW*VRhVHr>f@JI%g#2/eoCVnNrrE&rs8W)rs8W'"s8N#qrrDuqs8Mutr;HVGs4[L'~> +JcFC&s8E#urVlZn#lXZ!rql]lrr;usrr<#t!<)iqs8;oqrqnJIp@@>&f$24J['-I,VP9f\Vl6Jg +US=NZV5C#`USOZ\USOcaV59u`US=Z`USFW\rhBgsVldAAajAYun+QbW')VV*rVZQjrVl`orr)ip +qYL3jrquotrVlcq"9/?"qsOL^rdk+3s*t~> +JcFa0"TA2nqu-$as8<0"qY^$P37=B\j7?sm>MA7oUmEHZegQ(b4c_U.#oio]LlnauMLq>1'gs8W)u +r;$0erVlfkrrW/sp\t'hrV6EkrIP"-s*t~> +JcFa0s8E#rrr)usqt^3c!W2fjrri?!q>C0irW)ops8MutrV$6qq"*b.g>h5mi=b//hq$?0f@\^+ +e_Jm6hVdGUk5" +JcF^/!<2Qhs8;urrr)isrVc`trVZWnrr;rqs$m"aq"jg\pup\gbe^]cSu/0s`qY^Bn +rquforWN2trVcZnrqHHmrdk+%s*t~> +JcFL)rr)ls#6"GrqYL*dr;?Zrr;$?mrVZ\#rr)]`lfmEeg;LM%SW8)7?tE\L>$>-7?tF+jCi*p$ +BPhU(E,p)DG^b*lIXlltIX63_FEMSDEGT<"@qB:`?t!GI=]ed/>$PBAASus\UU7ngj6#Uln+QYU +r:Bpkrr)iqs8Doorri5qqYU5Bs4dR(~> +JcFa0$3'htr;?Qnr;6 +JcF-t"TA8rrVl`p"oS5rrr<#trW)lqrVua7q!?nhah5*_Vkg)`VPU/dVlHo-]>;M5f&>uepAX^h +p@n@XqYU-bq#C0ip]1'fp*o\/q>C'UhU9H_^q6tVW2-5_SXuOLTq@pPWj97Xf]2JqqYL-dqu6Tp +qu6Nn!W;qJs3:Ro~> +JcFO*#6"Gqqtp?jrqccnqtpBkqu6ZprVnDFq"XUWo^V84iQo6CT9"_LDJEfp@p`ME>$G?FCN4ZZ +Q_LRf[^EKK['[7?[K3kKqRljAs1A?DrjjPe\@K2ZWgAWkH$!q9?<0s);c-S!?=IDVDg?ttTWu;_ +io]Oomdp5NrV$6krqHEnrVQTmJcFL)J,~> +JcFa0"oeDpr;?Qks8W)tr;ZclrrrE%rr2cnqu6j!p[7G0h>Z7:hq?Z:hW*njo'HAWrr)6a!<2Ti +&b"f=hV-Z>hr*DLi8iqUlLb&Nrseo'r;6Bequ$Bhr;-Elr;Qs"qtU!arqZQrrqu]nJcFp5J,~> +JcF!ps8Muq!;ucp$N0l$qt&q!ah+s[rLjRqUSb&r]Z8FQp%JC["o8&pqYL*gr;linrr*'!r;?Hg +q>C3grVR*(r;$-_qY^9krVH?brq@T'hTW^CZE:(,WMZGaTq\ +JcFO*#6"GrqYU6inc's7qt^$Wna,Dj_Q&uXHu3>#?s[>SCN+NNO-lTP]=bbd\@T>c^;'Z_$,OEo +`5KR3_ns:d`VmaQ`#nU'>\8;AT +JcF^/rr2Zls83&tqYL-frq6:$rT`1fdb*I7hV-cJn+ZeSs8W#sqZ-Wps8W)trrN-!rVcconbrRe +rr)j&rqu`nr;?NlrqQKsp\"%@k2cO$#isq!g=Y*9meHVX#QFZ#s8Murrql]uqt^'brdk+(s*t~> +JcFR+s8N&s"8r,rrqQKsrr)flr;6Kl)u0C$iQ\s8V5C5hV4sch\\lY_p%J(Np%eOarVlisrr2p% +rr)fprr;uqrrN-!nbrOer;Zfqs8E-!r;?Nmr[@[>p\+:Qo$Y^t\$)g.US+ +JcFI(rVcBg,lRW5na,AnhpB$4NI,PYBk(IO>%MVuLU+A"]">_p`lQb`5KX7a2lBG +bK\;Un]E`1`5Tj@aiDB=`Pod8`lH0@a2>[)\[A`FMgoe]>ujj% +JcF7"s83-!rr2imqYU6grseqdgZ.2IgXss'fB;Vrqu6ZpoDejhqu?]qqu?Kjrqu`l!<)`ns8E6& +rr;urr;H(QGio&M>h":CA!<.QLcMrC~> +JcFa0s8N#rs8;oo"8r,rrqQL&rqu]mr:]gFcEEt?Undpe$a$hYdba6\q"OU[r;6HprVZTlr;uur +rr)lsrr)fqrq-6hrX/W(rr)cnrVliqrql]rr;Q]qs8F2?rr2lno]b,X]sau`!~> +JcF^/s8DN3[^iu^^AYkN`5BR5`r3p\_ns=0a8X*Y`W+$Z +bQ#cdbPK?[aSa'[`l,jq`;[dXaN=G*.EffN`Poj8_SEq%^V@CgVj`WfCL:1F<`rg>Anc+4TY]@@ +n+$#BqYU0es8W&ms8W#tqu6Emqu)*GkPp&~> +JcF7"!ri,qq#:cleC3"-hVmJSlhCAVq>^Ko"T%ogq>C6kl2M:kqYU-dqYU-equ$?hqu-Kirr`9# +s8Muo$N0o$qYC!crr)iprr2fp%fQ4kiSE;Lk2YC\jP8AWlMgk`JcF[.J,~> +JcFa0!ri/rqYgHnq>V3/r;6 +JcF^/s8Dcnr;APNq"FFSo'bl(bcHA6A7/D8;,^qJM3OpK]u7n.a2Q!;aN)9=_o':)_Sa70`l?'= +a2Z*;`5V\prQ#u$aN)9?`Q,s<`Q6'?`lQ0Aa2Z-<`lH3Ba3)TJrlGMjb0%`B_o0R7`Q8"us2Z.s +\#GgUK5t=#='K$<@VBUtJZ-`Gi9'Fuq"t$grri;tqu-Kis8W&sqZ-SGs6'E4~> +JcG!7!<)os!<2lq%0$2&qu6WqrVuoqr;6El$iKVbhr!8Cf\Pf]rV6C#rqlNcp%A+Uqu$Bkqu?]q +!;uKhr;I0'rqucnrqucnrqucnrqcQerqH?grqQL%p[I>)jQZ$slKIL#q"k"&rVl]os8N&urr<#t +s8Dups8ITLjSs`~> +JcG!7!<)os!ri6"r;H]pr;Rl;s8W)urr;usqWQ>A[\BOlUo1N8cemsWq"ad`rr)ihrrN-!rVcs" +rr;rprqlZls8Duss8N)unGi%Xqu?Kks8Dus/,]5>q"!\"a0VY9T:MLCStr[2g$SV4qu6Wps8;lq +qYpHkrr)irrVucprdk+1s*t~> +JcG!7!<)os!<2cn-N*c;q"=FYq>^3VjPeh0VN64@ARf+YD1.;6W3WtF]Y;4u_oBd?rQGboaN2B@ +`P]U4`Q#p=b0'P$qo08i`l?!;`Q#m:`Q#m:`Q#m:aNXV-rQP5_!6FuYq90i'aM59p\@]>YWg8E[ +?rp<(9i"\pFHE]NiTp%2qu6`ps8Mlp!<%KKir=N~> +JcFm4%fZG+rr)inrqu]kqYL!dq>UQ[f$i=Oh?)p4rq$-or;69`p%S@\rqu]nqZ-QhrrW2tr;QTn +r:Bpfr;QTjr;6Kkr;?Q^rsSenkj@Qmi83/ +JcFm4#6+T#rr)ipp\u94qu$9^ilA3uVPU)aYeefImJ-_UqYgBiqY^ +JcFm41&h.Nrr)ios8W&rqYBgXp@Ih?m,?C&R!NLY?s?fHHB+W$]Z7t3aiDB<_Sa:1`lQ=%bl>i] +aSX-Xbl5c_a:lS7`l?!;`Q#m:`Q#m:`Q#m:aNXY.rQP8`r5\r^bfp(/rlk8^,fn$F`l?'A`kfO( +YG$r!@T-,u9iPG5FFUO9iT]e(q"t$iqu)*GgAc[~> +JcFs6s8Mus$i]trqYL*gqYBs^rr)j&qsik'f@nm9oBcMWrquctrquTkq#C-mqu$Hkqt'U`qssXb +rqcZorqZKkroX4ho]tGjh:p]AiSs.mr;Q^(rr;utrqH?fq"t'hJcFa0J,~> +JcFs6s8Mio!WE#qrttY3q<5u3Yc4:iX0KLom.'lLr;-*YrVuiqquZirrVc`qrrE&trVulms8DrV +s8)]rs8N#ns8;lnrVZTnq^MIBrr)ZjrVcZkqt\se\?Dj+T:r!X[_p_bp\aabrVuops8Vuqs8;lo +rr.KKkPp&~> +JcFs6s8Moq-iWu9p%\=ZrV6$Pho2.?G\gboAS-+GTrbc@aN;THdEg+^aiDEA`qm[S_[sf,aNDcR +cdC(bc-4>ScdC/>ci;8ibl5a!aNDTF`lQ0@`lQ0@`lQ0@`lQ0>`V[[NaSs?]aSs0\`P]Um_'[.F +c-4ATbf[rB^q[Us]"5DDNdGYQ=]SX1BRGrEb1YqCqYC*irdk+)s*t~> +JcG!7s8;rsrVm$"q=sjdqYpicdbE^CjlGP%qu6Zqr;QitrVl9c!W;ioq>^?lquZlpq#:$eq#C0g +qsXF_rql`orqZKkrq??lrr2irrqud"rqc?[oD&7`$N',Jjl5F^g=G*Hqu6j!q"ssdrdk+/s*t~> +JcG!7s8;rspAb0l%eoqpaJGZ)U7nEdcLCT&rVm0&r;?HjqYU3hrVlfprVliq"8r,rrqcWrrr;uV +s8)`cs8;itrVlfqr +JcG!7s8;rsqYq]:qY'RPn`K&iVgEAm@:3P[MQ!_]]XkksaNW#[eBQ1\rltJds2Y2[rPefS$cU-* +aND`Ocd0k\bl5`bc2Q&hc2Preb500gb/h`Hb/h`Hb/h`Hb/jFupr[_/YH^i7 +JcFg2s8<'"rql]lrs.Z@hqcf0jneoT"oA,pqtpUHoo)/C^rVZWns8W#rr;?Hh!VuTkr;Z^&s8;flqt^$]p\k'frsJJ_hq[)GhrikGoDJUjr:]XX +JcFa0J,~> +JcFg2s8Dut(B+:4rquuF#TqJ?[TuZX!rVlis +rUp3ir;HPEs5s?3~> +JcFg2s8Dut)Z9X8qX`RiUi^!PA7TM4U:S1R^VIOu`l?*BrQH/&b0%uScHXPWbfn5PaN2NKccs\V +aMu3<_u@XT`r='W`r3mT_[j`-b08#Pb08#Pb08#Pb09e+rlG)You6^G1!%VdcHXSTa2Z'9`Q63G +bfe8P`l>j(Y,mFu?s-Q3;dj6PQH.eEo)&Iequ?]pqtg8Bs6'E4~> +JcFm4s8Dcn#P6g&hVdGXo)&FeqYpKpr;HNlquH`qs8N#pr;Z`ss8N#q!<2fo"9/5qqu-Hmrq?@' +r;QWnr;QWnr;QWnr;QWkq>L3jr;Q]ms8N#sr;QTlq>^6iq#pWor;?Qnrs8T!qYU6ir;6EersA2Y +h;78PkgRiNJcFO*J,~> +JcFm4s8Dut'`S(.qtTL-[%X1aUp%esnbr@bqtL'hs8Mrr#QFc&rr)iqs8)]prVZZnrVuitrVlQk +r;Q`ps83E+rr;utrr;utrr;utrr;ujs82f^rrE&trrW/srVc`rrr2rtrr +JcFm4s8Dut)Z00sn`nf>NcAN/=(6TL[)0c(a26!Fc-"/Mr5o/`b/_TDrlY/_rQ>/d$I-f;`l5j3 +_8F10rPnZP!5n`R!QN4Ib5]Q]`r!aR`r*pSaq)\>aiMQDb/hWBaND`Nb/aM(s2Ptr_RQY-F(8*E +='BBLE2h:Fl1=]IqYpNoJcFm4J,~> +JcFm4!;u]n#4C=!e(EgTqu6m"r;Q`rqY^C6hs7uforr;fnrqlcnrVZ]poDejirqufn +')_b.s8N&ts8N&ts8N&ts8N&to)JUdq"tHtr;?QorVc`orVZZqr;QWrqtg0gq>C7!q!?klhWNtU +iUm$I!rVckJcFp5J,~> +JcFm4!;uir&GGqcftOJ]TVoEJiq33Ks8Dor"9/)ks8;fsrr<#trr;osrql`prqQNnrqlWor;?Nl +rql`Xrr)crrr)]mrr;rrs8W,ts8N6$rVlcorr3*"r;6Kkru(_0p\=[^p[["VWLoo`V4ONrg@=b2 +q>UEkJcFm4J,~> +JcFm4!;uir)"$.uYE![:?Y"A=TsVYSa2H!;b0A,K`m4S+!6>)Y!6>)Xs24uX`lJ%trl>)ZrPefV +rQ+lY!6G)XrQ+lYiQ2&Aqoo&^rQGPi`l#^5a2Q*?rl5;caiDB;`5]j=rlGqr`59L.] +MuWYQo)JUdqu6Zqqu6oucIq+.fB3&0rs8T$s8;ijq>:-ersSc$q"ad`rVcZlrVcQkrquZj!rW&s +pAb0l#Q4Jrq>'g]ro3tJrr +JcG!7,6%WBqu-H`i1m0MUS>-CnFHVWrVZQmqu?]qrr)iqq>1'hpAb0ln,NFe!<)fmrr)fpqu?Hj +!<;lo')hh.rr)iprr)iprr)fprVc`opAY*l"o\H#s8N&sr;uoqrr)isrVZ[5rVZQjrqQ6_n%YZp +TqJ'PU8m8Nqu6Wqrr2`nr;M9IpA]X~> +JcG`Jli/X:qXa7DhSXSXEFW6jLoISm_8X@3b/;<@`lH3EbK%]HbK7iE`Q#m:a2c3>`5KXl`WsK! +_8F73aN4A'rQGGibfIfF`r='Zb59B`b/jS%rl>Ab`P][7aN2B?rPnZS#fas,b08,Tbg$+1qoT8e +a2>j7`l?*Aa2e1u,K.UB_oB^8aj8>[d`fnU`lQ!0\upEb=]83t>%DiiiTg+5rUTsirVQQhrrE"L +s*t~> +N;j%[r;?Hhrqufqr;Zfrs8NW/s8W#mr;6?gq>UBnr;QWlrs&&Pgsj^'mJHq^rr^Hkr;-Bhr;HWnrrE&srr`3!rr2fm)ZKd8qZ$Noqu?NlrVufls8N#trr;ut +rr;urrr3T)rqufqs8;opr;HZms82iqs7QBis8N#pr;Zcnrs\c(s81m:k2kabf%9ZnrrrDuq>C6k +q#:Bmqu6Blqtu$F!<7Q~> +O8f:\s8M`lrr2oss8E0!rr;usrVm`5s8W)qs8Drpq=s0lW26AhZ-2A.rV6?jrVulrs8W)trVc`p +r;ZTl!W;iorsA]$s8W)urVulsrVcrur;HWnrr3'!rVufpr;R3)qu?Wpr;Z`qrVufmrr;rr"TA>u +rqucq%efo"s8N&rs8;fns8;opq>^0fs8N)uqu?Worr!]6pAFd<[&9aqV5Boce+W_;rVlisrr2rt +q>U$ds8IcQJ,~> +OoPI[oDejc!;lWm#Q=PrrVulsrqcX+q(qn_u%FRaSa3Ybl>ibaT'9[b5KE] +aplG2`lZ<@_90d:aMu?BrQ#Glc-OYU`5os?`l-!Ab5TWbaoof*b/D0rb6u5(]#2S:b/)3=`lA#! +rlQ"t_o0L7^<"ICbfe/RaMu9B_oTa;`Q.nrq8iKRrlFuZs2b5[&]iD@aM*gN=&Dan?=7iLcJeBo +r +NW9%X!;uins8;lqqu6Zqrr3'!rVl`m"9&5prVZ[#qV]uZhV@Ppqu6p!qtp`MJ,~> +O8f4Zo`#9ts8W)us8N#trr)Zm'D_P(rqQ?_h7KV^U85c_oDeger;?Qqrr;Hds8Vuq!W2lqrseu+ +r;Z`qs82cps8N#trr2rrs8N8us8N&urV6Blq[WZ*r;Z]ps8N&mqZ$Bks82fprrN,pr;R6*s82Zj +s8Duqs8DuqrSmhVrtGD1q=adUca]gBVl62_]BAh`q#1*i"oeJtqu$Hes8DqOs*t~> +OoPI[oD\mhqYg9j"9&8urVlg5rr;lprql9Ri4Y1j@p)uhT=DhW^r4=6rQ+uXqoJWV"N\a,`l@nu ++j%sPb/VB<`llEBaMl3Fb/hZDaND`Qc,n&Bb/h`Na2l@"b5]No_SOL@bga_M`PTa9aND38`r4!Y +ap-)5a1o4%aSs?lb0.iFaNhiJ`lZ0?_o1QU)9gOVbJC]uVLiM^:gR^>BSsmhm-F9 +NW9"WrqufqrVuoqr;R$$p\Xmdqu$Hgrs&#Rf\G?=nbW:crWiAur;?Qns8V9]#ljo&r;Q`rqu-No +!W;ijrWN0!rr;cmr:p9krs\l's7lWmp&Fsis8DunrX&W"qu?]ps7uNgrr2rt#l=T$rVufqrVtjU +"T&&rrqcQm#kd!1kNM*hg\:[H$hsMnq>:0ks8Dlnrdk+Fs*t~> +JcG]K!<2ut+8c';s8Dlps8N#ts8MulkJF:*grr)lqrq$-irr2rnrrU-frr2ourqu`pqYgNqrr2ir +reLN(~> +M#[GPqu?Zos8N)urr;uq)?'C,qtp0YiQ%1)?XdhpRDZ_P^VI_)`Q6.!b5]QR`W4*Z`qd\!ai;9: +`lZEA`5K^;aN;ZKaMub/MQE +`lH6Ebg4YXcHaVXb0.oMrQ+`QnAlHd_8474^W"7)_R>M@@U<5CAS[XPiTp:3p&>$hrqZWnJcGcM +J,~> +NW9"Wq#CBk!<2or"9/5prV6BsrTDblhW"D,s8W'%rVZQjr;QZplM_=orVQNkrVlijs8W&trqHHg +rWiK!s8Dlqq>^9i&,c,#p](*dqt^9fs8;`hs7uWtqZ$Tnqt^3j%K?8%rr;onr;?Qmrr2rWrr1*ir;;-Gq#>j~> +JcG`Lrr2lrs8Er:rr2lpq"amai5)7hU8Z0"q>'pdqtg3erVl`p"TJAurr2Bdrr2os#QFZ"rr2rt +pAFpnp](3krr2rtrW`Dus82Wlq#(0jrX\r"s7cQhq"XU`q#C9hqZ$Bj"oA9!r;6rr<#srr)lsrr2lmrr;osreLN(~> +M>mSSrVQWnr;Zcn!<)co)#Emklg!EDP\k, +OoPCZp&G'i!<2`m!W)`mrs&>Rf%f'AqYU9mrVccrqulurr;Q]ns6BU`r<<3#s8Dilrr3,trVuio +q>LWos8;H=\D[2Yrr +K`D&NrVmo;s8N#trVlfrq>:0cr:ndBTV\Qoe*Q`)s8W&prql`orr2lrrq?Bjrr)lsrr<#urr2p! +rqlTlrs/H$s8DlorVl`p#Pe>pmaAN"q>L?lrr +MuNkWqtp?gs82`o!WDlnp_`l-s8N&sl/U?mF^efgEKI61_TBp<^r+7laoK]abl>icaSs3V`W*sV +a:-)-`Q$!?`l>s8`Q#ps`>m7M`kT=1ai_lQb/VE>`l>sHf$Usm[Dg%u_8XLpaq2kEb0SCgH%:@/ +e&]bKccF9,aT'7!b07oKf%&7!cH4;XcGd]CaN;WJbK%]Db0%fHrPnfTrPnEL)oft:_oU'HcH45L +_Rd.aV1N8b +OoGO_r;Q]_rrDumrrqZ6f\#0YrVmH-rqQUEm%K?:=-7:#^.aRefrV??drYPG2s8Mfjnb`+]q"jpgrr)clrql]ms8V*X +qu6s#qu$Kks8Vonrr39$kMb=]lJ^dsrVuosqYpQprVQZpKE$H~> +LAq8Qrr;oqrr3*"p\t0kr>#8%n&D6&UT;H'q"a^_rqlQks8W#prr2usrVlcorr2coqu6Qorr)ru +rVlisrr:3krVZTmr;QWos8;lis7-(8q>LC9jp!gILStMgKWQ=B$r;?Tprr)fp +rr;unrrE%Qs*t~> +N;itXqtpBhrVQKl,lRT7nbDtVp\=IDd[YDq@:Ob`\%KJoaMbp5bJqE;aihoNc-?73rQ>/]qSrQV +s2lt`lQa3)R'aT'6d_TC0Rdauamcd_s;%+EA>`l#m8aMuHMb0'_)rPniUrPn?J*mDmPaN)?@ +a25g6\\#_iZ]As-:/Y8'H`# +OoPI\p&>$kr;Zcqq>UWff%\j5lMLScr;-M31oDeWQ8gmPPO.jSNqXXOYq>^Enqu-ENrW<-!qu6U% +rr;umq>^Kkq>U?m#Nab'lf$mgpAY'pqYU*drquctrquZmquH_Ns*t~> +O8f4Zrr3*"s8N#prr`5trVl]o%fQ+tqW#MhW2Qu>m/I"XqYpQprVuos!<;HcrVZ`qrr<#t!WE#s +s8W!&s8DZgrUTsfpAY*jrr2p%q2Z[>++Eq]s8N#trso&'rCnCV)AaT1qu$Kms8N!!s8N#srtb5+ +p6.rk:2#TX_qb%Vq=j[arVucnqtg +NW0+Zqtp6hqtg9grt55,pZgnu_3\nLBQAj3`5TF2rlYYmcHaDMbg+GUbg$+1rQ>,`s2t8\A]i6A +c-OYU`l5s?bg";L`PfX5bK7cRf?;Ug_TKm_nrmnZ?K\^>>A=>Q,2POq#13mrVcTnrIOtKs*t~> +L&V8Sr;?QmrrW2trql^!k185>jnSiT#la`"qYBpbq=ag_"o7riqu?]TrX\u,rVZ]qm+//+BU/,f +rVZKj#PUk=)CO,1s7uX)qu?PM,:4EZ,Tn;Js8)cmq>M3-s8Jf@-QjQS-lk#g,V3M]RD%8Eq#C +OoPI\r;Zfr!WW/srr`9!rr2lr')qe+qr58dV5:QFnbN4^qu?]prr2usqu6`ss8VKcrVZits8W)r +r=K#.rVul`eY\^EP4/GLrVuorrWrQ'oL9u<,1?2`s8N#trt##,pk9b4(aC%=*5;ILs82fp!WW/u +rtkV5r1G2W*$#tD)(ZmP-X_Ok]%-?Frr)NhrVuEe"T8<"rVcWn'`7q1rVu]np@nCR]VM +NW9%U"8_olrVQWprVQU5q=*V(]SpiE@;h.4^rja?cHXMRbf[uJaN2O'aTB`2bl,]`aSsE[b5]]c +c!erCb/VHBc-aqba2>j6cd',"KmcO6aOA2G_o9dBbfI]Cd4c.8%^jI%_nj@8bf[rE`RELV#R^\F +'+YMHe&K\Pbf\#HaMu6=_U6nd%M&XC!"/cB$4.;:Bm?,Qb0//Tq9&ZWrPnELs2lk=cH"#Ja2uEI +a2?'CaN;6?]Y;1iH!40G;HS"2bNes(rVQKgqY9p`qu-JGs*t~> +L]7b]qtg-apA+U`s8VomrrqK:*hqZ$Tpr;QuVi8!>Ih=LRE!;QBi!WMtNs*t~> +OT5@[r;Qlus8W)trttb8s8Dusq#:*aqV8EUVl-cRmeZhWs8W)rs8N#rs8W'&rVlipqu-Nns#L&X +qtpEnrr<#qs8;iqq#C9is8;olpA=mfs8Mrroe.=1*$MQcq>^Kks8DusrVXDT)Bh]Kq#:#Xs"N#8GN2_s8N&u!<2ut0)keD;]-Yr+X%mI*ZZ+9)]0S;+!aLOo)/OdrVu]nr;HZo +s8Dutqu$EmrVHNlqYgNorqHEorr)for;Za/s8Munpt2XFTVnN]`UNa#rVu]mrs&H%s82irrJ(?&~> +NrK7\qtg3eo`#^*s7Y^5Y^:(qA8e'F_8O@cd9nMaN)]9&e#%. +PnON=2:p0ra3;cI`lQ3@`kogI4Ui&.#R_"N'GhQ(*Z5n5'+m!Obfn8PaV)n>dEKeYaih`FbJM9> +c,[cDa83mWa8X0Tb500o`l5d,[Zb<2>%;#RPLA[[o(_kUqtg +M#ReYq>C-cq=sUXp\b$prRKN[e`co1#5\5nq>:*hr;Qlur;Q]ks8Mm*q#:9mrqufqr;-?kq>^Hm +s"O?Ed[k*.oDejgs7lWH-R9iR/Dp=%r;Zfrq#C0fIO$*\V#LDlr;Zcrp&G'grqB4f-OJ&k9.V/5 +Qi-g^qu6Qo/b1P@+"P=VXbLL\/0Q>i+!`'U+ +OoPI\qZ$Tnr;RK0s82iqr:9^;WM?Vl_"%9nrVulpqu?]qs8<#us8W)trr!N.rVuosrr;utrr;uq +s8Mrmr;ZTirtYG)d$nO"o)Jafs7cQF,9@a:-JS@prr4JHp]('dGo[kEU&=rhr;Z`qo`+sgrq/l+ ++X5&!7OArqP5>.Wrr2rtrr2lr/ak/1(ad)BWI\PH,oIaJ(EFJ9)B=J/qZ$HkqtU$frquZnqZ$To +r;?Qos82imrqHEprr)fnrqc`prqud4rqcBW]VD3qUSjpTq>C6er;Z]nrr2clL&ZZ~> +O8fC^qtg0drV-=0rr)]cjQ!^qBl%.$X1>g^c-+8Rc-"2M`l@tr!64lV"38F(ao98._T'[@aMuBD +`l,m@_o]p>b0eJS`i=DWA\ua8aOJD]WsTCN$PpIu_7[_0c-+SRcXmn%#(k=O`5^*IdDX>P_9C4a +()7@]eM7sQ(OX`UaiqoI`Q6-@`l6-H(D[PnUoo_n:c07/*$>q3'G1ZYB[4Q@aj&)ScI:.aaj.j) +`WsQ(`lQEI`QI_lpr`QV)TKb4]t(7i>Zas0DgKO^m.BoDqtKj[qY0jbLAuc~> +MZ<_Us83-!qYBs]q>'sersmoEjON;js82irrr)`krq??lrqQLkrqQEjqu?3brVuZks8Voos8)Tl +p%SLa^aUNP:](1irr<#rrjO6r.3M=\r;Zfkrr;fopb*g5/bJu;r;ZZoq>^Kgs8/-3+W>Y"rjO-k ++tWK_r\40Gi@#Wf/bo)8r;Z`di7"<[Al9ft,:<0`s8%;3bkq>3s82]ns8)corVucps8;lprVuls +quciorr2cos8N&rs8E9'rr2ikq>L-grs%uRl1!frgAV$RrVliqK)^?~> +OoPI\q#;$,rVuors8N&rq"`UL?nq>^Klr;ZKbs89VY*umrLs8;lrrVZW#+Vu:>8,3#^s7cKlq#C%:)At!pqtg9kqu6Bjs7cQi +PTq([FS#F:*toS?oDS[fs8W,us8OeLr8&V2)(>1Op\XsfnD;N^N+,L%*ZZHurr;eEPKN^to`+db +s8VurrVccns8W#rrVccq"onT%s8N&krW3&uqu7K/rr22qU7IpATr$E6qu6QorqucorVZYMs*t~> +O8f@]qtg0dqYq`;q>:$gp$(;8CLC[^J\/n/`6?QPbK7cE`5BF/_o9X:aS<[+t*ErVQTp +rJ(?&~> +N;rnVs8;orqu6p!s8UO+i8OM2rrW0!q#:'hr9XFgrr)flr;QTlrr39!s82fpr;Z]mrVn)=s5kLP +-R8!Ss8Vfms7lSA-6O?VCA@Q"s8Vimrj*ji-\;9s)#jI5rVuljs8:q!+!N*$rVlLc.3TpsqYU-g +#lXf$dN^.bAbZ3(,l.B\nl/gbeLq>:3drVuirs8Mijs7uZns8Dlpq#:Qt +r;?Hhr;Q]q"oeDon+lkZrs%uZq=*G%g\h*OrW2opL&ZZ~> +OoPI\q>UHoqYpoor9U5UTVKHns8Dors8Dutr;Q]os82rsrr2fn!WW,trr2otrr2p'q#C6jrqufp +rVca?qu>b!+X%olq>^Kes8VlkGTRe>+D1?Aqu?]ir;<`='I&#*ruD%9s8DuspAb$L)AsJ;lMLMN +8g5,mMYR)Jrr<#srWiK$c5duH@J0X",l7K>s7lKgoBIJ?(F&bVq>\hh.jK/@p\Fj`rVuirs8Mij +s7uZns8Dlp"o\H!rr)forW3&urVulrrr3Q-s8MronCOt;V4jHUXR>f[rVlils8IfRJ,~> +O8f@]qtg3gqu7N3q"F@OioJ4&B3ADeYf=]+c,n2Pb/hT?rP8]U`Q$!AaN44tE66);`5BR7`5Kj> +cc"5Qbfn5R`50@2`6l]N\H*0T$cL05ccan_`nFr<'+kjKc,7EAe&p.gOqeQ>?.$d:aN2WLd*0AU +c+F&d',B$Ie'Kfd()1r>aiqiF`Q63C`Q63,&Khi[cHaYS^r+76^W6>u&IT-Z%aE#4dAR$P"BCQ2 +d+628`s0`/aMYs=_u@aWa8X0ZapuM4`Poa4`Q$!Abg"AQ`r +N;rqW"8r/qqYC-oq:Oc\o_nghp]C-erqcWsrqu]np&A(irVuoqr;6ElqYC0cqY9a]s8)cooDeag +rVfS:+XFMms8N&qrr;ro>9kI<-'J<-s7--hnm*:a-,]WYp&G$kr;ZTlrUj>?,q5AXs82i!+se9X +m/Qq]0E(_HSg5:%J,fQHqYgElrVuoqs6M$X)CtLXs7?2?+WVj[eG]4Cr;ZTmr;Q`rr;HZnrql`m +rr)lnrWE)us7cEj#3=e+mG[?prr3,tr;?TlLAuc~> +OoGI\rqcX1r;$F6)s8N&rs7uZl +nl?hS,F7p#qZ!T9*Z$!as8Drss8Dp)qZ!!)'-;N!s82Zlr;Rf8s6(RH&LI)Is76&9*>p"KdJN_= +r;ZTmr;Q`rr;HZbrWW9"rVc`pq>V3'qY^-dnC4G0St_XQ\)[5^qu?]pq1ep"~> +O8f@]qtg3gr;Rl9nE]H'iQ[Tp@pt;/_TL'Caih]G`Q#j4^;%P(aNDa+b503Z`dc%G`QH9?`5BU= +aN2oUdEg%adE'GH[`->6ajDjR&eL/JcHXkaaN`)`5S+YD&TuaNcb%WYbX)m[$Cf/V^Wk!K`ll9D +d*Fic',QDTfZ_m'%N#ckb1"VV_o'R>@jh:Mbd(jnerU!;qTOJ +,~> +NrT+Xs82lqq>UTkf[e[Grr36"q"jsgs8W)prrE&tqZ6Worr3#us8;k1s8;osrr)lsqY^Biqn[t\ +/Sj,;s7QEgpAam^Jg;TdK)GQCs8W#lrquX?*[;[M^]+31s8211,UZ=_r;?Tos8;ijs8Vhc+=8F% +q>^9jq#=,6-6[$rrVc`ps8N#rrqqg%-RGG[r;QQm*r#W\,U4gCqZ$Els7R]i+X(Lkrr)lps8Dup +p](9grr2rtrr2lrs8Mups8Mrrqu-g"qZ$Qps8;fp#3=n3jPn_\Jc>`MJ,~> +OoPI\qu?]q&cMM&rVcKZe>].:`:NX"r;?Qirri?"rVulrs7ZFqs8Muss8Mrrs7uQlq"VOR8L\?* +q#C$eqtC'apO+&%*.Rk`qZ$Toq>U9d+Vu(4*4u.Irr;i[+WV[sq#(*jrr;oqq>^KfRi3@k4S8[K +s7cLb)]fo-p&+ggs8N!(s87cp*ZgmGqu-Bk*r#QW*uuV,q>^ +O8f4Yrqc]orVn);oBkbpbboGf>(!Qb`lcEHc-F\_`l#a3_8+"0b08,Tbf]_%s2K<%a3)KAbKe5S +f$`0CAhFK`[Em@=c,.?F_96I))%p9#b/i5__nF.9eI)g'&e^qiai)HLb75=*0$hVWdEKtY`4aFE +c[lQ?'J/,$bgFJ_2A7#@9$YZ"_8FC=b/M9@E"jH4I`TdYcHF;H_SX=1d]Wrf*^[uj'u\MPe-?Zo +#Y<@lbg+/Qa32H-53`mDoOd)s&)O]tOU:L.b1f'W82K`?Q~> +NrT.Ys82osp\XsnqpjNRkPbDcq#CBns8Vuorr!-!q>:-hqtp^-es8W&t\fDn=;#((hq#CBnrqlHN-R:#]-0"b#qu;O!)C_*Ms8)ZkqZ$Knr:oM( +,9e;Arp]s`s7WW@+!E,[r;?Qns8W)ts8-=R(bWZ#qZ$TmqYpNkrr3bI-"pbPq>^?hs88r<+:*is6S7pjQP=VrVllrLAuc~> +OoPI\qu6]jrVcX$n_9e8W5SK*s8W#qrs/Q!qY^?lrVlZns8E0$rr2rsqu7o?s8Dfnrq?B^^j."J +(`sY9:&Xhdo`"mjrVs8@(EH6Es8D]jrtG>(i?90\(EVH/s8;nO*YTcaq#C?j)>X=3s8D]R+WMC> +[/04iq>^,g*>]V?bkqA;s8W'Is8-1G%k#*eqZ$TmqYpNks8W)1,%Y)Dq>^?gs7iK-)Ajp7o)8Ue +rUp-h$24Drr;HWprr2llrr<#irr +NrL^0qtp?lqu?]kn*&9,BkD1=^V@n4_90p>aN2BA`5KX7aNVrTbfn5PaN2BBaSX+\aN;NFa2cb/hNC7i)d]S]Aanb/M'U!i)p +r.b6%~> +PQ1[^s8N)urqlfor;?R(nBoD6mf*7drV6-dq"ssg$3'o"q>1!`qu$BkrqH=pqu-Nls8VZ@Ijcin +,9n0Q+sSDIrVlisrql`nk:Ru$,jbF.r;ZNks82ikZ7-h>,$XmCr:ru3-7/!Xqu?Zqs8N#tq=neL +,9S.JS=Q+=QCsZi-6"16qu$Elrr4hSqu'&3,pLb:s8Dors8;iqs82Zmq"t*erVucprqZ@q,UXX* +r;ZTmrr;oirjHjWq"ajdrr)orq>UElqu6Wqs8Mup(&e12rV6Elq=O^Yrr<#shrX1fgY_u%s8N#q +s8Dqfs*t~> +ScAZfq>UHoqYq!'q=jaVd'07D]A!&UrVuoq"TSK!rVZZp!<2ips8Moq!<2rs>5eL"qu$K]dWm&b +*ZZ7:*#fk>\GH.&s8Moqqr9%B(a//As8;ols8W#spT>_U)B2`Ps8;U\*ZlKfrql`prr;uts7uA& +)B0M4C7(HWRZsD/)]fY5=8MmprVn_Rr;8o'*#m6(s8N#ts8Dors8)Qkp\Fd_rr;orr:]bb*[)@h +q>^9jrr;ohrO$URp\=Xarr)orq>UEooDSmks8Donrr3N,s8)cpr7A$GUnF6[gACjHs8N#trrE%\ +s*t~> +U&Y,jp](9lr;QcqrVmu6n*&?&LMppQT#&ImbK%]=^rFI;b/qcJbKJ/VccjW4ap?).`PojbPccX5QM+ +U&Y/lp](9ms830$s8MrnqYBsdrr3,RhUUN^rVuoss82cos8R';s7ZKir;?BgrVQWoq>C9fs7u]o +qZ$Hmqu?B`jH*7a+sS?Z+!XT-,Te=Rq>^kh:C]IgZ/>6 +r;6?j#la\tr;Z`qs8Mup!<2lqs8JnqJ,~> +Sc8cjrVZZn!<2or!<2lqs83?%o]r^Kns8MusrVcP@*Z5t +p&+XcrVucms8)Vj+;u1:*?Z7C*?cRK)'fq2*?_ihrr2p(o`+p`,9@OCpAXsh.K9AHs82ios7lQm +r;Zfms7Xb_'c\E`p&G!jqt&0F,9S$T=h4J0qu?Wbrq69qrr<#tr;?Qnru(e2`iGT)URnLLrr)`o +s82cnr;Q]orr<#rq>UNqs8J_lJ,~> +UAkApqtg3gq>UHnrqc`lrVQU'rU/=RCMII/X1ZEk`;RXVaNDa+c"P>G`mW)UbJqTEajA>R`Pf@( +^sUEHb.u'Ah:^Q)FZKsD'GV;e#W3)0'c:6.e]?%Z`l6!I3>`J>[a32WKbJV9?>n.G_&7j>E +UC[qK?eX)UcH"&D`m;lZM@9t0()If!&e,?M%7D0L'cn'OaMl6?ah,gAcPIQ9'Ze/2aMu'5^V\(2 +bK%lMd`TbW_SjF6f[[>="V_f+f#ttRai^_W%h/jU4Hn.;a2u9uaSF!WaS!RQa;<"Cc-4DS`kf +U&Y/lpAYEtr;Q`qrV6^Kms5k^P*[^d_r;HKis8VumrqQEks7cQlrqcZp +qZ$TcK.A&b./s)@p\ojq*ZcRO-+ +Sc8]hrr)iqqu6`ss7uZo')VLi\tc$th=L@>s8Musrr)iqrr)iqs8N6#r;ZZnrr3)qp]('es!%@> +rr;ijfo&3;*Z-(B,U$s6r9KRg)&"=mrVu]ks8N&nHN"lbK_tcJ'`\+2rVZ]mq-4sW+'s^r.643(`j\?ZN'\!s7lW^rqQNmrWE,sr;HWp)ZK[)p +U&Y/k!rMrpqYpQorVHZorql]p')(P4MJ-I-RBscUc,R]>`Pop@rltJes2o6)bKA)J_oKjIbfeDN +_7dS%c-=DL`PL!:GVfd;$l0Hk'3CXUb'k0I&K09JahYp;^W=f5)&`urai)-:c-4SY_SjF<57S,<% +$B1W&JPbPf@nWq`PfmFajS6@%2BHj$l0Hi&J5Zd%1a-n&J75Wbg"2GaiMEH_A=%'&B_l0ahks6_ +nNn*_T'jF`RN)P_SjF3d+?HM&ePZkj3,Nbemf*o$5*dTQ.a@+c+h +UAk;or;QZp"T/#lr;QWo!WDomrri5PgYD&js8W&trrE#ss8;kFqZ$Hfrr)]kq"adbrr2]krr)ls +qYpMs9.2,6+sA0U>.F/'p&>!U,q'f^Zhj_%r;ZTmqmmso,>@t5rr<#tqu?]mrVu@7+t"EUc6a_\ +:&aqfs8DurqZ$NoDB(#GB?SlSP,"VguRMKrVlruqYpBl!<2ut +rVlZns8JnqJ,~> +TE"rjq#C?m&,lD)rVlcdpVrc#Yg<@Bp\t3mr;ZcsrVlisrqud"rql`qrVuln%K6>,qu?]qs8Vrp +s/eik,QAi++X1!rnG`+[roP7D(*TpYs8W&tqZ$B")]0Sdq>UBn5Q:Q[s82cpm3)]hTK +p\t3ls8Mlpqu1:F+;eS.da!lFR[9;)SnDCL*uu_op\t-jrr;`?*?H/2o_ne;r;6?is8MrrqY9se +p](-js8;cos8!QW)&7\pqPGM[(*FhAT)JK^rVuHf!<;opqZ$Tprr3#urVl[*r;ZZfm(f +T)\fgr;ZfqrVllrrVmAifT]`SF-aeS\]E":`l.ksrl]3%aMu6=^W=C2b/_HAaNi;gf?qIP^V\:E +aN2DK-Ogb($j[1E2NZ&/_8t!D'He))O3#D]`6,g9d%(md&M;8K`lH?Ja32ZCaj\H@$kisX]G)"j +/ChqhcGdiB`6Zlf;[=3M9WGS.F+esfG^)W/;+qE6&JKE=e]l7T`l"hf)]2SrajA\ibfRlGccXDX +bf\2U`QQ6>a2lHRf[Km7%h!7(e;FnL"qV=JJ(Mlcb/hWDo#LjOaSj9]aSNpUa8sH)rlQD*`l6!2 +ZDMkL<*<[E[,'d;rVuorrVZWms8DutqtTmYqtpBqrVHBhVuM8~> +UAt5ls8N9%qt^$arql]sqZ$Hkrs8,Ni7S)0rVuosrW)orrrW,us8Drss#U&Os8Vlnq=M(3BVbA% +qtpEgs8W#sqN<-L*$$A-WTa0TrVQWmr;'PD+XD=-q>UBnqZ$HT.ioo_kPkL$rr;rsq>^Hopuj+I +,pjT_*@.6Vr;6Nls8Dros10L"*A$XXqZ$TepAFgbr;62%-QjHYlMghYs8;o"*??MJp&FmcqYgHo +rqcZpnPcUbq>^Kor;Q`pqu->m+"S]_ZW/7n,9n^]l21ARs8Viks81gT"8qrirqucrr;HX"p#Y8t +lJUt,rrW/srr2rtrqufrrqQKnrhf^G~> +U&Y,kq#C?m&H2A%pA+R[k.RLdXn_Ses8W)s"T85us8;Zl/c>YKqu?Qe[V]WNp&G!is7u]pr;ZVU ++W_I<,Z^o.q"t$es8Dlj;]ckuFnbb3rs8N%qVie;*$XMDs)J&'m^nmip_(aJ2?s7lWms/[%Q+)LQKq>0pbs8W)prr;FaXS)Ag +s8Muss8Dflpo>>\*Z_C[*Z5q<-?82Dqtg?mq#16ioDSaipAXmf(&n..qYU3es8)cgcEa:;T:`^R +p&=shrrW,pr;Q]mrri?"r;HVis*t~> +RK!9crqlZo?iL*'qXipdL0Rtt]YDJ0aMc'<`lcNKaNM]F`l5j6_S*P&bJqiMa,WeeM:U>&`Q#[; +dE9YPAHWAL%1bFR_TL!D`Po[7dR>,k&6-]c_8aU3aNhaB&J>Sgc,n&Nb\tJ@_9pNUcbp1q',M0$% +LdO-aMl08`l,s@esHjV&/`R;cdgXgc-t+heCW;I%LNOSbLk=abeqSW"V;Y[bg4JXc-Y%jbfJ)Za +=Dtgb0\JW`5^$Eb0J.`!Z2[bQoYch&e>XV_pHNA`PfF,bf01p!li=(rQP;arlFuVrQ,#]'$/)/_ +mmCcMf<')>\/f,h=1.5rqZZjp\k*qqY'RRpA4[ds8)fpVuM8~> +T`55qr;6us8)`p$LZs5gA1dKrr;loqu6]rrVZXFs8Dors7l +QN$sarr3Z2qX4:Xo":cnX5*aTrVu`lrr<#srW2usq#=.eq#BlR-mKl],$"@7s8W)rpAb'eg*RgV +,HgY6rVlcps8Dusqj/3>)_CX]rVlirs8;[a*#T[)r;Q]mrr;onrql`nm^=DV(`jJ)-KY1)rso&. +rr;rj-lsEPOn\hRoD\b\rr;lqq"*en*Z65Np\Y!gs8A3/)Ant4o`"miqu$Eks8)W=,pFCqp\k-j +rVuorrquRo(E=A:+!;IB=2sk-s8DusrVuoos7uZjs8W)srVHNirrE&srVca/q#']oTq@sJT#UR) +s8Moqs8;fhrrE&tr;chms*t~> +S,WZjqY9dZqu$J>q#0U+LL""nR`3:bb/D<=a2lHKc-4AR`l5j3_SX++`l,pLbBXF'&/c-FeBlCZ +`6-0Lb0%%"%h9GCdEg+bcd'nTa3)na%LraPaOA2N`l,pAei"-S%\(hf`Q-'>]uA:AeBZ$u$k!gm +'a>5[_oKa6_Sa=;cd,Vu#S%VubJ_K:dE^(^cHF_`d*)Os%2`d2da,eJa(u>#(6Qtbb0/)Vd*Kn[ +b0mEu!s!&Uc-=;LcHjVR`lU4D()Rf#(_RENXjG><_8UEkqYp?pqY'XXqk3t>~> +TDo#jq"X[]rrN,sr;R)PjPBS1rVQ3drVQWprr<#urVukGs8Mroq"F^\Ppdmq+^0gqu? +P5c'lp\FXDU9(34p@nUbs8;fnrs&H"r;Q`prql_&qt^9cPU7Oh*#]J,.:W;Vs8N&os8;or8/iZb +JGo +UAk;nqYU6k"oJ)gpA4ads*=V=l+gtA;L#FXaMlBAaj%iEaND`NcHaPN_nj:/_o9L2e'`CM%L3X_ +&.oaKeBZ(Qd)jSUdF^2b)@1-5b0/&Rcc3uOeA=6a%L<-da3VrJa2Zce6W@j&dc4rb/V< +TDo#jp\Fgds8W)rrr_TEin+20"8_clqu-Nprr)fqrrN)trr"_OqYC']Qn'C"+s\0O-7'BPbP(l3 +s8Vrps72'r*?c^%s8;ols8Vo&E@E4W*@>Ons8W)urr2gD\g&CE:%\Jbs8Mumrr<#qrVQWcCa1&E ++i=$Squ?Wpqu?Wps7H-9l2LKQrVZ]ns8;iqrV6Edl>(-D/T(Faqu-?G,:+?S,:"N^-SJ)/N1\GC +RjfF)Pl1O\s8MomrVucppJ)\Q+X`fSs7cQjpAb*kqYpNko`*qMrr3H,q=jRVq>^Ens8Murr;Q^" +hqd_]i9gOD"S; +U&P,lr;Qcrrr)cp&H;Uh];2F*p\Opir;ZWks7uWls82rts8Dor+TD<9rUcC(*u,e<(E+A;&L,Ho +r;?TpqYpNaLE[QU+nbj7)YsF5p9ABX*uPkU'es8N#r! +UAk;lo_/7`"8_`frVlg5rVQ +TDnulqu$Bls8Mus%dVBkk4&ENq"FU_qZ$Torr6g6s8W)sr;Q]orVZQgpR@D,9Xr$q"F^$E[i4Y+X80[D#"&0qtpEks8N&[.3]c]mJd%`qu?Zpr:g6krr;ll +;'dbjr;ZWnrr2rqrr;ipqu?Wn;#gOpqZ$Hgs8;oorVuZmrqlHip%n^er;Zfn_HAN:.O$,c+s%pT +,U+Ng+^Hnrr`)f +q>C6l#5?p6nDE*jrr3)trr2ioqZ6WoT)X<~> +U&P,lr;Zcp!<2ut#lX]!e#]@L_=[[*=o/0spAb0lrr;urr;?Qns8W)rqY-C'*>BJ4*#9P/)AO;6 +D#+#/qu-QnrVt[u'cnC4qtg$b]P]#6*Z?"<,\ZlLr;-U6jrr2rqrr;ipqu?Tls8N&ps82Wlr;ZZms7cQkq=OXWq>^Hns8Vl.;^`Y4*ZuXG()e8: +*?ZgL(`":)q>^BkrVm`6s7b4h*#BRJqYU6kqu?WorVuosqZ$Toqu66fp\t3m!ri/sqYpWls7uWn% +fQG*n]RVqUn"F/pAb0joDedgVuM8~> +UAk>mo_/7_rrW/rrVlh?qt014Xa+DiH*5!(aN_oLdETPM`l?*EcHXSUaN2KHc-XnhJ.iM)(`4,+ +*uH.9'*q.Ob0@uIaiDNQ^^pnk%]Rq!_TeBD&eGlo'Fk[Idalmka32QIaNqU2'bV8*cc42H`P]j@ +`QlKBaj/R!%hpeMd`Bf7b$2m,ai)EDccjVZaN_ZHa2Q?Db/MKMak,(ldFZOab/1p6bL*.T*YAtd +"UktV(DdJb$lTcp%M"iMe&oVL`P]U1aiV:0)ANk&dDsGVajJ5QaiV`I`66HJb0'\(p;R0Q`lS/% +rlkDb"3AL%`W!jsaNDZLbg+;Wa32K?aMZ$6Z@l4O=BK^IjRi<@q>($nrVH +SGrckqtpBmrr)j'nC#kCq#CBns8W)r!<2rs55PU?kqu$HiqXg=(,pFBN,9%pR@j<-A)(6cT +qtg?mrVlcppJ;nS,C9(%L+">o*[)UL,)=M:s82`nrr3E*r;ZOc+X8>>rr;rsq>LX!rqYa0kkk50 +rr;p3r;6$;\tjsh/g_Jj,U4K[+as8DlqqZ$Nos82cps8;NgrVZ]p +s8NZ0r;6 +T`5/orVlcorVomss8;`L_5=HPiVr`Hs8;lqs8W)srVu`os7uZmrVlisqtfoR+X%jD(`jG9+($'/ +*YftFc2.;:s8N&trq/r'*$9Ct`.B6W*u>h4*$'[Uo)JR`rVlisrrr)lr +rr2lkrqud)rr)lns8Dutr;Q`rr:p6ks8N#rs8W)ur;ciprt550s7tEZTU_UL]BoFos7uZlrr2ur +qZ$TpVZ2/~> +T`5,kp\=[art58,n`.';ASHI]]tqJ1cd0hVrl,/`ai)HJa3+D'>KY:cSH%H(1u0mAIAqZ%hoQd$"g0[e]c:_cH48O`6?IX&/Gn@ccO5LaN2NHaMu3< +aj&2M[`6kDccs_Ybl5cbaSa$ZaND[(bQ,faa=#-ScdC(`bfn5L_nj=8dba2uH=`6$'>aSX-[ +a8j6YaSO'ZaT'6k`Pf[:c,-&j;GL8+Nm?_SqYgEorVZZtqtTs`V#Pr~> +UAk8np\b$mq=XI[rs.]AfAci1r:p3is8;ip:\t+fs8N&uqZ$3cnX_3J,p+!K+WE#&p@k%!*$ZCH +BDql-rVuoqrr'#D+rVmQ+!;UQ*?c^R+JIcjr;HQnrV63ds8MroKI.ocL&1iKqtU0irr`&ns8CXM +(]XI3rr<#oo_/7Wq:`i[NbD-5.S@JUr;$ +U&Q&.s8Doqs8W#ms8Mum_5a<@li6\Ps8VrmrVl`p:\t+fs8N&uqZ$9fnXV$C+W;%8*#C)np%=[l +(EOA7B)DW*rr<#srqri=*YftA*?#b=()e56)P#XXqYU0irV63ds8W#oJKPsOJbf?Fqu-NmrrE&t +rri)ms8;ijrql`orW)orrr)lprW<-!rqud5r;- +U&P8ps8)Nfrr6g6rU]7-QZZeST>%hKbfn2Rc-48J_o9X6cGn/Nb0S)Sa4&:a'F,Hj&K)>l(Ojuk +Kb4n6%M27\bf.N>`PKXBN=?U7*!urY$l06c(`!U;^spi]c-aYO`Q6`s2Y2[rP\fWb5TUPc-4>O`l5s;aND`NaMuBF`l#^6c-Xtmf[e?e`R*,i +^SuTo7PGJn32G6Rc-!r=^VRn1cJ2G9&eT34`P97*_oBd?rQPSkb/hZHb/h[&`Xp2,a32ZGcH*o? +`5]d:b/VO"b5B?Yb5]Q_`r +UAkQ!r;6?err<#trr2p"hV$02p](-i56(QZrVHQiq>:&q +T)TQ&r;HWps8McLWhc?(o`+phs8VrorVlfos!msFrVQWmqu-Gu;]Zl!(`FJ6-(OT$rVQ@5*>ob0 +-JJLsrr<#rs81gu*r[)h,pFTQ*@):7*?c_.T]#P9rr3E+r;ZfoZ6^V8;>C+irquirr;R*$qu-Qp +rVZWns7lTls7uZjs8W)us8N#trri?$rr)fort581qu6?fqYpBcqssIRqu?Zpr;R*&qskaB,Tjer +rqcZlrr<#srqud,r;ZZorVQHks8Mios8Dutqu6Tp#6+T!qu$Bkr;Zfrrr3T-rr;uinu&LZSZ&+O +qY^0grgWq<~> +R/]nUh6Cj,@Xtc!a2lTM_oB^;b0%`A^VS(6aiD9?`Q?ETP<'-a(_RMs%1n!3`ll]X$ka9k&/DOp +_SjC4^rFL/#SS$l&/H#u$4Rg['`Jmr5_Ztq]?&.Bb/hTEbDZi<"u+3Ac,\)RaMl'7`Q#p>A13CXMA +UAkAqq"FL\qu6cdf&,Qerri8ss8N#rs8W'rr;Q]qrVlcqqt0il9dpc!-5n$R,F/3'q#C3foTgXA ++s%r.q>^Kks8Dooqd(Kg,9J+H]Ct34/gqkb*@2dT^KjrWiK&qYU9i +r;YIL$N0l&s8MrnqZ$Qnrr3<'qZ$TjrVu`os7lQt_(-iQ-hmZ*rX]&.s8)`pqZ$Ths8W&rs7lHi +"8qujrql]trqu]nrVllqrr3#op\t0slf76oleVL9rri2rr;Q\is*t~> +Sc9B&r;?Nkpr&o)ZetNWs8)Qir;?TnrqudnrVlfrr:g5r9ICDl+r)+B+d;g#qZ$QooopI7*#K`q +q>^Kls8N#qqHY3]*?#u3[dr7#.3]ZI(*4>;;N]2ps8DrsqtfbQGe*2=q>^KnrVlcq#QFc&qu$Km +r;-H`rq?BlrW`?#rr;upr;HX+rVZ]pr;Q`rrVQWpp\b'grr2utr;R'%r4XI!(F&SQrr2fprVlfr +rVl`p&H;_+rr;fos7ZKmrVccls8W#rrr3#urVcWorqufrrY>J3rVuonr;Z]o]r%NpU7g'3qtg3c +SH"*~> +SH&WgHMdErRV#iai;0<`5Ta?5nOkQ'G=QCf>(f0((q)c'FbR/A!k*XaiMTCb/5Q/R)[FjaihrRaMl'7`lQEG +_SX:0`llB@rPn]Ts2t;]s2kGb`l5jp_#_Hmrl-P2bg";O`lQ?IbJqB2]Y2D/bg=eba25sCaj/AP +_8=45_8!h(`luo('bq)bb5TTlaMu3:_o9X:b0%g)`WO<)aN4>"(<=M@aNW&ReBYqQcc=)K^rFC8 +aNDZLr6"uZs2P&W*5fb7bJ_9:`4s=:_7Xeh<)R"7WnQb0rVccnqu-Kn!rMimVuM8~> +UAk;mo(;eY"4l/co)AXorVuorqYC$erVuoqs8GglrVuons8,M;,9e6O+rVqupAOm]q>:$cnPUMI +-64J9qu?]ls8Drsq4o&R+!KeGq>UEkm^d$[,UXo]+XSdSbl@_=s8Vrqr;QHjs8;]frr +T)TQ)r;?Edjee`Sb4,H0p\t3mrr<#trql^orqu`ps8)co:*h#()]9\6.@9c-r:g-hrVc7_*>9P4 +,cghBs7u]nrr;bh)]BS6j8/KJs8))k@jE*<*Z#_<.V?m(s7u]pq>^?ipAb0kqYgBlrr;uso)JOb +rr;uspAY?rrVc`ps8W)tq>^Km$i9i$rVlclq#C0erqud*rr)VE*#0K2qtp?jrr2fprr2osrVl`p% +K-5*r;Q``p&G'hrVcZls8;irs7QBkrr`9#rr)ir&,c>!qXUeSUnOZbkk=fJrLNt=~> +TDq=Vq"jj^lH"3\C5&b(^W"UJc-+8N`504'_8XF6aN2KGa2#pC-4(+p'b_;j'mS*Vd`08E`6?If +'G)B%'njQKa2Q9Erl?sK#Sn9neD\m&e&oRq8eD[S*#K:t#sFd*b/;NNajJG`b1=hU_9L6G`P][9 +b0%rK`Poj:a8 +UAk;mp\=[d"8C@%h>R?[qu?Wls8Vohqu6Tp"9/5trr2phqYp3_Kd%BQ+LWprVulq +rr;oLrr +TDoK$q>C0YeYB%BhXgdHq>^9drr2utqZ$Tprr3N+s7Z5A*u,M0)]aP#pAb!gs#0TJQS0F'*YTM> +iW&lSr;ZZos7ke1'c\C%p\+I`r;HHfl\cW%*uogSo)JX^s8Mior;-?koD\dhrr2rtrWi8ts8W)u +s8Dcnq>UBnrVl]orr**$rr)fprr)lsrr +TDrm*n+#bsZ>aMkS@-2I^=(0Fc-XYTaMl!1_8XL>bg";N_8X46@gibY(_m[$d`U"[d*C+Yb]+C3 +*#fG&%^jO!`lulUcHX;G)%RT(T[q3"_SF4:eBDq>(*"$)XNAo3_9:!AbK.]Ge&BVQaiquMrl#2b +b/_WH`l,j:`;.FPaSsaN)HHcG\2W +d)l:.(rjP6`lcNMa"%E"'84cRcd0hV`P]U4`lS/%!m&C$rQ+rW&')l +U&P/krVc`uo%Mjbrr3H*s8W)us8;TerV?9drr2rtrWE2ps8)`p/)hfu,p4EJm/$\WrV#pUPq+-r +*?-"C.'`gPqu$Kor;ZNko2@.X,B3JYrVlg.r;6Bas2;eQp&G!jrVccprr)j!o`+jeq#1KtrVuop +s8UaN!rW#rrr<#t&-)Y+rr)imq"aserV?Elr;$ +U&Pi*r;QWkkJO3t`VKB/qu?]os8W&nr;Zcqrqus!q#C6js!cnL*?Q1B($tkurr;ceo9CdL&f29" +*[S)ks8;forqcWgs7B/9'd%>fr;R?*qYKja_8#j=s8;oqrVuiqrVm#ms82cprr2oss8E0$rVuop +rr;lpr;Z`prVuWkrr)lsrr2os!rW#rrr<#s+92?1-grVHNnrVulss8MuqrqcN,MbNI7 +s8N#qs8W)trVuius8N#prseo+s82ZfJf>bAao;/6q>^Hno)AplrVuorq>C6l&,c>%oA6XFSXugo +q=FL^rh0:A~> +T)Wa#j1gLaB7de4`l6'?_oBg:_TC*Jbf\#HaNDcPbeM35aO&Y['H/29)$A78a2,s@bft2=%ga$g +'bq@BccX/Hdaumn_9pId*"N`ddEfVC_p-BKb/W,+T\%30cI'bSccaPS`lH6;f#u"Nb0%g)`WF6( +cMkun`Q-0Ab08#NaN4;!rQ,#Y!l`1#rQ>,\50D*odET\Nbfn/I_o9^?aMu-;c-ahX_o9L1_8*n4 +`Q,g5beqHA`l?6Ic-42NR;=V%cHOMTaMl-9`Q$'ErlkSgaMu6"auXPM@OeB>l2 +`W*sWaSNpUaSa0saN;`RbK%]JaiDB=_6obD;+jl(Oko6trr<#sU]5i~> +Y5eM#qu?]qqYpu_f\Glos7uQlqZ$Tprr61#r:]p]r;Q`rrqu]oqu?Whqtkpe*??(EJ+rp=p\^L* +.iTER+!N!V`VB<+s8W&srVlimqkkS\*[g^^qZ$Ejs8Dutqtg9jrVlcqrr)lms8;ims8W&ss82Wk +$NKu%s8;lrqu?ZqoDSafoD\Rcs8N&u'E7t0s8N&ts8;ops8;lor;ZZlr;HWnr;Z^!qtU-fqu>p[ +&-)M)s7u"--6sc^B@$POrV- +U&Pc(qtp*;Xe2Q5pAb$hs8)`pr;QZp!<)os./s2Drr2iqr;Zfnr;(j](Ddi2Ie`sBq>?[)-l3XA +)BBtF`;09,s8W)r./j2Ar2(MU)C>(Vr;ZZns8Dutqtg6irr;lpr;?Tjs8;los8W#qs8;]l$NKr" +s8)]oqYgElrr2Tjp\t-is8N&ss8E-#rqucps8W$$rqufps8Dcn!rW#qqYpNp#lXVnqY9jcrr2iq +s8Muqqu6Km&,Q8)q!'(K*ulG5bPLr1rql`qrq??lrr)j6rqucqs8Moks8Vurq>^3(USjZWVs!dO +rr)lsrqHEorr;u(s*t~> +Z2ak&o)BR)p>`8r;H8%K`lZQS`5T[2`Q?9EbK8#QrQ>/a;96qt`5]^AgMI`E)%mTld)j8Lep\#F +$kOBp)&3UXdDj#EbKeS`c-OG[M@UC3%a<,0_S=(6aiMNCaNVlH`QHKJ`llEK`koO4bfn>W_og.# +a:HG;d)jJVa2c<=b08#NaN4%o!m&O,rlkDbs3)_4cdC([`lcHD`P][:b/q]Ca3W2Wai2<:`Pop< +aMu6B_Sa=ka:HG;c-4>Pair)_e'#tXaN"4u!li=*rQP>br5efU(sBqBeBGf1":GVJ:9`EucHO;J +`Poj:aN44ts2b5_rlkDbs2c/&dF$1Z_T9g9aMQ'3G#VI<@ +YQ"V%rqm?,s8W&rrqcQjs8Dutp?CN"rr36#q>:*frr2rrrr)cdrYOrM+!MmK.dHd&ZVDSa,oe$N +,Uf&VqYg6h&,lD)p`gn-,dRIFs8Mlpr;-Ehs82forrE&rr;Zcbs82crqtg3equ5p]%0$2%qt^'b +qu$Hnrr2opr;-Qnrr2iqlM_:ks8N&qK-_Zc,9\B[AC(5Qp\t*g!ri,srqufqrVZ]prr2utr;R2h +j5oRhht-mJr;6Klr;Qourr2rqY5a"~> +WW*P/qu-Qns8Dror:7Y!S?_/Prr<#trr3#us8N#rs7lTmru(h7l6@)_)&FR_q"V-f)]9V/(`FJA +PkXtMq>Lp'qY]t,)BL!)s7u]pqZ$KjrWE3"rVZWmqu6NlqYpNnrqlrsr;?NmrVHNjrrN-!p&=sh +rqufp"TJAurr)iqrVccqq#:HqrVlfks8W'&rVZTlrVlfqs7H;1rr2_E+rq[D)'0i*b52#6 +rVccqrqZTmrqufkrr;p1r;6?,X.l5\WQt8O~> +ZMt")qYL'g!<2lq')_@VRVPi,N3Bn:dF$4X_o9X8rQ+u\rQ,#]rl?,"`Q$!Fb7G@-)A*\.d*S": +&fDc*'bCc]GLY'hbkfBkai`2d$P!jZLWmQV`l-0BrlG)]"3/F)bkoQ^a9Kf2bf\)Qc1fH^b5TK[ +`rF$R`rF*Vao0B\bl,W_`WO3"aN4>"s2k>]qo&QTqoJTUs2YPeaND`Oc-4>QaN4A#s2b,\rlG,^ +!m&C$rl#YjbKA,W=o\U9()@i+;RY?0bK%T>_oD\ss2P&W!li=(rQGSjaMu6@bg"DVb5KBkb082S +_15rm:02;,h=LIArrE&srseu+qtg'arVuorrVQKj\,Us~> +YQ"V%rqufr!<)lr!;ZTn"687rpAY'oqt^'ck5H.lIjlH_+shTB:+.,-*?6RV/!p88q>L'es8NN$ +HmKaYGl7U:s8VopqYpBls8E#rrVlcqqu63epAXser;H`srosFarqu]lqu6NkrW)lpqZ?]prquf] +rW3&qrr3>ADC6SR)BU1N->R`\rr<#eip>a`mf!.lrqcTns8Mljqu!SrJ,~> +WrEY0qu6Tps7u]mp[GM`T=s[grVuosrr;Ecrr3r:pNn)#(`FH=Z:uV_*>]A6+"!6Ms7lNjrVlfo +s8W'-rUY7V(*Ii!s7lWoq>^9ir;HZp!<<#srVcWmp\k'iqu6fus8N&tqu?Tn!WE#rr;cirrUKm\ +s8;llrr`9!r;H$^r;RB+s8N&5CEjc>&f2K/+CtBIrVccqrql`krr<#krr;p.q#BimS"ZLSb4#-* +rr2]ir;Q]ns8Dr's*t~> +ZMt")qYL*h!;ufq'Dqh)lIV#5?#Z@7]#E"Eccj;C`ph(Latq&V`Q6>4(_mo*'P!F`'G)9((a0V, +Fk,$bcHjbXb/VE<`Q$'Gf$n%9#RX5Eb/2EG_oh_p"j4p/aNDU$b5BH`b5KQ^ao]Z,aS3[VaMu<@ +rlFZQr5]5baMu<@aMu<@aN"1trPnfWq8r]YqSrQVs2slQs2tA_)TKb8_oT^=cI8.O#RqU^'c@l% +9@_8,`P]U5rlG,Z"i\Bu`lQ=%bl>fgaMu6@b5TTbb5KBsb082V`5\lp8PiE$Ra:3ms8Vuorr;us +r<)rnqu-Norr';*J,~> +W;ckoqYpZEe^cIQ!rVZZm +s7uZos8N#tquHWmr;HWirr`8uqt^6d!;l?br;QHj!WMuqq>U9jr;6Hsr;6Eirr2oss8E0!qt^'b +qu?Nlrr;6^&c_V*rVl`gcXeOT+=8*YK`1l(rr)j#o&&TskhlC>!ri)rrr3-!p\+C[r;QlsqtpB% +s*t~> +XT/;!%fcD*qtg6dpYMR?VpG)9rr2usrqlfrs7-'gs8DrsrtbV4koUcb)AsY<*YoS5*u>rgm/QqV +s8;lort#,-s7j)F-Wm>Cs8Dlpr;ZKi!WW/qs7uZmr;ci^s7cKnrVlfp!<2`mqu6Qor;QQm"o\As +rVc`os8N#srU'U^rt+r)r;HKab[;Y@)B]hBJc#EEs8Dros7-*`rsS]'o>d\tT:r%No_SRes82lr +qu?ZpZN#F~> +Yl=e'qYL-i(\mt'o^qY7[r65$NjHFfA$$k3OS(E!Yk +KZVff_op3Fbf\)Jrl#GgaNN&\R0+$_HGdnG`lQ0BprEZZaMu<@aN"+u!QrL_`W4!T`r=$Z`q@CU +b/h`Hb4*LMapZ;5aNDTHaNDTHaN4A#rQ+rWqT/]Vrl+oWs2b5_!R/^VaT'E_a8j6Z`=gD2c-4S_ +c)XGM((M#b%q +Z2Xh'qYpQnqu7&pg=t-Ws8;idq>:0gs6BRrs8.Ho*$6@I+!DdP+X2s4pAb!fs7lR(r;Z]lla>aO +s8;fpq#:U9hrql`ns8M]k#QFYuq>'g]q>1!cr;ZcnrVulnrrN,prqQNhs82ios8N#t!<2uq +rr2lrs8N&r!W2fks82cqr9!tiqZ$Qpr;ZWhcX\@J)(ObHrS.;^r;ZHis7GL=nEJs,s8W#orr30$ +qtTs`rr2p#rquTfrjVoX~> +XoJA!&c2P,q#'s_d\`h@nbrFdqZ$QmrUBgds8Dp2s8N#nIiT4>)]9S8*?Q=EMWj^4qY^Blrr)j- +rVuckl*K:Fs8;fpq#:U*fqu6Tp!WN,urp9[brqZNgrqHHmrr2irrr2rorql`prVc`ps8Mut +s6K[^rt,&,rr;lqq"Dm=+s.OHj8AlSs8Drps7?6`rt>;1q#C07VjX!BVU#)=r;?Nkrql`prj)QS~> +YQ+Xt!<)oss8*T-n*fArXDMH]Z,"9&a3i;\bf[rE`Q%Jis2H8*bf\#HaNi7M&J5]l&J>cj'FtUl +aj&DVaN;HE`lcNJaN"4u&&cW6cGGRTf$D@UcbdcJ`qd^M`r*mY`l7knrPe]S!6F`R!6FuVq8hpF +rQ+lU"3&:!`r*gU`rF-[ao]f0b4`Poj>b/h[%`W4*X +b5TK]b5]Q\`rYY@s8W"qs*t~> +Z2Xh'r;Zfrqu6che)0`qrrhoer;?Qnr;HZ\rYPJ0kq",%-QjHP+:3i!<2fo!ri,prVQZpr;QcprqZNis8;ip!rr9!mem%_o`#*or;6Bh +rqucsrqlEe!rMonl2Ch`s8VlnrVuon"k-m7K`1l'rr@@ki;U?rrW2trr2p"r;6Bh +rr3*"qtpB%s*t~> +YQ+V#"oeQ%rqcWnrVS`*+s8;osrr)ir!ri,qo)AXgrVlis(]4'j-QX'G(`=53+F`\KrVZ]n +r;ZZkrVc`mrser,q=t!`s8W#rs8W&rqYp0fs8N&s!<2`ms8E#srqlcqq#C3imf37brVc]ms82io +!WE#qs8W'"rVZWcrrN-!mJd+b#6+Q#s7lTmrr<#m#16a0K)GTHrr;rr!<;clrr;usnGa$tp"lX@ +R\$G*qY:$gr;?NjrrE&'s*t~> +YlFb%!rMikrr3c/p@.A'Rq#lQZFnB%dFQXgb/hTDb0':r-H=$Eb08)P`l?-Ja:o=#*#05)&J&Ho +b0.fG_SF=/_8OL?b/hTBrl+oX%+32>e]>tV`lQ9Ha2e"s!64fQr5JcV_u@LP_uI^U`r*mXb5'9[ +b5B?O`r4!Wb4NpXb5TK^`rVg_84"0aj%o?Tk.;# +Z2Xh'qu6Zqr;QlOiS+80rrVWbq>UBrqt^'brr;9_')hk*JfZ$Z*?lMSl1t)Qrr;lqrql`qq>Lp) +q"Xmequ$Kirr)cps8)ckrqQEkrqucrrr2iqqu?Torql]ur;$0cqu6NnrqZTkr:'dr;HNWrX\l's8W)ss82ims8;c3lhUMY!<:pT"8`&ip\k*qp#Y>r +ip6UD!;l]o"8r&nrr2rtquH`*s*t~> +YQ"h*r;?Qos8N#r%I^s9Vp=o6s7u]ms8;lps8VusrU^$fs8Drsrser,p3mhr)\a8/I-:>$rr3#t +s8Mrrs8;lps8Vm's8;cls7uZmr;Zfns7uZfs8MuurVlWmrr)oqrVHToqZ$NnrVc-`rVlcorVZZl +!rW#rrVuos"9&/qrUKpTrr<#urXer(s8W)ss82ims82Z0lM1AWs8Doss7lT[rtYJ3r;Q`oo^0Dg +T:`$oq"Odfrr)cnqu6ZqZi>O~> +Z2ae$s8)`p(]*acbD^XVMQX_2_:6fZbfIcB`lQBJb4E[n`l5p>bfn5L`lHTU@gEY`'c[p,cI9kS +_ns./rk\]Xa8X6]aT'6k`Q>m1bJqNBdDO&G`lcHBbPB3a`l5s:`l5s:q8NHS_u7RS`r4!Wb5]]_ +b5KE[`qdaPaSj-WaSj6^bf]q/s3:Pes2t>^s2OfPrl4uZ"3Sj3b3d:M`rF*t`5^0Mb/qiIcGn>X +cBc,ab/VE>ai_iOaN"5#r5o5b`l?!8_o;>hs2G#U&&$'%b1+SIYBNuB +WW*1rrr<#Ig"-0&"9%rnqu-O!qtKdYrr<#`rY#8%s6VB_*%)^TbOPH/r;Zfrr;Q]srquTk&,lP. +qu?]qq#C^Ko!;uins8;oro`+mh"TA5rqu-Nk!W;ior;Q]k +rrN,sp&53rr;$-`q>:*frW)lpqs"(^s8)KhrVm-"s7lTnp\t3lrr<#Trr)lsp\t0skMG1Yj5'Y/ +rrW2triuKR~> +YlF_%s8UBlrVcfsrr2Zlrr)lprr)lrq>UNqrVc]ms82cnrVlZl +!<2fos8N&srqlcpo_nmkrqZTmrqufdrr)lqrWE2sp\t-k#lO_trr;`ls8Musrr2rtq#:'gqu6Wq +rVd0(rr<#oqu?]l`Mrj/!hn-:rr*#trr;urrrE&)s*t~> +Z2Xn(qtpBkrr3N-iQc(FE4*%2?RmJm.]o_A:\ +r;Zcp[f:j~> +VZ-_?g#N&2"9&/lrr)j#r:fs\r;Z$\(]==3pmWQO+s/"=rV6EhrV?Kgrr;uqs7uWorVlisqu?[$ +qu$KorVlinqYp^Kls8Vrqrqucprr:gRrVm9&oC`(^s4lbtjkTb.s8W)(s*t~> +ZN'q's8W)ts8NZ,l(t2\nbi@_s8W)tqYgL$[p&"I_pAk'hqu?Qo +qu-HkrVQWprr;rsrqQKrrr)fprVlfps760es8Dp-qZ$Qls8Vrqs8;osqZ$Qmr;Zcqs8Vooq>^Ko +rVccqs8W,u"o\H!rVQKjrsA]#or"RVStk*1rr)lr!<)fp!<0D+J,~> +Z2Xq)qtp?krt>;*kJV=IC9tk&bKeARaMc0=_u@XT`pq+m`l#^8b08)N`l$!Ac$Bm7)Aa&ZfuV7H +]tDV.bg+JUbk]?[`sp/2_nsO9`Q$*Ea2lNDq8iKV"j"j-b/ha(a8jBZbkoQ_a8s<"rPSWNrk86B +!5\9Es1n]MrPAKNrl+iU!6G/^rlFWPqT&ZZn]:aM'ue24aN2NH`m2ZEaMks6`PBR8`6?=$`X'W, +b08#J`lQ=$bQH#/`l@tr,f@UBbg4\accjJM`lQa3W)TaMPHl@9m#@DSY6$o_8@]!<)lr +"9&,orO;fW~> +YQ"t.s8;ZirVu]De+ik@"8qujqu$KoquQ]mkPbtis82I7,p=HR-d)A_s8UpSrr!N0rVcThrVQHj +qu-NlqYL-hqtp3gp]13jr;ZchrtkJ'na#>sio&_Nh;$fAh;7,Lio]Rtq"s[_&cV\'p\4I[rVc`q +rVZTns8;`erri?$s8Dc8rWN9!s8Vrprt#&-p?gi6qu$Els8Dims8Dlq%/fqss8)cqhqmVXhu3QS +!WN#qrri;urr;r*s*t~> +Z2YI9s8;opq>^0s`o'bu4lJg@=_n`jjXf81oU8"?STV8*T +VP^ArZb!rjbgkV6lgF<:q"XU[r:g3orr;rprr2p+r;HKfqY^ +Yl>F9q#13js7+mDCL`jF]ZA=Abf\#HrQ#2caMu3:_oD;h)TKb8`lcNLb/VE;ai_p;()Il$&?*jk +`Pfd?rm(Vib5B9ZaSs?\a8j6OaSs4mb0A2Rb0A&Nbfe2Tb/hZHbfn>UbK7oNbK%W@_ns7,_7mRo +\@/Q5R#d,XIX#mPD/!TnA7T7`B520uEHZb_MjC$;ZaR?T]tV1l]YD;!_o0O4`5]j +Z2Xk(s8N#srrViBg\q-Xq>^Koqt^'brquctrqu]YrX]&)rr;ql*?uUJ+)gcNr;5CNrr3W1s8D]j +rVHKms8;opq"t*krqZ6e'E.@Wg=b*)cHt(mg=tB@[i7lu=f$Mdi +dFd=Br:9jiqt0ISp&>0nrr2rqao2AAqt^6k$MFH!mY*889>16%rVluss82fnrt58.qu?Tos7b.. +l/C_'s8)cprr<#q!<0A*J,~> +Z2Xn)s8N#ts835LU8loUC!rr<#sq"agarqlcprr;Nf +rr;cmqZ$KmrVuiqs8W,urqurus8;`mrsJH!s6P=e)Fh72r;HWtqu?NlrVZ`qrVmE(s7FI(US+9g +o(VnYrVc`"s*t~> +Z2YX>s8N&uqs`O7@qD%@cHNuEb/hZD`lQ=%bQZ/1`l5p:o>h'S`Poj^Hn%/p%tqY'XYqYL-is8Musa8QhPq>^Bjs8W#h@N6L5-miEqq"Xg\s8;cprr)j) +qu?Hjs8V<>l0I?`rr39$qYU0frqu`o[f:j~> +Z2YI8s8DutqW4fR[GLf[qu?]qs8Mrr!WN#rqZHcqs8VZhrr;oqs8NQ,s8D=7)]'82+3jQZs8Dlr +rqcZ^rWN3!rr<#tr\O?Ks8DimrVucos8W)srr2T]naYo"ah".6P)YH_Q^aJ8T:r!QT:M[KT:hgK +TV%gISY,bMr1=n#T:_^FSXuICR?N\kOd_rF][>d+o(DhTqYU0i!r_uorr2rt#6+Z&rqu]mjo55Y +p&=jgs8N&srr*T-s8Dlqs8)=p)&sVA,@L0>qZ$Bgs8W)tr=Ac)qu-Qa_53]nT;^oMrr)cps8KG+ +J,~> +Z2Xh%rr3Z/k.,G=F/$[taihlH_o9U7aND[%bQ,fUaSs0naND`Nb/V?8`m;jE',_Q!$Eh_%d/M?" +c-"#?^Ve%1`lQ6Db5BHbb08$(a>1fWaN;QFaNDNHcHF>Nb/qWDaiVQA`Q,g0^V77ZQ\]Kj?<:32 +?tB*2g_C2*W[-u!=)?];^V[n)`5^!GbK8#N +a3)TKbg4JTaiVQA_o:r_s2t;]!65#WouR*O*lZ.?b0A2Tb/M0?`5^'QeC@+r&/,oq8^bl)a1f[: +rQ5hq`l?!;`6H6=_l@lZ77^R$_s$glr;Qcq[/YX~> +ZMtR:r;?Has8V-6o`+sdqYKsdrr2os"8r&nr;?Qrr;6EWrX\o*r;ZcnR3*On+!>:ls81dS!<<#s +s8<)ss8;]jp&>j,p?()\g"bKMme$8Kp\"(ClKmm)m-X3>mKE"HmHs?@nGi%Xn,i"FmelMTlg4'= +n.G'RmI0W;naPu5kiL^Sf%fESq>Ug"rVZQgqY^9gqu6Kmb5N4Us7u]pqu?A1,97pO(Eb#'fDYLE +rVZWnquH`orsS]'q"asinE'$%iRe)/#Q+8jr;Q]orO2`V~> +Y5\n$rTg_^^?tmns8Vros8W)srrE#sqZHcqrr;Nfrr;rr&,ZD*s8MhZ)&aA2*GG3GqYpEnrqZT] +rW)usrr2lrs!@[Es8Mups8;Wbp@\%GcG$QBIDlO-?6C_<(+ZrV?Nlq#CBns8N0!qu#RTrVuNhr;Zfr +s8Drr'*%h.s8)]cD]]f9*>0>9;qM$Fq>V*,rVZTmr;Z]is7aO0TVA$QiqN?Mrr0A+J,~> +Y5]+&lbdaEFK3I'cHX>P_nj70`r='YaoT`2rm(Sen]:^L*6?:Hb/M?9aNW(Y$Q9ru$r#."cHjh] +bf7K5^;Kris2b/]r6,/`q8`QXrQ,#Z/]Q2]aN2KDa2Q3?_7m[u]""2eG%b8j?F?Yk1MYdV9_rkeoX +`lcKIaSs?fb/_THai;9bKe>_e6Wh%()[Mm&N@&EaNVZC +a2l?A`Poj +Z2Xk(rVlfuf\>9^rs/GtrVcKdqu6Tp"9/5rrr)iur;6EWrX]&,r;Z]npb*m2-5n2Zq#B=P!WW/u +rVuj#qXX1OrVcTm+8"LDg#1iKk3MI+o'c&:o(2MJp%%YBmdBQ6o^;/9nbr"]n*]W2mJcPRnH/4K +mf)SVn*KB*m/HJPnIP3_o^_SAmd')tj58M;fB2u1$3'bus8DWeq"amds2t +Yl>43s8LrRU9*k[s8W&ts8)`prr)fqs8Duq!<)?brr;us&HD_-s8;ff.N]?J(F.E&rr)iqr;Z'] +!WW/urVulprtPD.qXs7DlIWVAQBRPtQ'n5;USFL]Se%B`StD[LT:VUGTqn9OT:c(T"J26XSt>qR +s.TRgTV)4T"/DTaTDkJdStM^GSGf!#USOWUS!fV1P*;B?c/eEgqZ$Khr;Zfns8Dlos8W&rlMge_ +pAP'lq>U?ms8E#srr*`6q>U?es7Vg$*#]k>*uu==+3=KWs8W)ss8W)ur;lrrrr3?(s74U;TVnTV +h>%!L!<2ut!<0G,J,~> +Yl>43p>iSr?"L4Rb0A5XahdtqqSi`\b0A8]dEM1&!QrL_`>cn@bg")B`l?g7a2>a0]XPJ\V20,%?sm;J@q]RlC1h-h@U`hXA7fFd@qB1_ +Bk(X`Abp$=Ac?,\rl4iVs2t>^!li=&rlY5]s2I(<`lQ +Y5]!if&6&ts7uZoq"asgqu$Em$2j\tr;Q`rrqu]YrX\u-r;?Qlrg"`G*$ZeBs8V'W"98B!rVlfs +rqcX!qrQYae_]Qin0%;no'l&4lL"!-nF5o9n*TT6o();=mdfo +Z2ak&'DB>?WP/!&q#CBjqu?Zqs8Muqrqucsrr)3_rVuos%K6>*rVufnOrb;S+=1Xtrqufmrqufh +rWE3"rVcWn0E1hBqX2e;Um$h#Q^XA4SXuLHSt):AStD[ISXc.8^T:l1W!20=`s.CI*S=H1DTq7gHTV/$SU7e'JTV.a:OHuT[iV3C6nrr';* +J,~> +ZMtO8qX`O4CM%q%_8=LHaiV]D`r4!U`WaH+bg"ASo>hrpbf[oB_oBjCbK[l>`QHYR'bLla#t!1f +bfIlF`r;4p_8OF:ai;?AamdCMb5]Q]`r*pXb5]Q]`W4*Xb5]Q^`]D2`bfn5L^rOC;bh/^&*"s"u$qgs; +'b1[ueBc.T`Poa2`Q63S.<*X=BiUQ^Ar3QER~> +YQ"_&f[Tftrr`8qp\k!h!ri,nrqHWlr;Q`rkPc"cs8Muss7cO?+XA=^kPtA:rW`E%rVlisr;?R' +iR$'#gYqA`nac8?mf)VRn,MnTmL&IRo(2D?mdBQ5nG_hYn*oi:nc%qUmKN"Gmd]f9rpTmT$gmBO +naZ,;n+?5AnG_kXnF?#ImK;qGmI1#?#OUgBjP8AGq"t'prqZHfqY\M8)>a@4s81P&+<)@D-(Oh@ +-6XTU-?8bTqY^?krs/K!rV- +ZMt@4r:A@9UUElrW)oprqQNg +rYY\7rVlisr:fgPmanY3Q][Z(SY2^OTV.qVU&UecT`C_`SI2!^TqS*LS=H.AT)P8`StDXJT`1P_ +TDkD`TqJ(XTDtJjSXuLJTqJ$MUnaWVrh0CfUS@a\"/2B[U&L\rU8+KVQ]R?*_r1([o_eagr;HZ^ +rr)lmrquflrr2rqrW3&rrr3`/fI.XR)&jfhq6_Fe*Z?5@pA=jhs8Dros8W!*s8DrsnZSISR\\?t +rr2p!rql](s*t~> +ZMtU7mF\F]B99g?b0J,KaiVK>b08*-ap?56b/hT?_8F:aa=#-Sb/M35`QHHEcc*]@b/iaN;QD_SEgrUO6]a>[q;VBPD*kARt^Ms(M=B#\[pe +BkM!fA7baP$YQQAH--O?t!PUA7K(VB4PO]@prkV@q,FF"(>YIA,^!P +AS,Lc@9d)UNN9\.]uS@ +])Va.qu6c[db4/Vrr<#trquQfq>:3lrVcWj +s8VB +_>jN6q#C?m&H)79TVp'+q>UBnrVuosqu6Tm!<2WjnG`Cds8EN.qZ$Tks8V_Z->;N;rr2lr!<2rq +rr**$rr2rtrqcZlrXAi+rVZQhq=aCE^RUGcSGo2_TV).Rs.B:`!29Cbr1O+`rh0IhUSOc`rM9Ii +s/-.$WN*##X/`.trh^:*VP^2dVPU)`U7n8J@u+!>Frp\E#U*uu7@=m#V\ +rr3f6s8MusrqlZmq>0]rS>)RLc1V)7rr2inrrE&nrrE& +^Ae?7qtp?jr;RH-qX<+$D/>ibbl>fh`l#X,^W,ic*R)[F_o'I9bgOMN +`P9FaNDa+c2Z#fao]Z(`r!aT`r!jV`rF!W`>$/%[uG-1BPD-rD/3fs@preQ +@:<[FA-caYAnYjmC2%J^C'8nGQD%g`#BkV-kAnP[cAn>L_ +A7K+X?srqA)e*5`@:E\S?t +])Mp2qt^-grVluhf%'QprrW/sr;6KmrrE&squcurrVQTo#lO]$s8Muns8)!Z#l!*Gr:^0cs8Mlp +"oJ)iq>C6krri8us82NfrrW/srVHO'lIseCj6>gnlg4$-nF-;E*V&XfmdBE*ki1[_hqm>Mg"tQB +jm2F.pA=aes8DfgrrDurrtk\3q"XOTo'GT#iS`YQiT'(`kihL*o'lYH'_(JVnaQ&:n*ol:n*]`9 +mcN0Oi;3BO!W)]ms8W'$qY^Bkq>UBorquZorql]trqlTjo)9O*s7lNhs8W&tp]'er+X%mO+("m@ +s7cEW>Q,iL-R@.5rr3)ss8Mopr;?O$s8N#ts6JJ%kMu13s8Vusrr2otr;Q]urqlTj`;b>~> +_Z'cUiur;6!&V5Vo:rVlcorr)lsrW)orrr2rtrW)lqrs8T&rr;urqZ$Hhs8N#rs8Drr +s8W'(rV"q;rV6Eis8N!#rVZTjrVZ[Arr)fqqu6Wpq>^KmrVlcnrr<#qqYBU/YaCK9S=lOITV%gK +TV).R.%d*'TV%pOU7e9XUo(/nWjfRR`6-KXf\PKHk2bRenbDkOp%\=PlK/$-(?=?/g!Is`_7R(Y +XfSM!Unsl^T:V[Jrgt:,UnFEVU7n6QTqS3QStD[JS!0,:bNefqqZ$Hhs8W)qrri/tq>C6hs8N#s +r;cirs8W)ts7cL8rVuZjqu?]ps7cQaAKMs3*?&)Up]'s`l;nuG*$??Knc&OjrVuoqrr3r:rVc`p +s8;fpnAM#mT;0C%qYg +_>jN5"T.obq"t$i$i0MbfU-GkQFF]Ma8X:&aMu-6_oBd?b08)Pb0.cC_T9[7_oU!Fb/_HC_YV:O +aSj*\aNDZHrl,;db0A)5bL+AV`m+M(rlPAfb0%fHr5o2d`Pp*@_#DFnb0.iF`Q#m4^qmORIV<%q +A8,akB4kghARt^J!+Z";s().A+Co2&C27g0Ee&h!Ng6*+U8OuoYcb+7]>21p]thFpZ`jA46a!Jg +URRR4N.cY)G&qV?DJa6*BP1skB4PObAn#7[@UEGJ?XdPT@:a+a@U*8[PH_X2^;n(,aN;HAaMl3D +ai2WIb5TK^`r*d]`lQ +]Di$5r;-?frVm5ef\-'"s82ior;Q]q!ri,qq>Lp%rVuokr;Z]prqcHhrr<#_rWiJms8VopqYU9k +r;R?*q>:'err2rrs82]nrqlBeq>V!"gX+U7n+,o9nF,i9o()8KnGhqdnF,W+lKREiiS`e\me6/M +#6+Z&rr)iprr2uqmf*RblfI'_jlbdgrTG$bmHa-*n+-,5m.'Z:nb)PIm,?O?f(Jt@s8E<(rr;W` +s8N&nrr30$r;?HirqucurqlTjo):$8qu$KmrVZTmrqD[&-PmpP,2W(nqZ$TjpP'q6)_!)=oDA=_ +rV?Kirr2rtq>^HuqV^H"g?nn>!r_rmr;R!!s8W)rr;OY7J,~> +_Z'`;r;?NkrtPJ4qu6QioY7<'ebo:>s8W)trVc`ns82d,qu6Wqp\k-is8DcgrVlisrqcZbrW`Dl +s8W#srVc`pr;lipr;Zfr"TA5tqu6Tp1ALeIs8;corUf[-W0<@/R@Kh?T:VXITqS'MT:hdIT:hdL +Unjc]VQ-r5`6R-&o_8%PrqI-&qu$s8VleJfY[@+s3rVqt^9lq>C73rr)iqr;QThs7am=TVe9n +q"=R_rr;usqu6Woqu?Zpa8^Y~> +^]+K9qY'XXqu-O&q!6Y"DeYKL]Y;P2rlcD*`l5j5`Q$!Abfn5N`Pp$E]u8+8e'6"UbKA)PaSNpH +a9U&(ccsMUaN=;$1<@JTaN2NHbfn/O`Q-0C`kTO;bf.N@`4NRHDd6RWBPD'lB4bahBk_0lB4Y[e +B4kaerFmHlDKgSdPFo(i^V7M"_8O=4`l,d6`l5m9b/h]Ga2uKF`5hku*ll:>_T0X6_8*du]Y(PD +P(\4)EH#c2C2.EpASGadra7!]Am8\T@p`PO@qT=Z>?YZtWjK[b_7mh,aNVK;bf\#CccF,IrPeiV +rPeiYrlXcP)Tg%>cc*lA`lucVFpo)o&deZQe'lC_a2H29rX^1j':R=j]u.Y'cc3rC`lu]MaMl3A +a3(oH +_>aN7rr30!q>C9mq>LLp)pA=aerVulis7q5$qXjgPrWiK&s8W#s +rqZEf!;ucp%K?8%q#CBns7uNkrqZ?gru^phdG*[GmdKZ8o^qbJo^VD9lg=0/lg!fugY1WJmJ#fD +"TJB"rr)Qjs82orrq6:7qsih*h;@5Qk3;7#n*o`/nEfE*nb)SDnaGl2k2+\[ +_>jN6r;RK1oDJC[p8P!jm/$2Ns7ZKlrr)fpr;ZZn&-)D%r;Z`qrU^$_Itd^is69Lfs8Dutr;Zfr +q>Up'rVZTlrr<#ss8W&tr;Q^`rV$$_m`MGlQ'n28StDXGR[KY9S=5h6SY)UJStDdRX0T=Te)^&i +p%S1Squ$ +^],#Hqu?]prVuQho^CLXC2L,cZ,Y#%rQGPiaMu3<`l?*@rlPhobeD!4bfS;Zbh1g:16b3I%Q +bfA#N`luTFq8iTUs2b/](!"_Ha3)<=bfIT3]u7IHF'`9cB4kiUB-LntAnYdeA7]FhCMR[#DJXBA +K8c5"]"5Sj^;%V*`Q-$=`W!dg_o]s=`lH*>aN2KGaN)EFb/qd)aT'@Lb/;*6`5T[5_ns4%]=GMa +\=f%>H$""DCM7?oBPD-k@:s(W?XdSV?XmVXBP([Y>AB>*]"l;+b0%uSaMQ*<`Q6-CrQ##ZaSj-H +a=GNP`lYm0`Q-0KNsZI.,npBWdF?F`^;J.>d?GLa%291be]Q1[b0J)J`Q%o"&&u?&bKJ&L[[CJr +:1A4sm/I%bqZ?Qhq>1-krPnkf~> +_Z'l?qtpBjq=smbrrUHmi;NZZr;$3`r;QZp!WN#mrX\l*s8Musq"t*c==Yc.qu#^X$N:#'r;Q`r +qYU*arV-Bir;R!!qt]m`qu$Hn!<2rs%HYj_k3;F/oC))4lhL5RoEt*Um-Eiohr3hlpuh\WrX&W( +rqucos8Mror;QcrrVm3&r;?Eeq>:$`r:U((rUoI>jlPXhlK[U!mHs?1nac5?n,DVVl0%-]bh;dk +!rM]drr3-#r;6EirVlipn,=%$r;Z]js8W&th'a +])Mj2qYU9g&?2J4o(Dn[r;Q`qrr)cmrVlcqqu.-'s8W)ss7c?ho2I+`[JB^arWN)sr;6HdrrE#s +quH]prr`)sqtpBm%0$/&qrPJXPFnA:TUu.R,+G0lR$sS:StMmTUS4Ng]ZK*so(`"Sq>0scrVZWo +rr2flrqlcprr*]2qu-NorVZZps8Mrorr;rpr;6?gqu6Ek!W;opru(e3q"jmdpZ^8M[]l^+USOZ[ +TV8-STV8'Rrh0=arh0^lS<]58f^nn8rVQKirr`5trVlcqrr2iqnbs7&r;Zcns8W&tg*RaV*>B]p +oDeacrr3Q*s8)E0,9%XL'3"_urr;oqrr;rr'`\(/s8DiprRe3ATV%qSqtg +\c3ECqtBC3H"1]s\\Q(t`6$*Ec-4DSaSj-YaSsQm)TFLa2Gm9 +b0.j$aT'9[aSj7A_ofs;bK.`@]thIcL1FV+BP;-n@piYMBk:jfBPD6uE,]]4EI3P-XL5j_`59L5 +`5g!@aN;WH`Phbp!65#Y(<+52`l?'=aN;QF`l?*AaN)?@`lH-@rlI:C`l?!9^VRb(`504$\[fAd +\u_B\I% +a4.R-$4n*k)25uYbf@lIaM?0Je?9Mr',LX.fZ_dkb/jS%rl>nqaM,O4aN)E>P@$p\?ZFumqZ$Tp +p\Odbs8VrrrPeee~> +_Z'i>r;69aqu6Km"6SOro`"jprVlQ`s8;lps7cL's8;fis8DureKuOb+sZ4Lkl(ngrVuorrqu]k +qu6C"q"t*krqlNequ$KmqtpC3qq9EPj6,gumd9B2o^hSFp@RqEkiCaViU-L4rrN#nrqHKmp&>$k +qYpWrrVlKis8N&rrr2uto)B[+p$Cbtkj7^(lfm[!kj@j+lg=95lgO3#gXY?_rr`&ip\Omb!W;rp +s8W)rr:0b6rVuoqs8VunnPL;I,9S7[s7l?gs8Duls8W)uqqYX%+Y+`ah>ILm&qu?]ps8W)u +n`/`lkNVsF#Q4Jus8)Zjrk\Vb~> +]Di]HrVZN_oC0ir;Zfr!<)op!r`,tqu?6d./j2Grr<#rqX7,s)'0_=HN3d7s8W&tp](9m +s7t>P)&jkA,2)ejr;QWos8Ei7r;HWms8Vogb,V2/Wk7s$q>^Kmrr;iorrW2url"he~> +\Gm'7jjeTaCm;cQ^Ve15`mOb/s2t,X'#r,5`l?EQf\*nK$jH_4][G'Kqo\KN#0+R%_SsX9rPnHM +1=!kVai;39]"!c7?=[\]BP1g`?XdVY@qK@gCM[g)E,U/eUTh5B`5g!@`l,g;bKA)SrQG>ba2Rtr +!QW:\ao9H[aTBQ(aSEsWb5fZ^aT'9q`Q#p<`Po[/^;%Iu]tUhNR>uiAD/&u_)eNPe@9d5N@:*GR +B4Pgl@9m/^S[lJO_8F:9b4s0_b/hTBrl"lWo#UjQ-H3a8_SaO<1'nF-(E7)?_SaUAa3;B?c-"Pb +]LN8;(Cgtkf[S-fr5ScX(WXD0_o0^E_RYA);,q=edd$K)s8N#rqYpKsrVH +_>aZ;qtU!dqu6`LiRIf*"o@rjrq63ds7lTnq@*E%r;ZB!.O?5_,]!,;rr +]`/cHrVcQfpo13eoD87\s8W)us8;oqr;?QmqYpNp&Gu>(qtpE_[3Qe4*[#.grVc']#QOf'r;Zfp +r;Q]rrqufrrql^Fr;ZcjoD7gfO-5s'U8"9LT:r'UTq7jKTq\3PV7+P"m.'iIr;Q`rq>:0jrr`2q +rVlEg"T//trr)iq!rr5trr3-#rVZWmrVcfqrql]m"TA?"s8N#rs8N&u"TJAurr;us-2dZ6m,6F, +ZDaUtWMcSjUnOKWUS"'LTpqUKTU(q6bkD&8qu?Eirs8W%qtp +\c3<>nD&7s<2mFC`llEAbg=APb09e+qoJfW&]2K6bKnqfRMHSH$3`rFdEg&6b4D%7>$PTPC2.BkA7fFb?sR&IC2@TuDh+(H[CO&g`Pom=a2uWPdEg"WbKTt1 +s3:_kb/h[%`rsB%aiDF#`sTr/a2uKGaN)<@a8O'\a32[)aoBKbbfS!+`\GNQaN)9<`5T[5_o0F/ +^:(&6K6M0HCi!j!C1^sa@q8tP@q8tWCM6sV?&lG4`Pp-@rQ5,arltJe!m8U(rl"lWo#O;BaMc!; +_p6b8$4n'a$V/ss`m)EBb0A;Ta3VHDdaqb4&ePrra3N,UaMu6=`Q63@aN)68`QcTM['3t7;I"+T +k4noTs7cKl!r_ul`;b>~> +_#OH6qYpWQfBiJ9#Pe,pq"FU\rql`jrX\u-qYp?dOXMCo+Y&*mr;6Hks82ror;H0c#4ps4hWL]urV6-ds8W)uq>UC$ +e`5lPhuE`Pq>:*hrrE&7s*t~> +^&JTArVZQinuAA%q#: +_Z'`:qYL0hrt>5#fQCJM[CsK&`5paihs.ao'ceb/qp-bl>jDa2Z0A +aN)?@`l,^1`5T[2^:(#,JoPL=An>RbA78t[AS>^c?!^lG?rgK\X1QQr`l5s=b09k0s3(YhaMu3< +`q%2~> +\c309db<[[s82ins82Kbqtp6ip\k^'nGi@bAKi?A-R?2#p&>!UrWN9!s8MujrrN,sq>V5fcJ@m[ +o'u/:nau;^Hl"oJ/mq"XgeqZ-Wos8W'%r;HQgq>UrVQWpr:`c,+L]u +q#('gs8W)urr)j(eE?2\iV``Uq>C0grrW2tr5Sbe~> +^AecDr;6EhgoREZqYU!dqu?]orVllsr;HHjrr3Gss7uV&*Zl=E+1(k9rTX=]rs&H%s8;oprVHF? +rVlirrVZWmr:]'OOd)?,S=c=BT:_[DT;/*SUo(6+d-:9%qtpEnr;Q]rrqucrrr)lsrrPFKqkq>C3irr2rsrVl]qrVlfro):!7s8N&srUlWu,8D"=gACjKrVlir +rq0MBQh^OWs8Vug6Q-aX.,=h$rVuosrr3]3s8W#srr;okpS4OYSu10 +_Z(JOqY9pas8Vra^jBX-]>D;'a3VuLb0%fIrl4uZrlY,Zs2GVl]$njS5lh/q&IY&_c-ahZrQ#&_ +bf]Lts2G8\aMu0@a2n5%rQ#l!aN2B?_nWprV06'OBl.Qq?t!VYAS#OlCAquoEe0LW\A#Yi_oBO4 +a2Z0@b0.rKaN;TIa2l6A`l?'>`l?'@anj'saiMKBaiVTGaN2KFa2c?EaiMQDa2l?Eb08$,blc27 +c-6.02U'=caiMTGaN;HA`Q-!:_o':(^UgP=PC%:aBkhV?!h<<^q[Y#_oBd? +r6,8caMu6iaT'?maNDWPe;"Y['bLtgccab[rl@%DcTMPWbfdoDb0AHm(`3eu[EQ_5`l5j7b08&T +bJhQ@_oL!Jb/(Mf9hSH'[-[bks8Munqtp?0s*t~> +_>aN7qu7!"h9b-\s82forquZorql]srqu]irX]&'s8I-l+Whn&i;NWSs8:pVs8N-!rVQTrr;ZEf +rsAM[gth;gnF#c5rp'gWm-Elnki1[rs8N#rrrN,sr;6Hjqu6Qlq>LHqrr;cmnbiC`r;$Bfs7l]m +r;?Qor;ZWor:g4+o^(f)lgX<-mIKoAoCMVDmdBE#gtDW*$N'Pss8MrrrV-?lnc&Rg-2miAs7X&M ++X/"JoDSUcs8W&tr.6.9.;o"^qu?Y>,9A-U-ggd+rX/])qt^-es8W)trVlg'mG[=!gAh3Pq>1'i +"TA5mp&<#3J,~> +^]+lEr:p0dhQ3?ao)J[fqu-NnrVuiq"TA?!s8Vuqrr3K&s8@!f*?-%kh"ppIs8;iqmJd+brr2rr +)#X:1rqu]nqtpEhs8Vidd&NS"SthmFSY5nQ%%s;cXKAtcp%J(Ws8W#r!<;opmJlSQj8]&Vr;Qfr +r;HR"r;60IbdjdJT)PE(U84QWT:_dJT;&!IQC#_Yp@nUerr;uoqZ$Tls8VWgs8OGErr)lg[N-5+ +)fP?Jrqucqrr;kF*Z?;=p](-jrcK;!*??BjqYpEmrr2iq%fZG*rqufrk..(PUSH`Err3-!rVZQk +_uG5~> +_Z'Z8qu6F)q>0WsEDq+db08)Pc-4DSaMu6u`W*sQaT'6jahcBN9aC_!"YRRCeC)X`rPnlYs2slQ +rl4uZrlQV3aNMcKb0%cDb.l*;]"+2KAR/naAn#7Z@:NeZB5)3tG^4h7^;%A\_uI^S`qd^S`WO3" +`Q%bn!6FrXl,WnJaSF!WbkfK\a8s<%rl4uZs2HS._nj(!VicLPD/*cp?t!SV@UWbW@Us(_?Wpa! +Z+7Ea`l$'Eb/r#T`QQEoa>(l[a2lBTd\7Bj)A66$d*0e\a2H0G?3glM:Xme4a37<`%iQ#e_T'[: +`l5j7b07lFrlc/#`l?'Cbg+5'D,!Z/D7]$/s8VunqYA#.J,~> +_Z']:r;6Els4%>As8W&mrVuiqq>UQrr;6Berr;p+s8M[:,Ud@%p\t*es8V3[#Q4Jsqtg?kq"k"* +r;ZfCdc0`fn*BE5nF,T)lg!KfhXL@@oDSdgqu-?iqu-Hjrr2imrql`krpK[equ$?hqu-?jqu-Hj +rr)j"rquZkrqud;rpAe3l0.L'nF?,=oC(r1o^_2(ea`\>q>^?ks8;]lrrDuer[7aFrr;fks7'8> +)^$AUoDegirr;`]/1Dka.UCg.qYH!s+s8"Go)JRcrr3-!q>'perr3#upAY'tiU#ahfDkmMr;?Qs +p%.tVa8^Y~> +_#FrDrquQfnu\V(mf3=br;Z`hrr)lorr +qYL!OcaKaKU7RpIStD^KV5'WRV4j6?Pf*+eq#C9js8)Qis7-(8s8N&uq>1-Y<$)kq+Fj"_rVlis +q!KRV*Y]l%f_tXAL*[fX)f,!?rri?"rVlfqs8W)trsA>js6["bRA-MSrr30$qtU*grP\_d~> +_#GDNqtg'Wep:A9VT$d%d*g1_b/hTB`Poa4`Poj:q8iTU&&lT7ccc@j#"6qde'5tUao00\`lQCMs3)k5cHF/JaiMHAa3;',X(GXHBP:m_@qB4aAS#UmCMn3RY.hZh`PfsfaSX!S`<"!"pr_[= +qT8f^pr`KT!QN4[bUgoXaMu38^V@LgR=K6jA78qXA7]CaB4Y@T@piDD>_fYn\&,r"bK%TNccsW& +a=#0P`lZ-@g!E,%&.o@[c.(.d`l>d-#S7[Y(db^ZaiRlq$k +_Z']:pA+[e#hRbos8Vuqs8DWjs8E)tqtp3gs8W,t#63X5J,B0C-hr;HWos8)`hs7?6hr;Q]f +s8W'!r;6Hg!W2fgs8W'!s8Moq'_Ct`lKRX$mI'3%oC_YCoC(huf]2u2!WDrqrr`#ko)&"W-ia,B +s8Dips5>4J+s/"3kP5)WqZ$9^>U1X;,:1,)qt0Ao-6q(9p\Omgrs&K#qtp%h~> +_>b&Fs8Mrnl(t2poDejirVHNmr;uusrVZZms82fors8T$s5,8Qq>9mbrrN)rqu?*`!r`,tqYpWp +s8Drs#P.W>R#@H/Sc55tTV8$LSt;^RVR"\EpAb0grr2flr;6EirVccqoDegh!<;Tgrr)Eequ?]q +r;?`srVlcorqZR!rr)cmqtp*ZQ8'k4\fSqu?B] +^Af,Ko[.VaH`=p#_T'pPc-"2M`l?!:_o'I4`l@hqs2Geob/qlW\HZ3`c,S5UcG[T=_o9U7`pUqJ +b5BHoc-+AMa2>s<`4*RWAm&kerb!!WAS,I_BPMC&DL%_b^<+L9bK\2Qbfot,rQ+uX!6G)\qoJ`U +!6G&[kK*M>qT&ZZn]1^QrQYAd.E]`R`59F/]tCq2HZEt;B4tpi?N]5fh=!a1og7bs<'a'GM"Lg!\'f:C.*)a2.Yms2tA]!6Y;b(!=V= +bKeDW_nEE_<)-A(a6NBss8W)8s*t~> +_Z']:qt^6k$/jXos8W#gs8W)ls8W)sr;$9%Kr;ZferVulsl2L__$i^)$q"OOTn,<:d +r;HX-c-l7Wq=+"GnF>r1kNh9hl2CS\s8E2uq#('erqZQsrqu]kqu6Eir;HWjs82fis760gr;Zce +rrE&tr;ZWpr;QTns8Mus#lal'rVuloq#:9m'Cb2Fj5fRrnEfQ3o'l)@nEf8ag\h'SrVHEfr:9h7 +r;Z`os8W)ms6UBnrr2rq%Jp&!rVulos8Up: +kNDC5rri8urr;r:s*t~> +_#OH6%f5b,W3,^ls7uZoqYgBlr;HWoqu?Nl!WW,trs8Drh#I9Os7-*`s6oserVulprrDins!.=9 +q"3F1NhVu5Pan88TV%dIVPKulcKk<&q#(0lrVlfmr;6Hjrquirq>^iPQ*9QQr;6NjqYpNcrWE)u +rr2os+ntru=;N&$)C*r7s8;lrp@NPR(Dn2;T_eZ]p +^AeZ7h2Z)TYJS,f_8jaGbl5]_`r3mU`q[Ud`l,pAd)sYAf#u7a]>_h0a8X'W`p_"Kb5BHbb/_9r +a(b>g +oDSUe!;je9J,~> +_#Fc9s8VK@dJs7FrVl`p!<2ips8Mupp\k[$s82imqtpEgqZ$Tps82'[s8N0"qt^6dqYq3'hW4"j +l0Is9nb)SEmHs2qoD8@a!rDior;QcprVQKir;Q3cqYp'm`rVQU.qWd"tkj7g1q"=+@mIKuCmcN9cr;Qiss8VZh-i +_>b2JoDSI$WN,gorr)lsrqucps8N#rr;cios8W&us82d&s8N&qs7uNfs7lHhrrDums7-*gr;cin +ruV14qu?92OGB$hR$sV?Q^aP:T;89Zb2)O^q>1$hqu-NsrVQWop](0j!<)clqu$TorVbaTqu?Ei +s8W,u!<)ops8Dusq>^Em"TSGur;HWprr!Z1nD(m`Vl-AcUSafYS>)mZUn='@Z0M/arrMuonbr[g +s8W#rrr45:s7(=T)]'S?[IjM!nGiFaTbnge,8k^uqYp0ds7ZEjrr<#trr2rtrY>D2rr<#qrr2fp +s7H +_#Fr9qW=&ZBt(sr]tqb1aihd"`r=$_b/hZDaN4A'&BMl1a2QHJbf\2I`6$*?b/=%pn]:OK.*p#T +]"l7nP[[m/Bk(^fCLUmkCMn-3E0R3/_SO+.a25pAc-OVWcHQ1.prEHXqTSWTqoJZSn]:IEqoJfW +o>psSqofSqaN)9>`Q63AaMu$&SqM%]B,"lgC1h!^@;'CiAmnthY.MNfbeqEia=G +_>b#Es8Uisj8]/Xq#CBjqZ$Nnr;QcrrVZBg"TSB!qY:'is8E3%r;-Hhs69Lbs8MrnrqQTmpAP"& +lc.fXqZ$B^o]u#=o'>AplM:Gfrql`oq"amgs8MrlrVQTlrr2:*i'(G)DlgjQ7o_\%BoC2JOo&\?Zqu?6d#64]&rVlfo +rr4#8pRL?ks7ZHE*$u[P.Tl3;s7lNls8)]sr:p*erVm-#qYL6lrV?Birrgj1k2be+ +rrW#mrP\_d~> +_Z(2HoDAI%T!nIkr;6NorVccorr;us!r`,trVuiq!<;rq"TSE"qtU0j#QFc'rVHQis8;lqs7-'h +rVl]o-h[K4qY%glSXGP3U7nEPT:qsNSt`O8k4&?Ls8Dlor;Z`jq>:0jr:pC9mqVe*;S>3L] +qu?]qrquira8^Y~> +_Z(&Cn+5n=@rf,o`59R;rl>)Wr5S`Wq8rf\`lQ7#aq2Y:_ofj5cI:"Y`m)H?c,7^%aSs3LaSO%- +aM#R,_7k_2B5D'qD/!fqB5;=!CN4orZb+6#ai;<=_p6<>_oU$EammIJb5'-Wb599W`pq.E`r!jW +`q.:O`rF-ZaskQZc-4GTaMu3@b/hT>]s=VoGA:o1An>[o?XRGQASYmd?@B;k]ZA%2o>jeOcH=8I +_8!\(c-=YdJe/M)#ngUqd*]eRakFN>)\No%4j;-p^rF^Gb/hTBb/hTDc-=>K_84+1aihrTa2?!@ +ah4'A:/PMTdHg]0s8DfjrQ"qg~> +^]+B#c/\a%"oS5mr;ZZnr;Q[%s8Mrnqu$Bks8Voo%f?;"rVuTcrr)lnq#C0ik5GAYrqc]pr;R;P +f^S(in)rs*md99%g=u5rrrW&mrVlg"r;HZqrr2lrrr)lrrq-6hrpp!XrqZQsrqu]nrqufrrr;ls +qu$6g!;u`nrr<#trqu`k!;uirs8;oo!<)iq')UbGk3_U,naH#>naZAAo\%UarVuHf-ia&Arr<#o +rqZBgs7F8X*[MpT?17glr;ZTdGTS(S*[ae]qZ$Tks8)]tr;$0drr2p(rqHHmp](9ms8)`p#hA,! +k4J]RrqaP4J,~> +_Z(2Gp[Q%o_tE]us8N&urVuoqrVuos"TA?!s8W)ts8;uts82d*qu?Eis7c9err;iis7u]lrr2rd +rr)jL'RUo'WU_rgptqu?Zn`rCP~> +_Z(5Em+[tKMRU.1a2lQQbK@l@`W!jWaSs?YbT4jI`lQbfdoCaiVQA`l.\ms2b,\qT/ENq8iBO +e]@a4$HU3(`Poj:aNDWHrlG,^"3em/aSs3u`koO"R$[8s^Ve(_a@j\' +aN;NEa1fI,_p6r`W"9@S'bj'XcGI9;a3n<)'Gh2h0$;#MaN)TMaMu6BaMl-Bbf[rE_o9U2c,[T? +bJhN<`Or0P<_d(jcM%8;!r2Kfa8^Y~> +c2[hCpAY3`ddI#4"oA&nr;6Klr;HU"r;6Eirr2rtq>Lp)q#CBhs8W)qs82irrqZThrr2imrr)lr +rWE)qqu$Bl&(/kep?VG9kj.Quk2tRPoDJV"rr;lns8W&qr;ZcrrqcTnqsj^`rquZqqu$?ar:Bp` +s8Dros8W)sr!36$rr2imr;6Kks8Mlps8N#q!r`,urr*3%qtpr8rp^3c +n+c/&ch[M=!<2uqq#1Hms8MrrrVlg;qt^9bi(YC@+=8Voqu-Nh[j!.@+!`5`q#C?ks8)Tk&cDP' +r;Q]qrr2ros8W)ts8Moorrh0AkM,V-rrE&js8N#Is*t~> +ao;A?r;R3)r:n4(`UW[$rqu`np](3k!<;rq!<;op"TS;ts7uZo#Q4W!s8W)os82fqrrE&ts7lQn +rVlfps!RgDq=iL2PaeM6TqS9ZUn46VVl7r3qtL!frr;uss8W&pqu?Wps8Drss8E)urr)cor;HZp +irA->rVuiqqZ$Tprr)fpq>UTsr;HQmqu?]o)ZBU%dC63XTr+Z\Uo'o]Un+BSS"/%&q>:*grVufp +s8N?'s82iqqZ$KmruM(8s7P2>)]T\:-JJ@rs7irA*u>b8,LZAes8Dunqu6Nn!ri6!rr3]0rr;rq +s8W)us7Q&`Tq7aln,<:cqZ$Kmd/SU~> +dJs7FpAZ*1qX<=4Bns42_o0O:d*^1^`5fsAaMu6@aNDa+bm)D7aMu6@aSj6naND<>aM5d;`l#p; +bKS2Nd*2L3s2b5[oZ7$SrlG,Zs2G#S.\UN_AoM*l@q0(^@:X(eD3_ZL_SjR=bK7uQc,mrDa2Q*< +`5]m:`Poj9rPnlYr6#&\qo/o\`l5s:`l5s;q8iBOe]@a4!m&?url$V3aN2NIbfe/Na2Z*?> +'bIak_SsN[$5XBh&dk_[bJhEHaiaV(#Kk-*_og3GaSj*qa2,d;`Pfj;aj%r>Z!'q#?'s=;rVlZi +qu$KorQbFn~> +cMmtFr;?Km!;ufq!qXmor;RB,s8Vuor;HQis8W&sr;Zcqr7h2Nr;QTnr;Z`rqY^?sr;ZWmqu$Em +&)5q!lLFH8n+#Z*l/L@OkkP2IrW<-!s6KXcr;QW:rW<#sr;-Eks7?3kr;QWmrW3&sr;RAiiT][o +lL"02oBPl7jm:XJp\t0rq"j[_rr)ir"o\>rqtp +dJs7Gr;RN2qu6Wos8)Zda.f]nq>:0kr;Zfqr;Q^)r;Q`qs8Dutrr2lprr)llrr2rcrqZR"q>^Ej +q>^p\F[_rqufpp\k3nrqucsrr;Ec#64]&rr;utb5MJB +rr;]ks8Vck!rr9"rVe/Dq>UBerpe%2VP^,]U84N\T;JHVVN[:bo(i=]s8;osrVlcprqu`ps8Duq +!<)iq+8u$0AKVd1(alldrS&G;'c.u7\Fon#rr)lsrr<#tqu-O(qu?]ns8Doqs8N&ts8N#t&cM_& +aeGN'T>pX%s82iqs8MooquZcnrmCar~> +df0CIqtp9j!;ufq,PU`^QtL<0^;@q6aN`&Tb0%iIc-X\R_nj@4bg"JYb/M-1`V@OR`qd^Sb503Y +b5]Q^`[/IDaN)?Jaj.uM`l5j2^:8&m@:a(^@:*PN?ta:gH&]ST`Q$!?rlP8_b5'*Z`lS(t!Q`:K +a9KZ*`lQ0@`kTUm`ph&!b/h`Ba2bs6\W:iNCM73d@UL +cMmtFr;Q]q!r;lnrr3)le)L9'rt+u(s8W&qr;6?jrVu`js7u]JrW)lqqu6Knrqucrrr2Zmqu-O* +m`ODRo^V>9nF>]/l.t=lpA]^CqYhB4r;Zfls8W#sp>>$"m-aK9lKn02nEfSsh#@s*t~> +dJs4Frr;us+8>g5s8;T7V6ehJr;Q`ms8W&pqY^?krqufnqu?Nmrr2irrr)lVrqQL;rV?BoSXb5)'0]WlQm\d)BTuKnc/L^s8N#ts7lKks8Duos8Dfn +rqQNnqYpKo)#jL5m`2)mTqf9prqHHlrVZ]prVQHgrVl`p!<1UMJ,~> +df0CIqtp6i+8Gm8rU\pCBlB_b7`lH9HrlG2^`;[jXb5TUjO9',(IfcO_$/*ZPc"^WFI6ccjPR +bJM6FbK7uHcH4)Kb/DKKqT';lbKS/PaK^4k6qgmEh"14=r;?Qo!r_riqu?]pf)L7~> +a8Z/R9O!;uin!;qEIp\k?rr;ZfqrVZ[!jrr2iqrr)jBrqu]npTu1i)^ZdU)]g1H**i7:3lqu6Tsr;ZTgrW2ro +r;R2phrN\Tq#CBis82fpr;Qlur;6E@s*t~> +ciqYpNos8DiorVm,us8W#ss7QEirr)lVrr<#urr)j#q#C'fq#(*j(A.+9 +OHHB9S=-%CS"6IXU9E/=q"Xmgr;V?Ip\l66r;ZfqrVuoorpRk+W2H)YUn=KUT;/0UW/dnFq>LOO%rV?Hjrr3'!r;HQn!ri/tf)L7~> +`r@%WoB3&jBp-$E^r=O@c,n&JaiDE@^raU6c,RNErQ5,]rl"lWg;kGUc,J#I`m;rO`4WaI>[)#Z +? +df9=GqYpQprr3)le_9csrrrAuqY^3erVm3'r;Z]nrV$9hrRCfRr;Q`rqu?]is7?*drsn)AoCMD= +o^hD7mH<*\rqufrqZclkq"aa_r.4kBrr;rsrri;sr;QWnru(:jmd]c9p@IkElgO3#hTblrs8M`l +s8N&irVm#uqt^0hr;RZ4qYL-epY7,@)'9kA+<;UOp&"L_s8W)ss8Mp'pAb0g@^Q(.s7uBfs8)`p +rr`6"s7uZo"m"\%kiDC8rr`6!rqZQmrVY+DJ,~> +cMnLUrVlfrs8N&trRIgFe*[&0r;Q]trVQNirs&H$rq?BirVc`qs53hSrrN-!rr*u3s8Vopqu-Ef +kGjT9SX>nAUS"3VVP(ETq"OCWs8;]mJc>HDs8Dut-2m]=s8;llhncFnU7IjLU8+HUUS=%s7uBf +s7uX.s82iqpAFpX]WI`tVo\W2rqufrqtg?mrW2usf)L7~> +cN!nBrr4)>rUo?tcO@qTb"C4N.r^:V;(_oDYrrl0N1prNKU-HaNP`5KX/^qQY"FDY`%@:WeT?sR>T +@V'#?\\l>"dETeX`6lTDrPnlY0?;2Wb/hZGaiDTP^Cq7e&.T?g&.],ocGn#LaMu3BaN2B8bgFg, +PL%1k`PTsGbPK9k`l5a7bJVEAZZfhO<+qc\q#:9orVHNns82cp!rMimfDg@~> +df9@H!W;rnrri?$s4tlsrs&H%qt9d_rVlg(rVZWopAY*lr;ZZJrr2rtr;?Top&Y*frr3K"akZ=F +nG)\HnF5StlMLJY!;uik"o%ffq>:)@rqZQnrsAW"rr2lrr;HWorr3N!jQZO0lh'Z8mdB]4jOWMn +rseo&qtg?is8W)rqt^0hrVn2CqtU!]s7Q6c=sG49*Z?OLh>@6Orr;oms8VrqrVuT`>:Ll-r;HWq +q"apgrr`6"s8N#t"Q&8%l.Z.:"TAB"r;?Qk!W;rEs*t~> +cMmnDrr)ir(]OBfXI\2=qtg6js8N&urVccqr;HWpp\t0or;ZZnrW)uRrr2p"rquZkr;RQ-s7u&m +N16c7Tr"EPTV\EY\C:3GpAFR_Jc>NFs8N6"qYpKmrVmr:rr(rrVkU/]R\cgVUSFfaS^En +rqufrrVl]o"TJ>srVlfr+oVH8qY=27*Zl:9-lh(As8N#trVQWpqZ$Nop$u00*k)"FrrDihrXo2, +qZ$ToqtfupW1BTOjneiNp\t?prVlfIs*t~> +c2[hBrr4>Dp?8Z"@@t*H_o0mFaiqoJ`l?!8`5K^.`Q6HLdDsDNaMu@V&L?XRPZ@U+/`^rOC6ai`#T`r*gU`W4'YaSs=1ahQ$=eDNe0'c%Ah(BCqgc-4DQ_njI? +`m;cS`QUF]$]W6QbfnDOb500n`PK4)bL"MW`k-7m8Q0!4kkP/Squ-NrrVHKls8VrrrR_("~> +dJs7Gqu6lus8VoNg$Sb<"oA/mp%nX`rs/;us8)KdrVP=Jrr<#trVmW(r9O7Xs8W)OipGpno'Gi9 +nE8corVZ[(rVZQhpA+LZq>:'er.4kCrW<#ts8Ms#rr;rprr)cp&*`$3nabi2lLjT5rpK'trVlg! +rq?Bcrr2lo!<2rs.fB2>q>L-ds7Gl@-6F6S+1qOMp&FshrVZ]os7u]dhbbg>.O3^Ar;Zcoq>UBn +"TA2srV6Bl"Qe_2le_X@#QFc$q"agbrm:[q~> +ci4%Fs8Dp&rVulPWh[Q/q#(-lrr2p!rVQNlrs/;us8)KdrVP4Gs8O>Cr;6Egs8)clqXW+$Pbb%M +XIl)UTV&!eeElr*rVZQjs8Muls+11GrW<#ts8Mrurr;rrruD% +aSuM?kd5,2LVCM%aV<(GaihfH`l#d9b0%]NccF)HaiDR%aT'EBa=YEL_o9X:b08)LdD*c;_7Q:J +@r5jhB3SVI@q9>'T"2h\aN;NEbfe,Nb/hZDrl"lWJ]R]/!liF,rl6;*bK%]Ha2Q*:\@?s&@qoXY +?s-rE?#X=cr5J]Vs2b5_.EolO^rOpNf6.i=$P!0%dEKMVaN2?=a2cBDd)NOM +&IB3QVo$O"b/ha%a:uV-_8OLDd*'\Q\nFr;?#[RDp@S4Zs8Vs!rVuorqptdt~> +c2S:Orr<#ts8Ud6mJm4cs8;lj!r2cnqu6rr\K]r/r;Z`qf`(jL"TJ5lr:Bme%Go_"oBYW'kORs, +j5p.9rsAZ(s8D`is8W#prr2osJc>KE$2a`%s8MrorVuikrsn#=jRVd7mIg#9qX3q.jo,2_nc/L^ +r;QWo!<)oos848Ds7cQkrr<#AF>7d`q#1-jrqcZprr)ZmqZ#P*,9%pQ@.jR"qYC0err)lsq$R#t +s8N&uhrieTjSo/^rql +ci=%E!<<&t$ig.gVQ7E(q>:3lrr)j-rVuinrr;uk[NF?&qu?Wpqu6Wqir8uX"TJAtrVlfr,Q%N@ +q=gqSR\HILU7e +b5Wmgs6R@1@<8us`6-9GbKJ#Pa2c3bL";Rb0%rPb/hTBilD;C`Poj +c2[hArVlrOiog:?(Amn'r;-9grVuoss8V`O-7L:Ks7u]nf`(mM"oe>jp&4[brs[*/mIKZ2m- +dJs1ErVm6(oVSOpp%eUerqu]o&,cG*qu6Wei?9EhZ2aV!rVQTos5Eq[s8Mrorr)j7p\saOQ_'nG +T:hpRUnX`c_Vk+crVlisrVc`qs8)foqu)*Fq#1g(qtpEnrr<#sr;QZkrVuiqrtP+WXJVkcV4XKY +StD[MR?kter;ZWmrrE&tr;ciorseu+rVuirs8;Wkq"FO_rr3c3s8N&rrr;lqrRW84(E4Jsp&Fmg +rr;]k)Z9R5rr<#qs82cWUo'iUWq6/es8;onqtp +b5Wmdo$qGYBs,4ocH42QccaGP`5fm;bKe#;%M]A5f#Z(Ub0%rPb/hTBiQ2&=!Q`F]bTad>[^07M +B4t^_@q0+]C2J^%]#)D)aNMZGc-OYWb08#LaSj,0aSEmkbJhHBaiMTHaiV`LaihiF`kK0kQ2YP7 +?"7/J@pE>LAm\i'[_BeuaNDZHaMu="`[o0PaiMWHahu*>bg>.sd*9eXbL+PV`QQ?Dbf.lW\.B2^ +&J."Fbf7rNbKA!(a90H$`QA,'%EcT2_o&B[>>\48b38TrrrW)oqUGOq~> +d/OUSs8Dutq>UEAip$LCqu?Qk)#jR8qu?]ms7@`d*$Q_fq#C]CPrr<#o'(l%qrVuod +f]qtik3MI&mHWcgr;Quuq"Xaarr2QiJc>9?rqu]o"8r#iq>UC(oAAg#nF5o6nFQ#4kLA5ars\f$ +qu?]ps82Weq>:0js76."s8Duns8DrqbpOe_+ +dJj^Ur;Z`ps8W&mW2?lsq"jjerr*].s8D`modCjp)^1%2s8Dipq>UEis8V!U)ZTd9rVuosrT^\I +S#N0VV4sQSUT(Kip\Ojfr;ZfrrVc`nrV_rqu-Hm)ZK3LX/2VhV4a?OUnaf^QD3I> +qu?]mq>^9``TV.jWp%\Rd +p\t'dr;P.EJ,~> +dJj7FqY^@#pt9ap@^j"ecH=6+ar&4>_9:!AeB&%7'GCsjcdL"WcGdrN_oTjVaT'F&c-"8OccF&C +[!YtcCLCCTA7K:gEHf%/^r+13r5e`WJ]R&rrQ68(a2Ga.^TWc?=RMKB;`MYaiqiG +c,RfHrQ+uX+j/'R`P]U5bg4\]aMl0Acd0eRbeqZHc-iX'()[\o6.!sSb5'-WaqDe8`P][;`l>N# +91r0&f'EA9r;HWsrVQKAs*t~> +d/X.Crr3?'s7,"4s8W)qpAFphqu7E-s82Ol+=A$T*%Z:.qu?Nls7ZKmqr.MYrVZ9_qu6Ejrs[fC +rV,dHmHWhWFD%o'l/7lL3ia +q>UNps8;ln!W;rrs76."q>^9js8D`'-n-5Y-%l$no)8ahqtpBirrDimrs@NHmH4?Hs8)`lr;Qcr +eGk%~> +d/OXQrVulss8L6B[IV5U,]Uo(-6p%eOarqZQorr2lrr;Z_HrpKdbs8W)ur;ciqru:t;s7u,tXJ)AdVPBod +Vkg8`Qd>9orr<#rrqlQlrquirrVuos!WE#srt58/rV?Khs8W#j[Nct4'd%nunc&Ofqu.9/q>^Kd +j.`3?UX8o;rr;lnr;HWCs*t~> +dJjaUq#(0gqYfcQBPXNYaNV^(aSs?]a;2n7cH=?a" +dJj4Err30$s8VNEg&D!Rq>C'dq>V6.s8N&sgasQm+s\6Q=7,b]s8N&trVtmV#5n/nq#('crr3A[ +kk+67o'Pl9k2#S+rrE&trrN,srqccprr2iqs8N&r!W2eGrp]mfr;6Kg!r;`mrr<#srr3K$jlZ!u +m-j?*mHO*'imR]'!;QNl!<;Kd%fcP.r;Q?"+sJ*K,)H$inbrUfq>:0k"oeGtrVu]mrrhrTm-`R* +rrE&trrE&Hs*t~> +dJj4Err3<$rqP'HV"4?]rVlirrr)csr;$BlrX7U9(E453(`H?)]'5/K_>-1rr2rtrXo,.s8W#sr;Z]pbGq&( +U#,VDqu?]q!r`,tfDg@~> +dJjaTs8Dibn`I,r?F%>gb0J0/`r*mpa2H6HcI0'1&Ki&3&e$hAaN2QDa2lHKb2^P\b/r,UbK7K7 +]pCLCda?=.AXBT0LE`6/)'"3S^+`r*gU`r*pVb(7Y(a=#!H`l?*@b0%iNbJ_33`59-QH#@G/ +?=7#=?sdMS>?SMQ`P]U:c,BV(,fn!F`Q$-E`PKC.b0A2R`PKC0bg4_]ai)?BQjOK@%hNO)bfon* +qT&i_c-=8I`r=$k_oKgCaM`d;8lTE0jnJ`RrVcZo!;k@IJ,~> +dJs7GrVm5ieC+9ps8)KeqY^-g(&S%.q"a)X-6XET+>"o$p%eXeq#C6NrY,5/pA=mfs8V9;p@%A; +kN_d,kO/6Ir;Hm"rquZkr;?Qnr;ZWqq>:)@rpfsmr;$-^p\=Xar;RH,q#: +d/OORr;Q`qcE*_hrVZTmrr3'!rVc`n)#aL7qu?WkqWCm$)&=,.-R%OBq>^KirqbXRs8Ni4s8Vfm +n#hbISt2aLR\laT\(LBMq>L9jrqQKnrqZSFrpp'arrDrqr>Yb9s8;fpn]Ir2WMZVmX/;PiS>i"1 +q=4L^qZ$Nm!<2uts8Mus"9/8trr)j.rr)ihs7cGt-Q3aE,(T:]s7-*frtPJ2rVlisqZ$Bis7uK5 +Tq%pUlMCMXs8W#ur;P:IJ,~> +d/OaXq"41AVg)O/`Q?9Fc,mrD`l@tu(sL.AccjSX`C:^]'H7])#ee0oa2Z'Cb0&bc(Wt1Kb/q<9 +[WbtpAn#I^?Ya7iI\+6k`r4-dbf\#J`l5jo`W*sVaSj84aRR>!`l5s;aN2NHaNMfLaiDB:^W![D +E+s&tA78tR=(PQO@\^iPaMYsArQ5,]rl-#%aMl'7`QHHMb/M99`QHHP`QZ6FN=cX6*#<;9bgQ:/ +qT'Stc-4/E`lcNJ_9B^8bJCcD<`!(>`8gLequ-Kn!r`#pfDg@~> +df0CJr;QZp$fBRss8W&ms76!`rql^.rr)fqs7u]iphqB#,9RmN+2msRrrMuriVilXpAP"!f]r%t +l079kn)*+%q>UHorql`qpAFjc!;qEIoD\dfrql`ns8)osqtg6grt581s8M*7l0S$&o(2A?l0$.? +rVllqr;Zfr!;uBd&,lP.qi!!D,UOS*pAY*hq==Oar;Q^$rqlTmqZ$Ekrr3,fkMkIQrr3)uq>:0> +s*t~> +d/ORSqY's_Y+`T(qu?QnqYpNprqu`prr!s/!W)iTrYkh1s8Di\PF%c2 +U8Xl`VOXd=oD&(Vqtg0erVlisrp]r=rq$-`rrW2ur;Q^:rVuWis677nV4j`PW2ZYkUSj3Rp@nUa +q>L6hrVlfrs8MusrVlcqs8EQ,rr;hO-5@OC(nC3rs82W_rr2p"rr)fprr3K(s7lNhs7!FjTVn^Y +r;$ +d/PcunE02lFBa7/a3DWM_8aI5`l?*Bb/hWB`QQWMd*:-@%h]`q%hf#9bK\DZaOA;la;<"F_T0R2 +Z +df0CJqYgEn%I2O=s8N&ks8Vilr;Q]mrtbP3qXOUbrr)DA,p=QY,9\A(oDedeqr7VQrsSYOlh:2= +n*&ZfjRi3H"oS2lr;ZfprWE)tr;QQjJc>6>"8r&nr;HX#rr)]gp\=Xarr3T,qu?]kk32F4nac)= +m-=9&`;9N#rXAi(pU)Cq)C-T +d/X.E$iKS?Tu6Eks7u]pr;HWqrr2irrr2p3rUg-hrqu8:+;u7<)]Bifnc&Lbqr.MlrVZZac]sof +TpM^VUSb!+i:R'Lrr2flr;HToqYgTsrr;uos+11?rr)j"rr)fprr)j!rVQHer;RE%d]fXKX.lA^ +X/;SpUls^.q>^Hmq>UEoqu6Tps8EH,qXq->*toY9[.XIprr;Nfs8N)urr)lr&-)>&s82iprnj`M +S=7"arVccqrmh%!~> +d/OaWn`\W%?[B,odDjAP_T0X7`lS/%(s'h=aMbd>b08/QA.9.j)Aj"oHcj^YaMm,Z)9U%?[Zt*+ +@V&YTBOu"#N2aA+`Q#s=b08*/b(7Xba90T,a2\(u(sgFH`5/gFEbB'"?XR&I?sRVZ;kph>b0'_- +!6Y;^s2kGb`l?+!b5]Q^`Y-A8d*0dt$P*OW%\(np`Q-*EaSO'TaSs0oaNDZLbg!oC_SF:7a.Zs? +92g>klMLJY!<(LKJ,~> +df0ROr;$BmrQWpmrrr<"rUg-grqucp)?9^4s7lEis7H?krVrr;onrs\i&qtg0drVufor;6EkrseMQmdKi= +kjn?7kj$Ikrr3-!qt^-grr;Qg&,ZA).3'KU-b'$Rs82inqXORbs8W)srrW,qq#: +d/OUOrqtB>Y4;PkpAb0es8N#trr*i7rr)lrrVuohs8W&lZR-G-'Gq`/K_#$?qu>XS&,,IdS"QLO +S>`!SVlA,j@2rr<#poYdDuT;83PW2$)ZX..Z4 +q#13krrE&srVc`ms8Dp-qu-@:'cJ&8Zhj\$qu?Tko)8XhrVlco&H;_,s8N#trVkNJU8"@-qu4qA +J,~> +d/Pcpp>i5cEOoe4%r'82be_\7kmS%ut_`l?*=`;RgVa9'N.bl#W_aSWu.aRR@Nb5TK^`\#-KaN2KEair#Tc,[`:\Zp]l +ARK"T=^bK9>%h00^;J+;c-4DSaND`Obf\#Jqo0>kb08)Mc.NX9'G;"FeBlCXb/2!9qTAZU)90S5 +aNVfLaND`N_TBX5c,dhi<_Q.eT&BSHrrMukeGk%~> +i;`fUr;Zfr!;ufp#5SU?hr;Z]ps7uQ?-Qs`X+sA=7rVHQarr;oq +rq-3tbhqgXlL"''l/qR9rsSf&qY0map\"7TqY]^[Jc>6>!W;rnrs\l&q"aa_qu-HjrVlcprseVW +md9H3m.C#CmHiBdrr3)rq"t'gs8W&ur:g1$s7lCB,U"JAqu$Ems8;iqo)AXgs8;iq&,lG'rVuop +q"t*XlL+,snGE7cqZ6Worr<#t!W;rps8W)\s*t~> +h#@HTrVlWm&,Q>$c)@Msp@nC_rVulqr;HZorr)j1qu-Qls8Vojc6=/H(E")6;Z$=jnc&Rg!ri6" +p\ka%p?S':U8+?TVP']_^Z>(arr2urq>^Kos8<#srVZTlrr2iof_u$Rrr;uto)8Xhir8rWdJa4I +rr)ios8D`ms8Mus')hFFUogMjVkU#`V4soW^%M:%rr3#urVl]rrVlfms8Dp-s7l::*>os'q"t$i +s8Drsq#:6jr;I''rr)fnrVuosrr)ir$N'h:VOF*Lanu&9dJn^~> +huE`Tp&>^'qWOnoA#6uX_T9[8`PfR0`Q$("bS\LD_o9R1`6?-;a2cQ3%h]d#*#92HeB#c%aT'B_ +aSa'UaT'6s`PT)oBPD$a?=I5PD2,1-`6$6D`5]m<`r=!]`lQ6Db5TTcb09k-s2b)WhoGf?qoAo[ +aMu<@rlG&\q8`QUilM,=dE):/s2b5["3AO%`W!ptb0J8VbK.W:]sO`lA"ss2Gbob08#M`mkh@()*.ec,n&J`5Ka +iVs&[r;6Bjrr36$qt9aXqY^?lrrV!*rql^Gqu$Korr;oqs8Vcls8N&srr<#srVliqqrCd',Tn6T +,q7[Iqu?Qis8;`nqYgWqqtpU +h#@WXqYL$frVulrrtbV.n>iA;o`"ddrVlisrVc`qrVlisp&4mjrr2rtrVum3rVGMO*ZZ%6)]p?Z +q>1-gqZ$Kis8Drlru1n8rVQWls8;fnptq.,T:hpTSu89beb/t?r:^0grW<&trRCiHrrE&ns7QBe +s7-*es82fls2b37s8N#tr>bb7n%#EuW2-2cUS4KWS>u8Xs8;osqYL*dr;Q]ls8W)srs\[g*Z7lK +qtg?mrVuZlrt##+qZ$Knr:G*$q"jshrr;io"98B#rr)j+q"2.kS!fu$qu$Hns8Mrr!<2orrr1sX +J,~> +iW&rVs82irs8D`m$gc#U>)g&7bfn)G`W!k)_T'O:c-jMRa2c-:`lcTMa2Z9Dbe#eD(Dn#-'+he( +b0@uHbf7TDrQ+uX"N\g2aMn.r'ue5=aj%fC_7cdNCh@6hA6ieVEgjZ?`UV%KaoTT+f#[m6"3ep/ +aSs0a`Q#m:`Q#p?rQG>caN4;!"NAC#aNF+qrPnlYs2tA_rl4rV!62[m+i_L9^ohooARShJ?=$uN +AmoPb\AQ,(bKA#Nb/hZC`Q#ss`rF++b/V?Ad_rl,YnbgXJ=E_]/$A[CaurVcWlrVQKjqu6frq"X^ajSs`~> +iVs&[r;6BhrVmB*p\+L`r;Q`rf[]Zps8Drs!ri,srVm9$s7lNls8;ior;?QnrtbS0rVQBhB-/QA ++<;USiW&cSs7uZls7uZoquH`nrrE&rrt3N'mIp2Ap#b_tkPYA[r;$Bj_Z'H1qu6QoP5YR]qtpBj +rrDrqrs\/JhWsOqlh:/EmGQ%arrE&qrri?!qYU0brX/]"s'$co=Sr-qpAY'nq>UIHo&0NI"oeK#rqu]nrri8qq"apfrrW)nroa<3~> +h#@KUqYL*ers\l(r;!@fb4Yc4r;HWos8W!+rr;ipq#(0lrVlfpr;Q]q(B441qtL"u)'T\0'cJ@R +s8)cqq>UE$PU7dt:o`+jgrVZQirVlisrr)lrrr2p(pA\/9*`Vt7 +qtL*i!rDoorr3?&qYp4i*@\,dr;H3crr3H$oWFpXU8R;Ps8W)urr2rtrquctrr)fUs*t~> +iVs/]qtp?ls8Domrtt_0j*4mXW56U%c,R`A`lQ6?aMH3@b0\9/`#H_=cd'kU_SsL7eOBib',V>n +&\uu;c-O;K`l\2#rl-)%bfn/I_o'I5a2ZBD`kJutZkQH?"%,BUU.kUaND`LaSs3Y +`VmgUa<8L?aNEC*%15&Cd)WlCaNMEBaNMcN`Q$9S3slaff$)2*a:-59d)!)#;G157aQ`U$rr`2r +qu-Hm"o\;mpA4aKs*t~> +hu<]Urqu`p%/]\ss8DutkKW2Ys8W#r(&\(2s8;orrr;ipr;Q]qs8Muqs8Dfnrri&oqLg?s,7,5< +ir&fUq#CBlqYpEm#6+Ptqu?Bfrr3Aag$%\lkk+B,iUHaDrrDurs2+d4r;$?ls-!?`r;6BjrVuos +r;R/iiU,t.o]P]1l/9__rri?!s8W)tr!*,ts8N#qr;HU8rVuTd?7-t"p](9is8;cks8W&sq#C"l +-70`[[f>mss83H$s8W&Om-Wa!s8W#js82fprVlutq>:0irrW)nroa<3~> +gA_icr;HZos8VuopV`rGdJin.s7G0]WiD_pVk:#iWLo:)oD8Idrr2os!WDrqrr<#trZD1=s7Q%g+s'_Us8VurrVQKl +s8N&ns7056+;Z6/s8VZhs8NT(s7k0:T:VO`qYL6hs8)`ps8Mrr"9/8uroF*0~> +iW&rVqu7<+rVufhpAXsLSo&q5\\?21bfKb&.*0BOaN2N@a2H!;aiV]IbKIrCc-4SSd*cJ<'GqZ& +#S=Jdb0@fGbJsM%rPnlYrPnlY(X^.>`knEl@Ui_W>%hP\DN1O.`l>p:b.l!tb4NdO`W!mRaSa'V +aSO$ZaS +hZ!l\r;6uqu$Hls8Vs#s8Dutp](6lru1k6rVucns7?9ir:m!9*ucLT ++H-6prVufqr;-EjrrrE"q=sIXrr3&Kg["k+"RkdGlMCM[!VuWks2+d4r;$?ls,m<\r;?TprW)`k +rs\AUlfRTtjRVU0p!<:0rs&>qq"jmfs7cNmrVum-rU_Nb-[5F[rr;`ms8D]krsA1!+rqsW-KG.' +nbrRhr;Q^)o\\s$g%,1=qtpEmrr)j!rqu]nrVuop!<20]J,~> +i;`iVr;R?-qYgHoqY^3;UT<5DrqlZnrVulr$30o"s8Dutq#C?mru1k6rVufos7?9iqt?U,(_[o5 +)N"IhrVufqr;HWorrE&trVulrrtkM2s7PcLQDCFVU7n3TXN^;3rr)irrqXD0qu?Kk!WE#ns7lTk +s/>qrs8W)tr>,D4qu?]kp%6/$X.lSiU9LGlWK"giq>C6orr<#mrr;rsrsntt,p4CQp[nIbq#CBl +p\t1"mT1AD+!Mrhs8;ogrr +iVroVqu7?.q"Xmgp@%eDX_r$F[DKo*bfn0,`[JpOaiV`HaiqN?aN;]NaiMTG_o^0>e'-(_JJ8Y, +)]f>qb/MKG`luI$aSj-Y`>ut>b0%rN_T9d/[:% +]Y);(aSs6[anNk!aiDNHcHHV(%U.B'b/h?DeBGbMa3Vgj&.T?`!k-=i`q.7\`l5d;_7,8":/Y5h +kk+lSrqlWlrVHTnj8XW~> +huUEorVlio%KHA+n]'hdnEfE-l/:Cqs8W#rs2"^3r:g3\s69OYs1eR2rri8prVHBh +rtG%bhr*trkOeN9p"8%!s82Tcqu-No!r`&rrVn&?r;Zcms7lNQ,Te:ap\k!hr:g6kr;52",U4NZ +>4MC_s7-'qqu?Hjs8V +irB&X!WE#prseo'rr;ijg81n*r;ZNir;Zfrs8NN+s8Vlir;HZpr;?Qorr*N-s8Dutq=ajep;A:3jrqcZprW)orrt5,$abc^hU7\'VW26Nfm/$YYr;XY5qZ$Nn!<)Qhq>C?ns7cNk +rV-^KdrYGP4s8Dusppm&iTqC3=s8Muss8MrorVZ]qro=$/~> +iVroVrVmN/qtp6cq"ss[kdPABRD-bZaj'h-!6G/Z%EQ`BdE9STbKn>N`lQ:$aqqt;bL+eZ^s(!J +WuDfj'GrsNbfe8K`QS5$rl,tt_o'L:bg"DVbeLcK:hFEL=]f0IBlh/&a2lEEaSs5sa8j6Z`<4-$ +aNFM+!6tMe!m8U(rl+oWs2b5_qof)^`r4!Xb5TW`blGueb599[aoor5c-4>Ja=,'I`Q#p=aNDZG +b/_B?_8j-ECLLFW@8L38>%q/\\%TZ!aN2ECaihm+b5TI*b0S5Ia26*:#mh)Re'Q.W`5^0G`lYIs +&/H#m435FW`l@Vk%E5uu_og-9EDB&$B"RO2s8;inqr%L)~> +hu\5/r;Qru +s7Q'bq#(..lJLjnp@e+Ip$pV\s8W#mrVuosr;6BhrVm?+r;ZNkrr;ifi%H0"K`:l\rr;rprn/bH +*?cn6nc&Res7-'jr;HKcrr<#Z!qPF*rr3&rr;QTn!ri,srr<#tk5Tr~> +ir9,[rVc`ns8W'-r;6KlkcU]+p&Fsir:Ksf$i^,)s8;Wdqd"aAqu6Wprr2p5rVu]ls8;osrU6[, +'d"Hsq#C6is7lWmrqZR3rVlcoqs_=eW1]cPW2$&e]CtRjq>1'is8Drs_uBN4s8N#rpAXjcs8E#u +mf*4crr2io_>aK7*WH$8rVlisr;?Tirr;]_m)6$+USji[SYW0NV>:#frrW2trVca$rVZTlrr<#m +rr3o5o@tf5,(TLdr;Q`oqu,+n*YoY=;XXM`rVuHf'EA(3s8Duml`lnTTrRYXrVHQorr2inrrE&X +s*t~> +h#A/dq"X[^qYL6a`cYO:b.u*>b0'_'.*0HLbg\[Zb0nV[a2Gs$P33=(5iIBXtdoa2c9Aa8=$Ya<8XM_p$$CaNVC7#nL\"cc4&RcHFP<#nRR\)*H*gbf@ir +a:Q>(^r=@A_5Um09j2_mn,<1`s8W$#qtg0drS[^+~> +huE`R!<2ut!W;opru1Lah>dNMqXX[drqlTjs8W#orr2q2+=(pup\t13r;Q`qr;ZZoqYL3jpAaqo ++Y"H\p](9gr;ZWnqYg]sq>'sdqtpBm%ccF5mIKT;lK[:,s8N&nr;Qlqo_/0Urpp!_rqZT1rW2rr +r;R$$pAY!dpAOgcrsS&IlgjiDqX!S=hoGZp"oeApqtp +ir9)ZrVcQl%fH2$oYI)nr:g6kq"t*jrr<#srr<#t"_8PoC[h#rru:q:s8Musqu?Kgs8VinoiE%U +'I3;Ns7lNlqZ$NnqYqH4s8W&nn#VqPU849VS>NCHo_SU_s82WhrVcc6rquf\rpBabrqufprr)f3 +rW<-!rr2lrrW)iprrW0!q#::,o#7N'T;&*^T;/K_Rdp.Ms8MuqrVuip"oeQ$s8)KhrttR^+WM\M +q>^Hnq"rek*>9\C8c8Ves82ierr2p,rVucls4sTFT:E^kq#:9m"9&/qrqucrro=$/~> +h#A/do_/1[rVli\N)3BR\]`LFaj%oJb0'_'s2ZP2f1-&S=4>I>b/2!7c-4,Maj8)K_o'4>g.;u$ +&JNI5bJ_EH`6%u!rl-)"_o9^@c-=DM]5q:h@:WVV>\.ZAZb+K#d*9eYb/M?>_T2r$`P][6aN4;' +s2t8\qTAfYm`#j[b0%fF`l5j5`Poj +huE`SrVlotq#13nf\ui01\UMArVuoqr;Q`rr;6EgI3^$b+(++$s8W#ss8;lps8Durs8DulBd"fE +-H>o^rVlirqt^6kr"/c'qt^6ks5Dl.n*fE/lfd=,rr`8mr;HTo"8hcaqkF)[r;$?fs2"^7quH`p +rs/Q'oD/%VqYL-i$hi]Lo()>Cn*9-%ao25BrqcNir;-C7r;ZZos7cQjr4+%!.CJsLs7aD^)^H[M +CARi,qu6Tpnbs-sq>UEkr;HZpi9BR_r;ZfrqtpBnrr2fqro=$/~> +iVrrXrVHO.qYgu.p\Omes8N&grr;rrrt58,q:)13US-$1qu?]qrqu`oqu?]qjo9i~> +h#A&bp@eCZs8Vr@@8Vl\a3E#a_o9^rastEMaN2BB<='9V&4saZb/D-:bK.]BbKJ8Qa2H9K9FVdK +'WK@$ai_lL`VdgU`Yc\7b08)P`P-4nB3f"OB4bsuS[uMS_Tg:'blc,0`l>m:!65#W$-('-b0%rN +b/h[&`q[XS`r?P$5?`V;.6Bcp&4ggs8)fpr;QiqqYfUWJ,~> +iVroWq#:a$s8UR(mf3=dq>'sas8W!0s10X*+!MdR-f=drrr<#sr;ZQkrsAZ$qh$1=,9iiXq>LNq +s8W)srVmE-qYBgas469%o'br0n)'pbr;?R&n_iR&p@7P6m.BVn +rr3E'rVZQmrr2Wes8N&uq>Lm#\1&gQ\G,g.,pX]U-&)?slMgh`%fZD(s8Ud6lKd1(s8Mrnrr33$ +s8Mrnr;PaVJ,~> +i;WfVrr3W1s8Musrqc&YXi1&4rr<#trVZZnrr2os$G%Q,(E!u0,2E"irr<#s!WVrorsJ`%q1'S- +*?C^GrVHKrrVuosrr2p7rql`qqZ$,\S=uXLU8"NZ`9mHqs8W&ts8Mrsrr)l6rr2rqrW`?#rr<#t +rr)iurr)ilrsJc(s8Dors8;fprqZQprr)ir!<)fprr'\4s8W,us8DusqYq9/r;->+Zm6k>[.O'u+<;F;++a:drVliarr;rrrX\r'YG7\b +TB?%Js8;lorqlTmrr2'[J,~> +huE`Ts8P.YqtU-iqq6.$DQLFle'ZF[`Q63EaMl->b/fAB%29d")\9X*_oBa=a2H3=bKJ&Kaj=H* +&.o8$d`qd6rQ$)$b0%fEa2le`Q$6LcHsq]b0J,Oao03\aNVd*`X9Z#_o'F2`l?!VaMc*0O_\<3>Zb06?=RMSU;+=Ta2c0Aaj%lKd)Z..s3)8"`l5sAc^,+P$^]DoQ44KC&.rU- +cH6(*n&Q'_aMu6Bbg"5@AP>QoA&IO&r;QirrVcZo!rD]jkPp&~> +irB#WqYps%s8UC$ec5[Kr;?Qhs8W'?q"f+Z+X\QW,TOJsr;-UEo +!ri,qrr)lss82ir$-qo+na>]+le:t0rseo+rqcTkr;Q]nr;6Bh])Ma.s8N&ss8O)9r;HWnqt^!a +qtg0dqY0XKlKdj)lgON?q"jpdrqc`rrVl^"qu6Wpr;6Bjrr9k7s82rqr;QWo!<2uq!rMonrr3u4 +q>^KSl0S3Lp'r;!TE,:L.2.j,o[,(oUgrTsO]rtGD/r;Zfa +jQPdXs8Vfmr;HWorVlfo!<2$YJ,~> +huE]Ts8W,u$2=DlT;]!irr;usr;ciqrVZX3q"\qQ)BKk5*>c9cr;-?krVQWfs8Dus[/M!H+aj%Y +q>UEo*<,m7rr2ikrVulsn=$5JTV8!PWLh#orquNjs8Dor!<2or])Ma.s8W,uqYqB2qt^6iqtps8N&urr2lqrql^6rr;utq"asWZ_j@o +X/DecUnWsiqu6Kls8VuqrrW2ps8;lqrtPG/pT>\],IOa&)AjM8J+NU:rVulrs7-*drVld*p[knc +S>2tXrqHEirVlZnrr2'[J,~> +huE`RrVnkSp]'Q%BO\$R`R!#Zb/M9>b0%fE`lcNDa\`H\+X%U9".7NZ`5BX9`Qu3:a3N5##7V1R +@F3-?rlY2\s2lA'`l,j8`5p*B`QG]!CLLOR>\%bdP.JiW^rOO7aSs2daT'<\`rF!]`lQ*;a2n8% +&'3)Bcd0tabg";QbK\5Nao0O"dEg+^bg=YZb/hQA`l5d0_SjI8ahl+'b08)Pb/hU#`BhMbaND`T +dETG<_5M9]>@_2J>?GEN>)9i*]#)S3aNr)PaMQ'Abfn5N`l#d9bKu4R#S3Vt&e5Hi&8';5a2c3@ +rl4KLs2tA_%Eco@c+pYr7S$^*g?nJ/rrN&rr;Zfl!<)*\J,~> +irB&XrVuoq!<2rs#2Rc.s7l9bp\u!-s8N&uq26[G)C$LT+ccKus8;oprVlg'pV%pt-mhshs8Voo +('"72rr<#trr<#ts8UR5lgXE2lKdF-s8W&trrW/urqu]'rr +hu<`VrVcaGrV-0FVP1%iq>LKrrVc`mrtP;+m[Bc;U8=Z^WiFkArr;lms8W#ns1A:-rrrB#s8W)prr<#t,5qE7lf?jP +da64[`l5s<`l6-Le^N!sg?%l$q#(0lrr;rqqu6]rr5/F8s8N&ur;QTns8E&rrVca3q=CkqT:r$R +WhH)]SAP"!rr<#or;?Hks8Drprt##*s/-SW)B9V6)'OP'rr)corr;Qgqu-Qo$iU+cU8XTNc2@G; +qY:'lrr)iYs*t~> +iVs#Yqtg3frt"ei\n+mI]ZA@FdEK\N`Q%nus2H5)bgFkdC_IHn)]9J!D:?\S`6ZNDaiMiQS.-#G +&ie7aao0B\a<&IDa2lM]\\Q%q]=br&e_8EueC)[fbK.iH`rUb/hTA`Q$'>bL;+E'FkT^ +&J#IdcHO>Jb08#L_o'Laa:ZS=bf\/UccaD";,^.jT&8r6rVlrsqu-Kn!rD]jkPp&~> +iVroWrVuoqrVm,Kj8]/Yo()_Xs8W)ss8W)uru^t7rqO#O+s7pH/0]'3p](3hs8;fii%$/r+scm\ +s8Dcm!r`&qrr3'!rVQTo#h&)-p@.>1k1K\5!r;Ncrr<#t!WW/uquZlts1/+`qu?]pq"XderquN\ +kM".sb/_H=`lQ9DaN) +hu<`VrVca#rV>iPY2AmNrs&H!qu$Korr2lrrr;pU?m(]472qu?Wls7aO6 +TV\QVW2-AhQ+$2[rVlg"qY:*jqu6Tnrt,20r;ZZlL`@BU)]p)tp](0jrW<&trr2rgrr2j0rr)fp +s8VfecD.24T@Wr9rVuiqqu?Zpk5Tr~> +ir9/[qtg3gr;R?!c":FG[Em1HdEg%X`Poj:rQ$2*bf/5`d[CXW',2$!$rPQpcHOGS`5p'5&etog +$e!>B`5qr#rQ$)$`lH6Da2Z0@a2P8iC1(R[>[hJbV8CEubKS;Va2Gpp`<4-$aND??s2tA_rPg\3 +aj//Qaj8Jff$r'g^p^GW\[]5`^;7\(_SO(%]tVCq]Xthe\$`EC]#`:Of[nHoc-",Irl;ms$HgT: +b0%fH`l5p7rP_+Cb08D`b0Ir?`O1A6?=7)9>[M)Ra3\N, +&/#Kc$B*Ab0%uRd)*8G;H$e/XlT!MrrW/qqu-Nrqtg9Ss*t~> +h>[NTr;HX$gtCTbs7GsVrr2p#r;6Eks8N#sruUn6rVYLt-mfrW*\1I[r;HZqrqc@f*@2aSj8]/S +s7ZEms8N#q(&7h/g$S>#mITW-h"h!Mq#1*grVQQls8N#ss2"^7s82d5r;HKgr;QWhkhOM&^r"(2 +_8F73`PfX0aN"+r!65#W'?8,9bJqWD`m3N6rV6`5naYJss8VuorrW)kr;-C(r;Z`qp%O4f+sA>Aq"aserTaC^s8W)urrW2sr;Q^!jPf7Y +h>R?Tq#(-js8W)Ys*t~> +huE`Urr3K-rV3Fg[e0Uts8W&pqu-Knqu.];p&FsdgE7[^'c7`5=6KGWrr;unohH;E(F%f:s7u]g +rr<#ur=K#.s6,Z:S>;mUSu8RCq#C6irs/H!s8W)ts8Te3s8DusrVmc5rVZQkrquNShU0 +ir9,Zqtp?js#KuOicA78Xi\c4c-=JVb/hTA`Q$!Ab/hZN`QuiW\d&ia',D/p5/bpud*'SRc8Z1K% +hHM)bJ;6@rlY)Y*6H4=`5][4Zs[NVA79%YD/c5^ai)KLcHXDLaN+8!]u^5rs2YJc`Poj:aii#\r +n%h.`k8X_[_9Mi^r4:5`P]R3_u%:N_>_4`_8F7.\$WKG\Am.We^i6pb/_NB_8uZ!r5eoX!6+lU6 +-.ErcHaJRcG@N,K5>(&?s-W:>[^o[Yedulb/q]EaN)NI`l5s;b0%`H`5omBBFG4S$BrfWbJM3=b +g"AQ`P]^ba8jB^a:6;9cHO84CfXD7GgP[Nrr3&sq"Xgf!r`#pkPp&~> +hZ*TSrr3&mdc:?,s7cTirVlusq>:'gquH`qrs8N"s8;`P>9G?n+;#tLhuEHMs8#eD,9J,Bq=jge +q#:^Enrr2rtrVulrr;XY5s8Vuqs8N?&r;?6Ke&]T/`Wa?! +_84%-rkf,`aMu3UEo +r=Aqurr;ENmcO'-mechNjl6:>!;l]oq>Lp)r;ZZoqu+EODUSRXs82iprW)uerr2fqrr2p"r;6Eh +rr3>\iTf+bs8W#mr;?Nns8M*ZJ,~> +gA_Z]qph@FoD&:`s8W≺HNmrVdlbAp&4pd<$3.s)n>Y:rVuZls8N0" +rVlcq%dfIPTqJ$NSZ/^Mq#CBnrr3-#r;Zfpqu-To_#FB4!<2ip-Nrr;oiqu?Kio#Io6U9:Mn +WMZJd[-IViq>L?ks8W)ts8W&s&HD\.qu?Ni^hdc3s7H?hs8W)t"98B#s760fs8N#srs\l+pZ&-A +US#I#r;-Ejrr`9#s8M-[J,~> +iW&rVrVnnVo]NA]A#d,_cHOANb08)PaMYp8b08#J`QuTEbf\2B4q&AG((h2j^u!;[ccn6W().@Q +d)ErJaSj9[aT'@&aN)9?aN)<-?"mt]?X[G_G-/Nta2H9HbK@rNbJq*6s2kA``r).q^V7Fs^VIRr\@B$I\-fj^^!5!We^Dac`3IB/a2?!Fc,e&Q +^;%"/Ch-US=&`O9A7p.i_T'C2c,[rNaN2B@aSsY8"'Pi)*2s8VlfpAOsi!<)'[J,~> +huE]RrVlrIgA1aJ!<2or!WMooq#C.7r;Q`rq>L?fs8VrgBI+ZH,on0XYl=OuKI@`c-)1,5s7H?c +q#1?prqu]o#h\4sn+#]4jkg":"o\8rqY^?ks8W'#r;6EkrVsb6rVuiq#Pe>un__d:`;[S'_Sa:0 +`5]d7_SX41ajntof\,!3f\"ZtaMu9Aa2Pp4_o0I3a2ZK`l1P&U_#FB6#6+Puqtp('irr<#erW;ulq#14# +qt^*aq>^Kmiof@Trr3&srr2lrrr2$ZJ,~> +iW&rWrVm0%r9:5cfD>@Drr2rr!W;ons8N!?s7lTnq#CBinm`aW*uu(7,-:_=r.61-*Z^dBs8Vcl +p\=^hs8MrqrugppQD:+OURJ'XXlB$Or;HZprVc`ps8Mrqrr<#trr)f3rr;rsrr2pTrqQKmnD2F1 +_SO++_o0L4`Q-!<`5K[;bLP4sg"G*4f\"Wra2Q'=aMl'6`5T[6a2cWdlh:>X^]+*0rVlfr,5V?; +pAb0ir;Zfnr8Y&TXf&4rVk]f[VsOH_rr;rkqYpNpr;I<*s8Vrls7lTgs7l9eq>('irr2rdrr)ls +rr2p+rqlHip +g]';4mD*RNNP!*Sbf.E9`m)iSaMGX2b0S;N_8!q1^<4[Ed7k2_*#fP-(6R1lcb +`4WRf\\,Sh^V@S!_7mOj[^3EM\[T)[]tV7s^qI4`Za@-O]tV:s^qRFm[CX2obgFe]_8uSps2auX +6--g]_7n4Dc-4JW]sjME +kl1Y^qYpWrqu$Em!p%qrrr2urqu6]pq>U-kq>:*hrVmo4s82]nrqh6p*$cLL+XiHCX!&W;++a:g +pAb0hs8MrprXo))rVcZos8DoCnEK6!kO[d#qu6]prr)lsrW3&srqc]nrVsb6rr<#trqm!!nCbn$ +aN4:t&&Z9$_oL!Qj6lU8q"ad`qu-@%q"jpeq!R1rdEBPL`50:.rkel[fBW,,_>aK7s8E&squ-Hm +rr;lsqu$Em"Shfms8Mus%K5JOmI'N5oChY4h>dNSqYpL3rr<#trquZkq#: +j8],XrVmH.r;4(*aSGc6qZ$Qnrr)fpqu?]qrVnnRs8;corV1dc(*!u+(a=q-W#cp*(jkrUpAb0h +s8N&urr2rss8Dutr;Zfeg5;MtWLoi^Tt9UgrVlg'rVulrrVZHfs8Mus!ri/sc2R_Bq#:obU8"6mq#(-gqZ$Tpk5Tr~> +h#CRTp>^U/IC-r;ai_H7_8aaGc-"#C`lcQM_nX(/]#qn/dF$KR&.09j+rM/;d"_T*)@g]CfYY\Q +`m;lOb/hZDaN2BCai;?>\"m& +bL"AO^TV*F +lMpn`!rW&srVm!!p\XshrrVW@iVid.rVlirr;?TlrqcQmp&=jgs7lWmr;Q`prVuii\0NLE+rW)llrW2rrrr2utrqufqr;R/siTfjplLOT>o%r:'s8W#orri8p +p\4L]s!dsIqu6Wpqu?ZprVZWorqufos7ZHlpAapcrqu`or;Zfpr;Q`rrqu]kqu7/Nm,mL-s8W)m +s8Muoqu5[VJ,~> +nc/Re!r`,tqZ$Tp49,9Zs7lHccDn;Ds8;oqs8W)qqu?Qnr;Q`ks82irqZ$Tos8W&rs8DW!+U9EOTTuG#pAFpes8W)t +s8Muok5Tr~> +k5YGZs8QF(qu?]lp?JP]?EM5kccO2J_SX:;aj8/ScGRlHaiM*0^;7e1a2cBHacHZB(*OtC*E3^] +#7EQFeBZ4Wa2uKKbf\#G`Q$!Da2H0@Z+X.L?Wq/TAp8a@`Q$!AaN4>"rQ+r[c,^%1bfn5Lrl$>+ +bK7iJcHXGLaN_fHbKJ;bZamca_SX70_S!=cZE_6sf[eU%ccjJOb4EjWbobKc_R-_\]Y;(o^U:2U +bL=_^d*KkS`l5s>c-42GaMua+ +WEW7i@%HH[s8Mlhr;QfnrTF32~> +lMgk`rqlcqrVlutqtL'grt3i3oDejhrVuipq>^Kls7ZKirVlllrr<#ts8W,trr4)8e0Q1a*@E$T +,9S1,qu$Bkrr<#tr;6UBn_Z'B2!<)os*<,m8s8W&t +rVZ34`PTI,_oKa3]Z%k8i:?dBqY^3hs8;]lr;7T7s8Mliq=NO``Orat`l,m?i:d*ErVQHks8Dil +rVli5rr<#urr)`prVZ[(rV#L7kj[p/r:BI4iVicWqYpHn"TJ2jp\Fae,6%Q@q>L?hs8;lrr:^!_ +r:BX-f>jDTNGWM's8Dutq>UEorVlip!<)fp$KpRBkLon8qtpBkrqc]pjSs`~> +nc/XgrVZ`qqYpZrrr<#tq\]+iXf9\CrqlWnrr2`ns82iis8)cps8Vljs8W&srtP4U+;c.5*>o_7 +)BDNHqYU9ks8W)rs8N!1s8N#trV#T?US+?YRAR!bo(i7`rrW2tr5&C4rVQR#r;HZqrqucqs8Drs +(\?+q`59C0a2Pm.`Q$9bpAY*irr2lqrquflrqcX8rVHBiqW,rG_S=%0_o'OPpAFderql`qrquZl +s8Tn6s8DusrVmo:s8Mrrs7>0ZVlHnoUT:2hS?hSZqu?Zqrr)cmrr)isrr2g?rVlfrqYgHhrqlZn +qt9d[qXO1#e]!rJMJ?nrs8;lrqZ$QnrVlis%fQG*rqlWfaJ#8uU#>bBrVm$"s8W&qk5Tr~> +kPtMZ>Q=[!qu$HlnA]ZUI(7;Abf[oD_p-BDbJM]MdE^"a^W+C4_8XR?aiDHDb/^Rj&0i/@*Z>e& +#qsiVbK@oJaiMQIbf[rE`Q6-DaO.u=Y?,:??"I>\Fa1[?aSj8sa99Z0bfIg'`W*q+b0SAWaN2QJ +aj/2]cFC6l]tq_/_nhe1_oBd?b08)PaN"4us2ZD,aMPg0 +a3ViRc-Ob]a3DiUb0[)iSp#Nt8OUYNd*TtM_8c>o'$&,5`kfL(LJplBAAn' +lMgk`rqlcqrVlotp\k*njOiSns%34ds8Duss7u]ks7uQls7QBkqY^?ls8W)srVu`hs8CYX,U=NL +,TnE`h#%'Krr2rsrr)cms8Mrorr2fprVuoCiofe"m-*NdrVlusq>:0js2+d2s8;j2s8N#ms8)KM +a2Gp4`5TX2_T'^Mli$_\"oeGsr;?Q`rrE&tru:t9rV5R0c,[c=_o9dIl1k)Ps8Dusrr)cps89_4 +s8W,urVZ]qs8Mus')L\No'l/Ao'bo!dJs7As8;cnrr3)uqt^-es!%I?s8VWbjO)5PPalW*@j`cS +.Np8i.OH>^HiO!Arr)irs8DrsquZltrVZ[#iooO\o`+pgrr)utr;>XUJ,~> +n,NFe!WE#nruqCAs8;orqY.:j`;'?3rVHQns8N&ps82ilqYpNerr;lorVmZ4rVccnq#C9D=rn\%% +ilQ3-JA4mrVlcq"9/?#rr2rtrXo,/qXrp8U8"?TU84ckq=sjdrr3'!rVaS3!<)Tirr3r5s8;WO` +l,d2`5T[3_oKsSlh^SVqYgBlrr<#trp]jdrqud+r;#O0bf.E6^;7kO9 +kl:\]7/Qr]s8Digs8VuYIp[W1_TC'DaMc9Gb/)'3aMZ0If>c%V_84+1aihoOaiVE:d*T3e%MKTd +'b1Z\\C/[GaMu9?`l7qu$c^9/bfn8T_nE-UAH#p@@qT_'_o'L8rQ;mr!m8U*rPeiYrlY8^&')Z. +^sC9Qa0N4h^V[n&\GilC`6m>kbfRoE`lQ=%bk9-UbTP!Kb0/#RcI'VF\@B2c_SX+(bL4PSbf@fE +`Pf[9ccXDIaSj9[aT'@!a2Z-@aM4$GBHA8Ap!]$&19b5TU7b/hTB`Pop>b0%`Jd`0bQ +ZET=6JQ#<7%MKQo%2KWn&e#"OgsF6a_SaCmaT'E]a:Z>1_nX-l@8fp)RH*o=s8Dflrr2usk5Tr~> +l2Lb_rqlcqrr3W-s8N&umbR")s82irqu6Wms8;lr"T7Y*gA(XH!<2lo!<2uts8EE&pMD)u/K5ra +e+s%?rW)orrr`8tqu6Nn#h\;,n+5i.kMQ7a60)#jI2rr;uos8Vf8^:0irrN,squ.c=p](7o-RU5k-RU)[-mKfV*?l[G+XA0Z*2`T1r;Z`q +s8DrrquQiqqu6cQl07.&s8W#Xs*t~> +mf37bqZ$Tp')_e-rV4X4Z0hSds8Vuqs82iorr30"lttDJrr)lor;cirs8W'*q=SJD*%)IC-.)Dc +rquforr<#ur<<5up"c+/rhp*qVQmQ'q#10jrr9G+"98AurVlg4rVuokb.Pp7_8O=3_o0mZlhLJZ +qY0jcr;lotrr2rrs8E&trqlZlr;QZorYkb7s8Vl\gWd^U_nO++ch%25rVlfrs8Dlor5&C4rVulp +rr`9!rVZZl&,G.oVPpDfVl$MqSA+OgrVlg#rr)cnrVlfrrVdl(8CU%rVu`ns8NT,s82irqu?TKUS=HYf_tXG!<2-\J,~> +lMpn_rql`os8O;=rVcT\Y%2.Ibeq]Oa25g9d)O)H`Q#PYZI7CUc,[`BaiXP*'?\GAbfJ#QcUe3I +)[-TVYL(_Ab5B9Y`>?P8b08,Tccp&bK.`F`l6!Ccd0eO]Y)"r]tUVPbL$70 +#K=a'_oU3Nb/26ub5KC"aiMNC`Pfa7^7TRT?!165?=RGDHaUf6aN2O'bl>fcaSs3ZaT'C*c,J/f +2%1!.)&aMGj0PZUmfBs$b!s8Vrlir=N~> +nc/Xgqu?]qrqufqqu6uPht@$Jq#C9jrr2p+rVlNcs)B>6M"(<8lfId2*rVlNM`5p-8 +`5TU2`Qd3+q>UEoqZ-Wis8N!&s8N&ts8N&tqYpWpqYpKo)#aL7rqZ$De&08F`l#mWqu6Kgr;Zco +rr9h6s8W,urVQ`oqYg9j')UbRo(2MGn*B2aiW&rWq"ajer;S)Br;6Bhr;HTopVn^),p"$G-QaZS ++=8Qb,V;c!,p4]jq>UEmrVccrrr;ltqZ$Kjrrh'>kN(Irrr`2rr;PjYJ,~> +mJm1bp\u95rVQ,^Wm1PCpAb-lrr;utrr;`fs)&u*KC&C/qu6U2rVZWorr)ijp](9gq3rNG-RdL> +rr;uprrE#prr;p5rqZ#CVPL,aU8b??p\b'js8W)srr2rt_YsQ8rVliqs8E#qrr2utrr3Z-k/>Ba +]>;D$_oBsWmeZq_r;-d@rW3)`)p\b!i!<2uq!WE#pru_7=s7O8W +)'9Y0'd+;6',_o=+ +nc/OcqYL9kr;SbUo$VPhKuVEWbfn2E`5p3B`P'.>9*c)Ie()XX`6-9FaN;WJa2l*5bgOMQEWcLR +$*hn)cH=/Hrl#eq`5BL4b0A8Yc-4/==D_\]?>+7uO1E!A_oVi"rl>)Z_T2l"`PojaN"+u'ZS85`Q6$:^Un>c9N#ZN +n,<:[pAO%OJ,~> +o)Agkr;?QkrrE&sr;ZcprsntZh>dNKs8Vims8Vurq>UBubU4JR+=j)`r;Q`rrWE3"r;$?l$hjVq +s6cquo_AIdpA4dfrrN,srr2os&(L";p%.G.j8/fUr;-3ar;Q]urqlTj_Z'H4s8El5rr<#ts7u3) +`ll*4bJD*5ce[m[s8W)trr3)tp%eU_s7QBhs8W$;rr)fqs8N&urr)TTh8mgY_9'dMq>L6m*Y>&s82Zir;QZp,l[]:q>:*gs8VopO^ +)^g?/[*S72q9(!%-:mt4s8)Zns8N#q!ri/qr;QrpjQH$hl2:Par;-9eroa<3~> +mJm4cpAYO!r:.q)[IF+hs8Vrprt#&-qZ$TpaWhZ>)'tdKr;?Qos8N&u!WDinrsSQ#q>]f[[ds.l +s7Z +Qa+d%mIeF<'-BX;s8Vrlrr)j!rqufrrqm&YW1'NS_#!s,i;\<~> +nGiLds82fls8)fpr;SbUqV@QHDm7C+cHO8N`5BL8_9'sIV@!\A&Jp&Kb/V`PbK@oJ`l,d@b/qHE +^s0lSPKV5%d)*fBrl+oW"NA3p`le;,&^82+@VK@_@UNhiQG:5Ma2c:#b5]Q_`koeG`l5p:aND`N +b/D5^_nj7.rl+oWqoBo&e'ugjb/VKE +_oBjCcHX5?[D9A_]!Jrsda#qTccsPS_8uZ!qoBc!a2Z6CaMu9>`Oqdb>Zt?.;cch/?&Z80`Q--D +rlch6aMu6@aNDN>b0.l[D?paf(DR\t&05k?NiUINgpIb+'dq/D`lQHH`qmahb/M9=a2Pp0RpSc_ +;Ng&4rV$$Gs*t~> +o)Agkr;?QkrrE&qquHNkru^@Wo`+sjs8VomrVHKmqZ$Ne:+7V9+=A:%a8Pf2s8W)t!r`/lrr3,u +s7lWfrr3&tq>^?krVlrur;QZp#h8)0p$VA>iq36M"SME]q>C6l"9/2nr5/I3s8;j.r;$6iqW?8F +a1oL2^rFCIl1k8X%fZD+s8N#trVcWhq>:*hqZ$Hlqu6cop\OgerrE#srtG;(p@e@FbeD*=`5]sc +rVlWmrqaG0s8W,us8;oo!;uinrr!W3s82irqr[)6oCDPDl07$es8W)qq>:-j,l[]:q>:*hqtg +mJd1cpAZ<3rU\[=UYl(KqZ$Tns8W&rs8)cno1C8P)AjS86cAlrqu$Hqrr;ZjrsAT&q#C!cs8Mrl +qu6Zqrr;usrr!?'nXZ/AV4aT`WQFr0s8Dors8Dusrr9n8!<;los8Nu7rr;lZe&BDD_Ss:-`7aDN +s8MupqY^6grql]qrr2lnrr2rqrr2lqrr)itrV6Bl!WE#srt+PC^W+@4`6%BGs82irqu?]1rql`q +rr)d.s8)coh6`uVWMlhsUSt'(p\b!hrr`5tqu$ +n,NFd!;lcls8)fpr;SbUrT:LrKa2c-=cc",SbV'PH(`""u.\kG8bKe5L`Pod>^WamG +`QZ9LbL4ncb/;KDrl#eqaN;K?`Q69Jc-"#;ARf4^?=@YjPearO_8Z>ps2b5[_T3tA`Pojd*]b?\&,bm_n3Lf^W4aNcHOMSa2>am^^J-&bg4\ac-"#C`PqbpqT&ZVrl?/$aN;QC^rOO< +bKJ8^fZ(5#^;Rap[*7.Nb0S5H`Q#L1!QiF\`u;q<_8aBdF^A6L:K(A"A7^;)_SjI:b08)PaSj+& +aMkp+^W+CCFEVnlLCFq3$Id/;c,%cT:^\'FR`WCebg=N1`rF-Zao9 +o)Agkr;?QjrrE&sr;Q[!s4Z2is7ZHl/H#PCq>L3es82inXX##2,9J*X-"lZ?s8W)ss8Vurq>:3h +s8W&trVcWnrqlWmrr;oqrr38lhXpL4m-<^#rr3/ur:]g\rr2p"rqZBf_Z'N6rVdN.rVl`ilI!/[ +_SjF4_p%$4r;Z`oqu?]q#lX\qq"ORZqu6Tprr2fms8N#t"oeGurr)fortbV4qt^$\p@nLMcGRT? +`m"&Sp\k'es2"^7s8W)ur;ZX1q>1'grr2rtqu?Nks8D*AnF>o9p?;%krr3*!q"Xdcs!I[@q>C0i +rVufqqu?Khq#,=X+YHdop\b'hb9ePX;Y^7fs8Mrrs8Drrr!rT's8Drqs7u]pk3_Bnhu +i;Y_,pSOIkqu6Tkqt^9ks8W)ps8)`jW?3#q*#KV=+(OX0rr;uss8W#sq>:3hs8W#sr;HNms8;iq +!<2orrr*H,qtI^iTV/-XUoD?%qZ$Hkrri?"rVlfqs1A7Js8N&urqPa*]#2A&`l5m?i:m3MrVQQm +rVlKiqYpBlr;QZp"TJ>us8N#r!<2lq%dhTZ_o'F9oDeUcs82ir^Ae*2!<2uts8N&u'Dhb-qYfVN7s82ikq=aZ))]L/$rV6?kr5g*)(es`'qu?WlrVlZn&cMb0 +rVlcqrr)MpVOX +mf*Liqtg0dqu-Bk2XfID;//]s2Mmrs2P)[s2lk5`l6!B +cdL"IXMMop_7d4_^sUQUbK.iNb/VK>^V@Y(`6?QTdETbO_oBdnb5]Q_`rF!c_o9U3_o9[:aN)EE +rQGhuf[@OJ_7mFgfA+Zra1oX6]#Z)8a2uHEaN;K=b/hQAUN'F::ek#!=CtF<]thS+b0%rNb/jS% +,07d?^;n.7ajA8Yd+_Y.%37UZ^Ve4:UC@nI3RGp`a3DlOr5S`W&]W#;a2l +o)Agkr;?Qjrseu+rr)cprVuoVhZ*WHr;Ru=q"Xdds8W)sqtZ0s,UXZT.Nfstr:g0ir;Z`qqZ$Qn +s82Bds83B,q>^Kos7k7Ap[[e3kN2[B"TJ>rr;QZp"8r&nr;-Bts7cKlqYpNndJj+E(&Rt/qu?Wg +rp@_@a2Ym1`Pp$qrVlfors&K"pA=jdqYpBpqYC!brr;rnrV-`rq>0sdrr<#ts8W)t)?'F0qtp9a9`P]g7fB2i-s7QBjrVum!rr)fCrWiK&qZ$Tms8W&srVZ]mr;70+s8N#qrr<#Ukk"?5 +oC25 +m/R+b('":5s8N&trVufmfqbhCs82cmr;Q]ps8W'=s8Mupq=f^h+!DI:+W)8Zq=X[crVuirqZ$Qn +s82]mr;Z`prr3W*s8Vofb*&ZtUSslf\G,murVlfr!<2ur!<2rsqYga"p\k-grr;rCrrOnA)'5LMs8Durs8N#hrsJ](pu80ETV0-trVlfsqrRj.~> +mf*:crVQBi2".PXBs#V!b/hZC_8FODc-4GXcd:%dC'G%Z&/6B)$ZFV?bf[lEa3;WNbfS,Mbfn5P +aN4;!)T^(Dbf\&O`6HQA]T-$+@ps%\Ee2'G`l?*@qo\r[s2OlU#LC6,bf%TGa3VgBc,mrDaMl9E +b1Y7M[)C/,^V$hTda657aq2S1`lZ9@aN;QE`l5p;a3)L#b:q&]b/_K@`PfX,^;%P(b0.rObK7iH +a2>d +o)Agkr;?Qjrri<"rr;usrrhErp\Omgru1k6qtf_r,p4?V+CcbIH: +`PCL/q"t'ir;T%]r;$0`qu?Zgq"jmaqt^$Zp[dtGnF,l9mI'H5nac5Brr;uoq>0p^rVHEjrVQWp +qYC*fn`/$4b/hU&oCW(\rr3-#rVc`qdJa.Brr3)ps8;iorr)cpqu$BlrYGJ4s8)cqqr$].o^;;G +mHW:&s8DrbrVcchrYb\7rqjee,9eVbs8((e,pY)6r;-Bls8)cqrVlTi!<2rs$M3$FkiMjErqQBh +jo9i~> +m/R+bs8W,urr3H+rr),_U"9)8s8Dlorr)lsrr2p9rVZQglt@O\)&a;2,93r\q#C6kqZ$Kis8Dup +rr2rorXer+rr)NiXJM_bTr4`m^[h:$rqZKmrr)lnrW)forr`,qs8ULG(B+12s8N&urr2rsl,^cc +]u7h/_rgmnrVlco!<2ip!r2Zlm/I(brr3#ur;?R.rr;olr;Z`os8V]Ncb7B<_uB<&r;Qp!rVc`q +dJa.Brr3)ps8;iorq69lrVQQn&c(@fV5L8dVl65bU@\3\s7cQlrVZWprVlfqru(h9rV=DY*?6BM +rV4SW*?6HqqtpBms8)`oo`#I$s8;oga-i`lWnR@LrVuiXs*t~> +mJd:eqtp?hs8VsNp=+1iQG(#WaN2B=^Ve=DbKA#Oc-+8ObJQgU%Mg6.'G(A/cH=PTbJqoM`m2WK +b0'\(rl4uZ!6Y8a&BE&=`k''*An>:T@V9k?]Z'lkq9&`Ys2OlU#K4m0ai)3@b0e9Hb/qiL`Q-'= +ajAYa[_0i$b/:lp`R2cIrlG)]s2b5^4j(smdE]YH_o9[?d+-b+iS`VMhV[/Bf[eU&dE]nR_Sa:1 +aiqrRaiDE=^;%b/b0JG\ahkR)]Wg;7_Tg+"aTT]*a2lBMa9TZ,ccO#I`lIYk)TK_4b0A&M]:EYB +>[16/=&`gEZamrs^aSNpRaT'Bi +c,IK$J59*>E45E +o)Agkr;?QkrrW/srqud!p".ptr;-Eur;$-brVlfrrr*`6p]&E7.iBWY)^le#de`qBp\t3mrqZTa +rrL?mrqud#rqQ?fq=OL]ruV+4nE]2qeBlFY_8!^t^r=XNh;RG\o(i1Zq>1!erVHO1rqu`nrqu$, +^WaX;l21>Trr<#trVccrdJaCNp\amfrr)lorqQC!rr;rss7Z +lMpk_!<)os%K?>$c_IZCr;ZcprVlfgrt5#)a\F,o*#oY:)Fi'Jr;ZNjrr3#qs7?6irVca-qq%4. +USOW\YeKo1rr<#sr;QQor;HWorr;cm#64Gts8Mojd/F(Crr)j+rr;cWbeD!4_SO.5Ys8N#r +s8E'!qu6TrqY^*f%.`lQkMtOZhrEqip\k*k!<2cn#QF]$s8;Wirr2p1rTMM +mJd7dqu-El1B%%=ii6^2aMu09`l?!8_8X[D`5':0a2Z*;ahc8t2&?`C)@dMf/[!OKd`'ARai;0; +prNKXrlkDe&C8VC`kIgC?X[;I@W[@CaN4/!rQ,#YprEZ__9C'C`PU'E!Qr[db5]Hpa2u]Ubdt0t +aMkj%]Z&:Dbf7`FrlRjS`l5g8cd0h]da#tTbKnetkjn66mciimiSNJOl0e-6o]t)Td*L"_bfn2N +`l?0Fai;TLaiViWb.+Xg[Bn$+bf\#KaiMNCai`#P$-C$'`6ZNFai;?na;<"?`l#p@_o9a8STeOL +<`<%%@U!fW]>F?a+Ni$XccjJL_nj+*`7WX]";;D6fA0%9*t`qY`6--=_92YrrPnlYrQ5Jj`5]Hh +BMV<)M!G!>!rM`jkPp&~> +nc/Xgqu6fur;HWorVm#Hd/X.?qu6fur;6BhrVlfr'Dhb)rV;d6+s\!R-RU3\mIUAXoD\aiqXXXc +rt5)*s8LX?p[Ie9ioU4?rV?6cqYpQprquNi"TSDrs7lTndJa7JrVccqr=]#*iQ8jTaLoO3b4GQ- +s7cQmrqudGrr;onrr)ZgpA=IGg;gIhP*1iaMM[4KN/ijRLQ.UpZ-qLjlL"-7q"F^`rt,//qYgHj +ldi/3!<2lq +q#2'-s8Vlipfnsc,E0Yl)Bp["qu?Wis8VTf$30u&qZ$NJnE8m3rrE#Ys*t~> +li.[us8W&srr)fpqrsfQq>1!gqu-Nno`#U%s8)ZfP:IRl&0W/>+E$K7s8V]irrN#soDT="s7ZBd +hk[0IT;ncl^@M3rrr3#tr;QQpr;HWms7uWss8;`nq#:<@rYtn7rVulrs8DrUb.ks:]#D\6p\t0l +q#C?mrVc`ps8O8?rVuosrqufrr:K7.cG[T8^:h1m^VI_%]XthrdG"*_qu-L4s7uWns8;ckrVlis +rVliold*Se_SZ-Iqu-KmrW<-!rR(TJrVuoqs7cKlrVlTl(&n72rr<#ts8;iNZD4FrTrFreTtL!q +rrE&trVlfqrVulort5&#oiN1P*/DBU',i+]q>^Hirr;lprVuco&,cD+qtSd4V4adCqYpHnroX62~> +mJd4cqtpCMqt]mI_Ja;*`lQ<=`l?!8`Q6 +lMpn`!WE#qrt3uAkPtP]q>UEns8Mrorr2rtrVlfr(An.3r;?8<-m]fO*%2sYTD&<[r;HWpo)AUf +#lW3>n+#u2io^4>s7lZmqu6Zqrqliss8Vln#6"T$qu?HfdJas^rVlfmr;HKUaMYs2`l,[>s7lKk +rVufos8Drrrs\l(qXrpj[%3)+J:N4LHS^%rI!p6fJqJ]+It<<5T"3G;o(E%\qYg?ep\jses8W)u +s82W=a2lNDoDAIcrr)irrqk+B$2ac!s8)]ks8;fdrY5D3r;6Els82irr9!>:mI'K"-5n:-,psRbq#CBjs82ipp\t3mqYg`ts8V0=jlPM$rrDlVs*t~> +nc/XgqYq**s8Murrq<:lc2.>;q#13is8W)nrtPD2s82]cHm0UG'GVc1,Fe?*q#13hs7ZF&rVHNk +je&HBTW+ii]_;3urVllrrVQ]prr2rjrW`?$rql`jqU,9\s8Drsrr<#pkf:TY^rOF1e,T=Ds8Dup +rr)fprr2p-rquZjs8VrXgs*dR_T0^r^GNaB_o0O0_oBd8_7mXr^<>F*s8W#sqtg +mf*@eqtp9j0)5)-f5ken_oC!=a2Z*9_oU!EaM>L(_o9X;a3)<@dEBk\>nRn_%M'Ed%t;gPrkniT +b5K?YaSEsh`lGfi?tinRARoS,]u.b4rQ=KJ#04m-`Qc9Pc.Ct:gt^N0e(EL8ioK7bkiqI"k3)!nk25"LgYC`Nmd/iXdDEW9`lH9M +aN)NIa2c?Fd^-$"^3 +?WrDr^;It1rQ+oZ*6?.=_84%#_p-6M\c`QM&iL76")H?1b.l!7bK9_*s2b/YrQ+r[%EQH,^2[1H +=anoiqtL'Os*t~> +li.(dr;?HirrW2Ohu1-k +rr2rtrr2g&q"jp^nE%NQOG82_GS>4?GB\4QEcH&;FE;SGFa&4_GCfaL%%4iemIpDOq#(!^s8N#t +')qq1rVb:eGT=G +rr2rtp\l!'s763iq>-U*-QFEO*%pOTr;-Hnq"Xm`rr<#srX/T#s8W&ts4$?!i;W`XrVZZXs*t~> +kl:\^$NL)(qVn3KnG`I]rr2lr!ri,rr;Zcq')V_,pAb0fro8YR)As5))]^91rVllnrVuQi%KH4r +X.c)_T;AHfnc/F`s8W)trVulqs7ZEsrVufls8Vinci3nC&c1n;^r=@0_TUO's8Vums8Doqr[n0L +s8W)prVlfpqVf3.`5KR5`P]L0`5T[4_SO(-`59=(^r+1*_o9C"^te\`qu76)s8Dutrr)lrs8CNd +`koalrr<#rs8N)tdJa@Mq#CBns8;fpp&4sgrr3`3s8W)rs8:TSVQ?\oV5U>`de!M +n,ECdrqc]orVmZ3p$^tT@:ZdecG7]KaMu-8aND`L`l.krs2Z&"`QQ9:bfdrQ`cMq0)ANnt#mZ:3 +b/VN;rPnfWr5oYnb/h]<[qfGZBO,.^F1B9+aisb,m)TFPai;9Fahcn_VC,eD]9< +eBQ4_beqK?aj%oIai_u^]Wo#U[c#WXai;?BaiDfM#L('2aiM`Hao06TaSj7!a32QB`5g$C`lGi] +CL(7J_r5ScU*PBP*b0S/RFpSlk'F=sWaO85IaN;6;d`fqXb/h[&`r4!Y +apuV9`Q5s5UKUJf?)Qi[qrRj.~> +li.(dr;?Hjrsee[f)PdLqZ$Tpqt^-er;ZTl(B=:3qu?]fqsL"&+!i$Q+"11brr)cpo)AXg!o)`" +rq-E`Q,sKnc/I\s7lBf +s8N#tr"]#!o&dfWKn+VrF)c;FH$Xd[FEDYIrcJrsFE_tVH?sj`F`_hWK8,8]`oHIVq>:3lrr +nc/Xgq#C?m$1#I%g]%-Js8;iorrN,trqufpqu.?1qu?Qns7?'PQlm.a(E")8;tp:ir;-HirW)ut +rX\V(U7@pNVl$WXp\Y!jrVuiqq>^0f#Q=]&r;H?hpWrj;rt=eN^;Rk*aN3-0s8D`mp@eOcrr2rs +rr)j$j2ALC`59Cj_`>QK^qmn*`5Ta9`P]X3`5BI._Sa.%^r441_Ue/Ts8;iqrr;usrVHHlrr)ls +d(mc=fD#7Drr)lsd/F:Mq"Xmas8Vuns8Drpr;cirrtYM1rVccqq#0g/Y,A4sYFhkkQ07i=rr;rr +rr;oq(]XF5r;Zcir*^W\(EFZ-oDeagrqcZlr:BmfrVlg)qu?WmrPkb)T +n,ECbrqZWnrVmc4oBakk?]r(<_UHiWbfIc@`lQ[_&RCNZbq`5]sV&Wa3Mi@[Dg/(^pCYt +e&]PX`l?BH`P]U4aNVoXf]DDRbKeu.l0I['naZ5@lfmd)o(2PJo`"M5oCDA=oBto.lfHsMgudt_ +d`TSG`5BR8b088[cICIMWkH-icc=2La2uHMa9Ti(_TB[:cc,e$rQ+lY)9L+Ha2Q!6`5TI/\;k9/ +<`<1!AS,5P]Yhbfa9Kf.`l5s=b5TU*ccFMTcHaMa;&C#b(D0-]f#l+O^ +l2Lh_qYpKo%JIlrs8Vrqrql`mq>:*grrE#orYth9qu?WjoZ;2'.30WU*$lgVci*nArVQWorquZm% +fH>+s8N&urm:'*p[.8*rVm3'pA+^fs8N#qr;HKqr;Q]qs7lQtrVlirs7^T^rYPP4rqlZjiP!@Q_ +SsIFq#16js8Vrqq#Cm@Hn`RNON.l\&EGf`;F`qtSH[C$`G'.nLFa&"OG'\I^H?aRUGB\.NG +_(:/b3ns#s8W)rrt##'qtg<4aiDKfp&>!jrr:@E!rTiZrr3)qs8MrnrqcWsrqu]mrr2utqu6utk +j%O#q"47AdJj1Gr;Zd!r;6Eiqu.K5q#CsrVuorr +r38\n*]T;s8Vrnrr3#ur;?Tprq$/?~> +nc/Xgq#:a$r;>9EY42Jfs8MlmrrW2urVl`prVulsrtt_7qu?Tho>bhr,8M47'-/);bl%Jtt +n,EOhqtg0drVmB%mGbNmC8nkYaNVlVbfKe&,K@mNd*p=cb/hTBa3D`Qbf[nr:^[pH)&a8/%gf5^ +cH+,HaSX!SaT'6k_n2F?A7K+VBQ:Q$^rjg?b5KEW`r3s\`lQ6Dr5],``lQ6Gb!sYSb4s$Xb500\ +b/ha&aSs0cb0A2TaMuBFaN"2"4ibX_`QQ]KYf+Z&^pUl*ccO)JcHXq\bf7Q:_oBsPiU,:,](&gcd`p(X_ofs@dETq[b599[ +`rF-[apu\?`PKL5`OAuE7U;bPqu6WqrVlfurVQK]s*t~> +n,NFcrVlrrq>C6l#hmu/s8W)qrr;rr0DthLr;Zfop\jsgqYgHgqtT<4:a@81,U"0N,TnLIs7l?g +s8N&ur;6Eirr2rtnGN:kmbI$so^:o(rVm$"r;$-cqu6QlqYpBl&,lP)rqcJ$>i#/Sq>UBirVQTo +s7$!ks8;`mq>($fs8Mrr%J]turS#0.`5BL6d/*V;s#pAUpAFmeqYgElq=3@=ML^>1I=$9]F)l8C +H$ajaH[9s^G^OsfH$4=VI"$KfGC+RXGBIkDFa]"Xiq)pArVmN0q#1$]s8W#H`6-3erVZQjrVc]p +rVd&us7p]Hs8Dlorr)l]rX&O'G1??as8;orrVuNhs8W)tqu6ulea)Pqn+5l8eGfJ!rr;lop%\F^ +r;Q]nr;HQiqZ$Tprq9&**@Fk\rqZTms8W#qs8;lps8Vrqs7lTmrt>5)r;Z?Hn*Jp2s8Mrns8Voi +qYgHoquH`gs*t~> +nc&UgrVm!!r;?QnrsShrV5)u@s8Vuqs8N#t-N3uDqu?]qqZ$Norr<#prV>T6:*CSr*#TJ/*ZHA7 +rqH0es8Doqqu7B0s7cQlqu?N0T;/<\TVJ[No)8RcrVucorVuiqrr;in%fcG+rVL#,h>.*Js8W&t +qu6Woo`"dg$2aMsqY^Bmrr<#srY#8+s82iQ`5TR/_TC:)rr;omrVZ[>rr)lsrr<#od)3N4^V%># +`Q#m6_o0L2_n`t#_o0C-^qdec_E#BF^;.V&^r+.._Sj=,k5PAVr;Z`ns8;cos8;ospWgLla6N^) +rr;rqs8W)ts8W)tr;ZM0[f61%rr3#urVlfbs8Dp)s8MmmER4@Rs8)]nrVccqrVuZlrr;uss839! +f<;?PXei%nWgWGWquQflqu?Wos8W,ts8Nu8r:4NTq7jNmJR"arVulss82forUBi;~> +mJfEJqYL0js8DQPb\q!^[)0f$b0J5RaN)3;`l63Jai2B?b/)$<_9:*?D`8:E)&a;(&J>?U5h3om +c-=;MaMu7!`>HV9b/)BFaN)#I?=7;R?tOP_^!+aEb/qZoa99N%`lcO(aq)V<_8XLE9LZG3d)sYX +aNOJ'!R/^baT'Btbf\/Pb/hZD`l5d7c-kCq_o'^B`l7nrJ'5^S`m_W._oTj3\[9l1aiDBCcHt"f +d*0GH`Pp0[mbm$[lLOK3mHa31mHNs(m-3g-o&/aN;THa2>g7`l5s?aM#gC:n?Rpb/M9km^q#eF>u>'7>>e^+\]E":aMH +nG`Rhqu$Em#QFPms8V-;oDS\=r;Q`qqt^6krVuooqZ$TgrV?3bq=M(0,p=?N+!qpI.j?B?VtU/h +s7uEgrrW,qr;HWprrDimrs.';p$:i0jSSrV"o\H!qY:!Xrql`qr;Zd(qRh>Wm/?qYrVl]jrr<#g +rX8c$rr1hjiVWQNrr2lr')qq+s5_A@_Sj@2`r#B-r;ZfrrqQs!q#16fpA=7!W/#a!HN/@VG'%\F +H$a[UFD>,^;+X5K:KCb3CN"9=I"-KhH$=:KG&h\NIu:,;nF?PYr;Zfnp@eC^s8V`@_SO=gr;QQi +s8Dp$s7uCn?'YHfrr)l]rW`46[U0"6qYL6drr<#srr;lrrqud'q!6o3kjn98p#O[%rrrDpoD&4\ +rVlfo!r`&orr322*%2gJ])2L,!rVomr;Qs!q"t*eq>($hrrE&tqu?Zuf'Mkhrr33#rVuljp\Xph +s8;orp&BO~> +m/IIlqu$Hnr;ZZ/UqZO$s"40Js8Mrms8W)us8)]os7lWlqYpBb[:pj,)]0>2&euZ3,>Y--rr)lm +q#Cr;ZfrrVuKgrr;los8;os$iIVa:[J,]qZ$Tps82fqr;uuu +s7lTkrs\`$qqc)Ks8N#ts8N#sr=/f(s5qSE_Sa:1aSkl5rqd!"rr<#tqYgHkrr4\4cbI64_S*\" +^r+%,`l5^)]X=]-R@K\3S"H[g]tD"k_8O4+_83n&aMl0<_8=XXrVlolqY^@6r;ZNWcbRB=qZ$Tn +s8W)urr2rtrr2rooi>.Us8N#t"9/8trr2p+rr;utrr;utrr;utrr2rrrX&W(ph$a4rVuZmqu-Qo +rVuiq!<)iprr<#t'Dqb-maA)=UT:AnWhQE]p](6krVZ]orr)j(rr<#tZPb#*)S,_Drseo&qZ$To +s8W&nr;ZTgq>UBl!<2ut#lO4hTqA"'p\t0l!<)os"9/5rrpg#=~> +mJf9Hqtg9ks8)9AO(EXE`6--?b0.lD_8XF4ai_QAbg4,I`P]g?acT4+%h]Tp+qkS-$k4tCbL"G[ +_nXCoaT'6u`Q#p=c-F2Dai(Sj=CkcCC2]NO`QlcQbK7`oa99N%`lcO(aq)S5aN2PpEC@mnccF;R +a3+D&rlPDgb/hTBaSO$jaMu6=_ns1;gr2gd_T^9E`Vmeja3M]R_7.(qai1fpf#?"R`l?'?cI(%_ +bK7]Fh;[#:i9p+,o(),0lK[g,lK7?thq-Q1^:2)-eD'*OnFQ;IqtTdQmd'H?q=sF;dFHh;f$_UO +]Y__3bg+/Mai_6&\[U&4cH=PV`P_\o1WISY_naS`7ss.:_nj@8bf[oB`l?*>aMu<@aMu<@aMu<@ +_o'RH +rqcHirrW&go^Mm2~> +nc/Ufr;R!#pA=migXuK)s8;rsrVn2Bqu?Zos7uZgs8Vlmc[.2c+!_aS)^6FT+Xqlrp\Opds7QLol&frl(@Wm'@G'\CTH?OL[I"$m'T@3!"rr3,ur:g*err3,_a2Z'QrqZZpqYgHmrWi?# +op2RckkP,UrVu-]#QM5pKsgmWrUKmes8Drsr;Zcnrt=VXmHO<;l0?jls82ioq>^Blrr)lsrY,2. +rVHQooOo3d,Yn13rr;cns8N#q#QOW!s8W#ss7uZos8;lrrrhuRlK[F/rrrB$s7Q0bqu?ZppA]X~> +mJd1crr!<+qu?]SWi"JIs8W&rrr)jCrqufrrVucpq>^Kkrm,j=*#]n6,o.F<,TA"Tg@Y1?qZ$6d +s8;]l(B=.,s8VocSsZRIV4ss:q#16lr;HZqnG`Ifqu.*(s8Vll^qRRu^;n%>p\=aoqY^0hkfh,eh>[ +m/IIlqu-Qos7*R;B:?X8a",9SaiVWF`59R7a3MfPa3W2Weu`ahPj=aM>N(>A75PA87=@_T9pDbfn2Kn]:aMs2b5_&Br;;bfe#U3iQE2bfRcCa2@kq +rl>,_aSs0X`r*pX`rF#+_nOCAQ?#%)aiquK`lcHD`P^'Ge$??q_SO*mcILFbaMc3?_8+(8d)X2Q +i9]1@gZ7_jnEoc:nb)PBhS#SUXehr$Z`0n/\$E0=X0KFgiU,sokj7^%oC;DCm,[<\hsf^S`l6$A +d)aAKbKJP]\@T#\e]l7Z`5os<`PjXQb/hHFd=%3L_T0X5`lcQMaMu/]'["M:`lQ-;Lf$fDE7FFXs82Zk +s8W)prVuorpA]X~> +o)Adjr;QTn/H5MGs68Cts8Vuorr<#trr)fps8VrmrVl`ipu\JA,Tn6S*?QF@+snUE^\%O)$30Vs +s7cQnqY^9hrso&*rr<#rs5)W'oBti1g\q-Trqucqs60I^r=&T'R?a57qYg +mf37bs8NZ.s80F+\*a(ir;Q`rrr;usrr4;@qu$Kmq>'0M5p70e*#BJ4&fr2=?+]Y)r;HZes8Vin +s8Dutrr)d4rr<#ss7l;kSZ&BUS?T3lr;ZfpqY^?lrU9acs8Drsr5Xrr2ips"XNOqu-Hhs7!t?`k072aiD63^qQq0D.dWu +Ao)@/F`;>GH['XSG'7nHFEMDa[(sc&rkB\o`P'7,_8FCZs8Vrqs8DuprV?Hkr9;/@_)BP^Ls8)clrr*6(rVucprV?KnnbrLarr +n,NFdr;Rr;rTK)MH*P3)`lQ?HaMu0:`QZQGair5_cdBO`.M*=4*r[#h$ka$W6CuQTe^;j^bKI`G +bJsJ$rlPnubJqT5]6e1+@pWPcEk9!'a2uC$b5fTQa99Z,`l?+!b5]Koajk]dL5*sm`5Tg:^r+.1 +`l@tuqo/?MI`9@Ca[1K3bg+GT`l?9I`l5p>f>=o._o'-jaP"eabf[uI`4s%%`m)fWjPnJ:l/V4# +o'bf*lgNfLT:)=KYdU^D]XYA]_8*k$]XP>RXJh`/iTp""kiqL*p[7Y=lf6^]hpKNjcH")Eai;TP +f?CG,Xj5M?b/qlM`l5s=s2kkmakW5!>,ouh_oU'Hc,dusao]Z(`r=$d`l6$?Zq&+mc-FQ4aSs?^ +aSj-YaT'EYa;`+:a2Z$7`kS-Y@T$9/=^biBS&ik!`5KX7aNFM+s2lY*`lH$?`OQd*)AS1Sb.5I/ +cHseZb0IcCa2Q +o)Adjr;QZp!ri,nrr3/Yg%bUIrr2pKrr)ipqY^BhrVu`brPr_&,pjc_*$-1I*[agTkPt8Ps8)Zl +s8MusqYg +mf3:cs8NE(s8)/\T\TMFrr2pLrr)lrqu-Qjr;ZQ_r5NIt+X%dJ()Rr4)C/+Hjo=uKs8)Zls8Mus +qYgEns8N#qs8EN.rr;ok_jmKpUS+WgmeZq_!<2urs82?cs8Drsrr*H.qu#_\ggK:Brr2rtrr)lo +rW2usp](0js8N<%hdis=rVQTo'`S%.rr2rroZ+kf_nsOBs8W#ls8Dip +n,NFdrVo"ZrUJBQ=e3LOb0/&Rb/_N?_8OO;bh1=gh5XBf(*+>=(`4#)%MLgH^>-oTccF8NcH+&N +`6$'>`lQ6Drlc)$`Q#U&LhCL3@:F.q[(O;p`lQ3BrlXfQ+NhpN`P]^:b/hiId)\Ps9?52l_SsL2 +_8O=3`l?*@b/j=sr5a<+a2tthVf:D7b/VHBcd0VMa32u?^W4@-\[1#:b/ViPc,dZ7_o':1g$./3 +i9g"0n*]T-n++boSYE6q]"5Pj_8O@4_8!LgaN;B9^V%(`\$i6>fCnt2mdBB,n`KH5h:p]Hg!@^\ +ai)<>`lQ`^[BR?[fu;4Xc-42HaSs?k30?s?f6?Fdqr`5Ta;aND`Nb/h`C`lH$?`OQQj(D5 +o)J^grVm-"q>:3ln(dO3ruM+;rr;cnrqQNio^%Y_+se6S*#fk;+"/F_aRT0+rr2rt$NBr&q#C9j +s82WfrVm]5r:U*ds8U@6me#i3iVrlWqY^BmrVQQms760hs82d*o_S<8['k;Vs8N&urVZZis7-'r +qu?@mfOEh7r;?Qnrr3Z2r;50c`Pfd3d.[56qYpNnq"=U`rtak$K7&&hEcQ5@I"#H_,pF?I&I]$P +!WU0]n]/nmh>RBKq>LWn +qq#Q-@fQ<#rp0UarWrJsV3Th(Zhs[krr)lsrr;m!rql]prqud&mH![)mI'E4iSOM4!<2ip*rc3> +r;HQ`_(-[urr2fjqu?Wps8DutrV,H7+tA?LKoqt^0drsIcKl.ke.s8Monqu-Nns8N#ks*t~> +n,NCdrVm'#n\_$9q>C75rr)lsq>^HhrqQ$JNuoGe(`aA,()Io9,C@K$qYgEmrr3?'s7u]mrVuls +s8N#q%fQD"s8;ceP+n>=TVedHq>UQqqYL0]rr;rqs8W''p\ac;Z*S]NrVm!!rVuoprr;rprW<-! +s7uX!r;Z@fdpCr-rr3Z2r;?Qos8L]f_nj:,deN\=qYpKlrtbJ/s8W#I^rFC2_o0O0_nr0qAnPgr +FT-G9GBS+MG^k0bFEqkKH@1*dH$F@VI^Korr)iqmJ[%`$2sepV3BS"[/L"'s6osds8W'#s8Dlprqm;EX/`1u +WiN7lWqu\ms8Dror?)%;s8W#ss7F)U*h!$-r;-?krVuoss8W#ij,+j(KCSg;r;RT2qu$HnqXLe` +T:Ndiqu6Wqrr<#trqu`cs*t~> +kl1n_hO\2&]>r%mb=g!u`lPs?b/VlWcH:26%Mfa!)Aa/$&/5O[WQi`3bf\#Mai;6@^raU:cH!rD +`lcNMc-4#G]=PIPC0b:UC2]leaN)<@aN;NDaia1q(s:(F`P][7aN20?dqb\R?dm9=`l>s7`Q8%u +rlG,^r5\rZaN"5#!6Y;bIEKFScp5iU`mMrJ`Q6HQaMl6J_77M+`OT`5'++ceRd8 +dc9Z_qu66Pn+##6StMj[\A6,'^U^qd`m;i:UT;)NaiD94]tM"q`4NIgeFi;'lL=02oB5`%eEZ#H +bKe2O`PoX9c-XqG_7%&*cG[uO`l6$uaqVqH]Ml=1g<%@RaNDcOaN2NHbf\0'b5TTob/VHDc-FUe +HHIt-e]e$4mDoXWa2l?@`Q,s;^jH&c10Rg[>ZYg[`l,d7aNDZLb0%fF`Q-$=bK\/'&ds*%S9rr;ifq>:0orV60dp]#a~> +li/I1q"t*kfA?Q-q>C3ir;HWps8;ogs89?6+s\*R*#p%H+Wr=@WVZGcrVZZo%fQ8$s8;oprr<#m +s7uQkrr3f6r;Z]ps5E/9qtTO6nGiIaqu?]oq=smes760hs8Drsr;Zd#[mAZ#^A@g.s8D-\#Q=\s +J\B!!krVlip"TA5qs8Dip#jh$OlgO<0r6,*>!r2cmrVl`p!<2ur# +Q4:^KgioBRdrr3?!r;HZqr;?Tprr2QiJ +,~> +mJd1crVn8?hk$n;rqu]mrVZWns8W&to)JQn>TFt)+Vtn3+<2CO>H.Mrq>^Blrs&K"r;Z`qrVlfs +p\k+)rVQKjrr;orrhc'WUSO`abkh8:rquctqYC*\rr;rmrscA"e:PC2s8Drrr;?Tprr2Zj!ri/t +qu$j!rVliiI(6q*rr)lsrB1)Zs6[kF^q[k1lMph[s8Duss8N&toD8LYdEBYN^r+.-_RlIeA8?C6 +H?XLTG^Y!eI!Bj[GB%J=EHQR+HS'VoJpMTcHZjLVUUS@a\&H5%^W!n(dJs7?qYpEmrVuoss5(N+ +_uB]9rr2rtrVd$$nlXUq]Cu4'rr2rtnbs*ur;HTnrr)fqr9dSA^gd3?r;ZWmrr;lprr3i7s8W&t +s8Drmm_>j'V6$Sk[#X8DqtC$hrVclsrr)ir!<)os#5E6hj7N9Krr3Q*s8W)unE>6F)BBS?l2:MZ +rr2utr;Zco$NBu'qpD:1V4HB;rr<#trr3#trpp)>~> +nc&Ufrr<#srr4A7]P22d_8F:7aiMNDa2c-A_UI#"5mIl+((h<"*>T+u4G2&,c-FE0`Xg#(_T9X; +`5]pF_op$<`le;*&^8D5_n0YhB4POaBop*JaiVX'`rj?&b0':r"3Sj3`rVccjAQcXsJn +guI)JlKd^'p@@b]?&.obl>g1 +aMu6?`lH9Kd)eld_Tgb/VELaj"N:&/>Nbbgjt\rl+rZrl,Ynb08)PaMZ!*MHs"]@(G\) +s8D`hqZ$Tj!<)ZlJ,~> +n,NFes8W,p3rAsPhWOq=rr2rtrr<#tqZ$3fqLKk=+s7sL+s&!M-]HmSs7QBdrVucns8Dutqu?Tl +s8DfoqYU0frVmZ4r;Zf`j8/E?nE0KFs8Dfos8Mffq#(-ko)A[hrr2op&,l'F]AI)Srr;rss8N&u +rTX@]r<2Xmi`PLEr;Q[/r;Y0``P]X9f`(XFrr)lqs8Vfkrr3MaR=93qE-HJMJ9+OG.i\ro!"K#0 +!!O/Z&-N(M-l+'A"nhp."UkkdAo`-CFaeO\FFT+[jno&W%/p5#q>^9iccjPip\ame#5n+rO3qD1 +kPkAYs8E<%rqV5NfQYL8rquHgs8W&ss83T.qYg?irr;lprVuo]lgjQ9p$(qmrr3#ur;HNmrr<#u +rVuotq\T,.TDeffs8;corVu]jjb>',,U"3U++sCg!;uin!<2ut!;lcq#ik"3n,!(ap&+gh"oeH! +rqlWcs*t~> +nG`Lfqu?]n$,E.Hq>:3ks8W)ts![aDo`+]8+!M[E)]B_8+;uPah=gmDs82irr;Q`qs8W#srVccp +qZ$NnrtbS1qu-Nms7"!sTq%aJVU,#:s8;oqrVc`tqtg9^rr;rsrr)j-rpk9BgL&h9rVQQmr;HZm +rr)cooDK$orVlcmm8VnAl2L\^s8?a4s8UTf_nj40f`(^Hrqufos8VrorVQWb`50F0_oBO+^p/]- +Ao`*@H['jcIsZHfHZO1FE.!1L:2k9!I"$NjG^+O`J:)WgH$"YN_8O7%`PTR-`P_!@s8;cmrVuip +s8;o@aiNB7rr2rrrX&W(ora8!?hXHtrVuosrr;rrp\tj)rVZWmrr2loqu-ACXO_U>rqufmrr2rp +rr0*%*uu== +(*4 +nc&Ufrr<#qs8Q*tlAo8%]tVP.bKJ&Mb/VBD_V!:D"qM7W&el,o'akRi\]W=;bf%WF_SsR6a2u3< +`5Kj>`6ZHB`Q63HccsVN`it,(AR/VNAs'XDcHFPVa2Q!:aSs?Ra;E(Dbf\#H`PopHct9B+9YAct +b08,Pb07s+b5B?\aoKZ^b5]]cbrsCs`Q-KX9@lYUbeqE@cd0\Tft"Z3`l5X,fZ;C[`lQ'S +bi.R(h!==qna#B)i4GMPYIMHj`Pfa8rkq[GU7J-b_mFDZPc_R8_T'X;`Pom>_nWt![_hk:q"*_> +m.'K-e)f`Mccbe_*:dGVRFZ,"Z/aMu9k8Cu83_nj=3aN2?>`r4!S`Yuh9aN`&U +b/MHJe'HFiBrBR"[+!1=aMu6@aSj6`aMu3 +n,EIbqu6Tjs8N8]huE`Ss7uZnr=mO*,9J!N+<_pSG/3eErr)HgrV6E_rZ1n7qZ$Norr2lrrn$c/ +r9`e0s8Vojr;Q`rqt^'crr;Qg'*%n0r;$Bfrq`:MhSO71rr<#trr30"s8W)srVc`qr?_ICqu?]m +s8)cnqu?]prVulnZ\cY7q"k$bqu6WmnAWMb_o9mqrVlfr)?0R3s8W#ZU4IN*FaA1TJS6GV)@coO +!sAl.!"o>5!#-t!*tehf.Olhn#lju+"8`)u!>5J8&J6R-EHHJQDfg/LLofk7rVlg8rr<#sq"r4S +aSYi3qu-QpqZ$9^<8)-=r;6Nnr=&]*p&Fsiqu6QorVQWlrr;rsrtYM/s8W&trr;]1J(`:RqY^9d +rqcWjq>UEorVlNgrr3;ujR;R1mHs2slMgegrqH*`qY'pfrVn,Ar;?Qkr;?Tpq#CBlrqaii-mKu\ +,U=EL.3eWcqu?Zqqu?TmqZ-Qns8W!'s7b@>o]H2Rqtp?l"TJ>rq>9gaJ,~> +o)B=$rVlcqs8)coqs'rOq#(!gs8)^1rVZQ9,TR^=*#fn?,'C]pp](9ds8VuqrrE&qs7uX+s8Dun +s8;lrr7%(0RAldSZ1@no"8hrmrr)lrrUTpts8)cnr;Z]pr1K,*^M`rJr<`E$s8Dlqs8MurrVuor +-N=&Bs8VrqqZ$Kjs8W&ss8D\rKu7U%s8Vros8W&haND<8`Q\)Tr;Q]q0E1kHs813^`kf[8^V@U^ +B52@-H@'m\I!L$eI!9jaDGG%kIsZ3E@<6[ +nc'0us8N&mo`+sac=U:n`P9@2qT'SucIAj%%1X!g(_dGf4`l5s=rlXfQGg+4Sb/;B:c.@c(d]ca%ccs\Wc-=DPbfRrH +`Q#p:`lH-Bb/MKF`6?0DaN;`Qai)BMfV*]$:?_AcYJJ,lbJqT?qnYM.`P'Ilp[[hEk3VEq +f@0$6`l5p:_o'OCeD%12XjtV6_T0sI`m2]Z6ciB@g<@[U^r477^W=C8_oB[?`P]gq`>ZY4`QZ]N +_SjI;d`p(\Uik>78Cu24`lc$=sH[(j]*aMuNL_oTj: +`l?*Dc-=>KbKJ/N]u\= +n,Ejoq>UBks8VH@q#C9ls7uX1qZ$P!+XS0V*?6#hnFukWs82TkqYU^-arSM8Fj)W9Aq#CBlr;Zfqr;ciqrsJc*s8N&ur;6Nm +rVlg8r:^0gr;-Ha<8=::o_n^frV?BF`PK=3_<:[nrr2p2rr)ZmqrOf8E,9lLG'/4#,p3s.r;[Z: +!!<3%!"KPZ,UP)Q!!a\pAj@4:#Qau.rW!]7"9\f-#64f:*,9D3Fa\:FH[gsho^MbX8,`J^il'%' +qu?Qnqu-Efs*(s!AFfZuq#C^Bfr;-HnrV-3hr;Zcpr;HWps8)Wls8W)ss82ioohaZ!UlGEN +r;6NirV?Hms8Drkr##D0r;Zfdk4\H>lLrVuorp&G'grqXiQ/0H)] +*[2jK:b!>4S,WB`s7u]orqllqq>:0jrsS]'s5!>AlL4cQrr)fq"8quiqt0o=~> +o)Adjr;QWo#5e86Tu?^'rr;io(]+10=<&Fu*u>\/Rd^"Mr;Zcns8Drsq=4G%rVZ]ns8;Nhq>-PV +S"cUTZJ#-TrVuinr;Q]q!ri6"nbs:!s8Vloq#CBOA_c3_aT)#6rqcKks8Dolrs/Q's8;corVc`q% +/fi!rVcQjn57o7S,*$_$MjYUa25X7^ukOmrr)rsrr2rtr%S*Dd*08?c,[N.^kQQ>E-?SWI!KmVH +$Y!^Jp2!+:NgYqG^*e`G'J7XGBS@[H[:#;Gp%EaEHm"daMl$5b/V0:^qSn0q>^Ejs8Drps7kTja +liX%rs\f'qt^88\'ALRr;ZTlrt5,-s82ims8W&lqu?Wps8Murrr3#qqu6U.rql`ms8MafiRaods +82fps8;oprr2rprq?@*qtg +nc'0us8MojqZ$EURU:ES`lH$;qoBYtaO8X""qh@c)&Nj?dF$:_ccO2S`l6$5aSj9XaSs=#aMc!@ +bL+SNb.>/mCg:@SA9+*N_o0gHcHOB/`WF6(b43Og_p6]ObeM-C_cG=>>H-;rc-+/Jbf\',a"GBP +`l>s9c-FDPbJqTIa2cHIb/V6>_o0[KfgSufQA`5Tg;^;%=u_9K6F=(^Adirme#i* +p?9u`lH7Jl_8X@9cI^@WXgH'm`k]d>bK7`T@B7.=e^i6c`k]U1cH*lB`6ZWI_o9g;ai;<nt +b/VKAa2Z!;dDsJTcp-=5QZ(O&c,n/Ha2n8&!6G/ZpW36S(uXdY]YqM-cG[iJ +r5LY;bg"APcdBkJb/VBIdATMF$l^E0(D6m4(^q@;gr[:F][+pHaMu +n,Ejpp\t0hs8U[+s8W&ts7uX1s7ZK-.3]fW*?lmJIHpJ)qZ$Tjr;QWonbrOdrVllrrr35ehX^:( +jkfV.rrr8ss8W)trVlrop\XO\s8N]-q>^Kgoh=3'dp)YFs8)cqrVl]nrsJc(r;6BhqtKpdoDS[h +r;Q]mrtG>1BZ8V%rUp$drV6-+`5'41c2%59'E7q,qYBNbJTbsQG'SFj6kUIK#5\B9%0m" +o)J^g%KHD,s82`ZUTEPOs8W)ss8Dp1s7Q?',TIU=(E=Y5Hg:;(rVuoprVuEes8W&r(]X=0\sAqa +Uo(3>rqufprr;rrrr)fnrr2rgrrq>UDd!1 +FanX\H@gThH?aL_G'eR]GBS.RH$aghI<^"Y_8X=.dC['1_t=!+s7lHjr;-HjpWLS(qu?Wprr2p4 +j&k35M>I/Ks7QEgr;HZqrr;NgrVc`q!WE#rrrN&prr3Z1qu?]orr)llViT`kEm"FYs8W&prW)ud +rY>D3rVuAsU84T_WiN.qjS/]OrVuorrr2utrr)lr!rqulrr3Z.rQA[o*#9e5(E";e\ak.h)BJVO +s8VrsrVlcq"9/5nrr2p*d\3,#VVV4MrVcZnr;Qitr;QHjJ,~> +mf*alqYU0]`b]@^]ue@7`W!mWaT'BudDsk0%L`d_)^$7.AB;s@aNMfG`lQ0sbkT?\a;W(=aNMfL +bItZ>>[h8R@qh%>^;S%8ccs\VaSs3Ia;3(CaNi&NcT0P3`B_nrc,@`H`P]U4a8X.2a2Q!8`P]O2 +dD+#QbKRuI`l6'=a2Z6HceqU-`A,obbKS5Qf"/c3\@8`ldf%CpcW[@%c-FJM`Q8&$!6G/Z!Q`FXaSa0sbKe/GX)hKJ +nGiOfrqufr!qk17rr2urq#2*,s7uB_Te.<0*ZHIT,`DEppAY!arqZ?ZrW)orrrDrprt*TKo^1u" +mJm4_rr;rrr;6KlrrVlcqss^es7lTn%eBErgu-qYRed!]s8W#prVm$"qtg0err)ir%0$;#qY0jd +q>L6frVlfr'D_:0MVi`uqt^*drTV28`l5p^qYU]4fq>_63$ipD0 +(e/mW3#r52!sKf+^IgBq$N'l,":,>>"8i-`&Ih]VBRjoGH#eJ%f^8_=rVuforVulZ`Q7QFqtpEh +qu2;TflPC4s7lWor;HZqoD\I0YH"qup%\@Zq=sd^rql`ks8N)urVm?)qZ$7ffA>Ogli6bVqtg +nc&XhrVlg(rVHE1Tulm*s82cns8Dp8qu6?]o:.0E*#KG9,pJ6@rV6EmqZ$Kjrr2lgrrL3j +s7tH4USOZdWQ4Q/q#CBmrr2rsr;6?hrr;Qg!WVlmrsnc#=5;]cS=06RrVuorrVc`urr)cmqYps% +s7Q3]q>^9hr;6KlrtP8$[YWac`Vo`5s8M9#_T0[8lM:JYr;cirs*XhGs67A=^W4:/]!6itF*`1] +I=-BhI!]s^FaJ=XDN&XMF`r.WGBmQHDfTTVkirVuol +s8Muqs8D#qa70'-rr;fjr.M<-EQn4Xq#CBkrVlihs7jpDWjD3fq"jmaq>1!fquQ]mqYq'(rr;ao +f\YUgm/Qq\rr;6^)ZBU6rVliRXer5%Vlm:qZ2=7pq>^Kks8W)trr)lr+o;6BI=<5)Aa20 +*$DHSq>&;`)Bt4:0k$h^NjT:ijlqu6Nlrqufrr;ciks*t~> +nG`Lcrr"GDo]DBHL9\bC`Poj9`l?*@b0%iOcHt-s(C_?&',hVoCXLPLbfIWA`Q$-Gc2Gl`b5THu +aiqfKa2uB9Ti>]QbKnA8X3/H#a3hrOdq5E'@^=M7`6?KFbL"kbf[-USKT4.#daHUmdEp:h +da6.WbfdoEbK%cA_9^Ljb0nX#bhC7]`W!p`b08#L`l?*BpW39T(Wk"B^Vc^]?=-f3>@CKI]=Q"t +`QuHGb5KCFb08)Ld)sJJbFqQJ$lfrk&KVo/REE^rW"TRRFj.b8_:6l[bf.K=aNVlMb/qZ:Y$k't +<0$#6s8W&mpA4aYs*t~> +nG`dnrVlZjs8Um3rr3'!r;ZTl%/p5&s7Z3OGU=UQ*uY&&#H.@mrVlcms7-'us8N&rs8W#sipZ:( +l/(S%rs/N&s82]hq>C3k!r)Bbo);,Yr;ZcirQB<=guD3&rV-'sfrs8Dqq>^*Hlg!4#rr`8ur;Q?gJ,~> +nGa(!s8W)pr91#YkP5)WqYgHoqu.6,s7u]eo]:-<*YfS-+!;`(q>:0k!WN,krr^Hb +o:V_NX/2W,o)J^err;oprr`/pqu-Noo):6@qZ$Qis3,ZAgYbj!s7cQnrqucqr;$9jr;6BhqXj7G +rUfl^Ch%70eFrqBr;Q^4r;$Bmk$cc^AbQ-'rVb3`^<4F?rV?Ejrr2fp1ASu)_o9R1_6.ZjE-cPP +IXQTgGBe@VF*`7XEd#8sBR=iCG^=FQT[Zh]F*N1^H[L0erd%dsGBeCZF+AMAc+q!.`l5g-ciYnKus6ZtPKQr*CaQN6rp\OpgqY^ +nc'4"r;?Tpp?fh4@]$i\b/_ZE`r!gqajA/^cI9pC()7Ds&/GidLXF8fb/q]Kb0%s*b5KE]`Yce= +b0J#N`O3-dA7B4aA:1]&`l,m?_oTptaoKN^`pq,@bf@rOa478"f@eh>da5hLa2l9CcHFAWe^W's +e^Mdab1Y4oLJC94?aA&4dE9_TbK.TEc+[*#]hm>0bK&5L`P]QsY1(M8b5TK[`Y$hke_]Zao'Yo" +SYWU3]YD5#rl?,%aMl'DaJjGJK1CX+_oB[/NC?E^(5T-&_8F70_u7Db`k]F.`Os@(lMp\Mm-X6* +gtV>Ed)O&KahQ0Kg9dlocHF5ObL"$me(%%8d*ftOa32oceCB+07mo=$39AVRG\C>oL9/JHgW[pi +c-"5P`5][/dZo"-cbN6)e]c(P`lQ +nc/Re"o&&sma^J!rrVoos7uX1s7uZfs8VolbY9N-+sA!P,#?Y]p](9enbs!trquTlrr;?DqX00JI'!<<9=/jJ:(2('":!Vl^k"p=r2!s&Q=AScdAGB%hTJ\:@As8;iqq>^Ko +i5O(;r;HBis0@^=d9lG?q#CBns8)PZ>='f&;-m*e8l^qHZG*Z/F'r*jS^d6,s8W)rrr3<"oM"-+ +f4*\3rVcZmrr<#mrr<#trXo20s7Q6gq>^KegZn1mmdoYbrVm#os7lKhrr4/@r;?Bjr;Z]e_&t!N +*$\t:7j]WSpAb'ja!r)VR/d$]qu-NsrqlTjrr3#mqu6Tuio]Xcp&=skrVQWprq?AB~> +n,Epts8)`l`h9j8s8Voprr2rprYPV1rq?Blp\;p)-5mmE)'9qpdeNYrr;Q]qo)8Xbrr39%r`%M)hit#2r;Rl:qu?Zmrp.h&G?n-F<)lkh +=bsGZKni`=anYo8qu?Tnrt>'.e`:kaqu?Zf`P]F0`9$mrq>L^Kks8T6\g!aC&qtpEnr;ZNaQWcX&4&9*W5tFq6TWl)6O`Ff4FJ.1UqY^?iqYpL# +r:Wk@jj[_tq>C9crr)lorY>>1qZ$Tkqu"F+XK/:tX/VQWo_JO\rVllrrr2rt,5V?;s8;K&)]^"; ++CWA[,9fMIs8;o8,o7_irqcTjs8;forr3T0rVQWjs8Vo`Z(Re\_tX*/rpKf:~> +o)B@$qtpBms81c?>&1Ufb/DWLaN"(t(;n53f%/7#Y;R++(Dml&%Q(E8b0\>KouR-P+iqjKbfIuA +_gkm&@U3\dUVY*jcc*f>a2Q-Bbfn5L`PojfaC3*7`luWZ50_g;MilK<`Pp!Eb0ADde_JBRLL!>1 +4[2+mMFMfdQ?d^C9<6Rpd`Tt[aiVWF7ag70U=@?,e[WW:]WArodDj8I`Poj:b0AGogYM8eoBYK& +N2*_m`lPp0+iVUJb/D0?aj$lE7!:e;U;"jsaMai`*Fqi4OKGq)^VRhd`Flp+`59R7`koFhq>9O@ +mITbpi9A\8`5K[2c.(OdX0gC)ahuQ]PC(Ws9@D/+bf\/]eC]:@0cMc5:d[*%7Y$\rXeLDT9gr<> +[F*X[e]u=`c-FGW5M>&>9u>3$`l5s=b08#NaN4>&s2b)Ws2YVkaMc<>bL=MM^O]?er`'8->ZeAD +_99XAbPoZ`a?Ibf_8jR?b/^+[(E~> +o)B:#r;?Toq>^KMhuM31r;Zfor;ZZlnZ3rV,p"!J+WkF_nc/X[rr2p5nb)eZs3^H- +o'"p/s8W&ms8Vrmq=smerrW2tr9sVSs8)Qkdr!t)fhCl3o`+marr;i]`f"20Eg4)\h;@&Ies/m" +;'5r#>Fa8%UIuW(EqZ$No +rqufmoZYGFrVlTjqJX:0a^Y&Eq#:-il_dd!5%&;PEH-)&Dr]L.h:p`Ah:^>jS8M;EXQ9E]p]'s^ +s&.P'l&hk +s8Vji+=C[Gq"M?B+Y0nos8Vq,-m0i3s8W&ns8W)tr;?Qnrsel(s8N&fjQl*ms8W#kqu?]n!<2`m +J,~> +mf*^oqu#TWY1`[Ns7u]nqYpNp'`J(3qu$Hirpm-7)^-(6)B9]/l14?D(&n.2rr<#kjH-41V5LKP +p%\L`s8;cmrr`5trVlcqo);5Ys82cpe8=%'fM1i3pAb0hs8Vu_`J\).E0@WUgtpiCdum3i;-@C5 +;--S#`Urs"rVuimr+*t(_K#8KroV)7^r=OmqZ$Klrr)jPrr<#^]YqY'^VIX.EH5fAH@'j[H[L0e +H$OL]GAp9n]23?gH$ORWH$+OF]@NKH$adbFa8"L`59@'`kf^4^A.O(s8;orqu?Na +bfT;Qs82`gC;8]MAGlK)rqQHTUJYYc?#Fe(E-#)uin*)Cg=tH>g"!^*D,Y8Khu3TIs7lQm;V0Oa +O/DdRs8Dutli%q%s8VrqrVQQe^p0]3Xe;_gW:BcQs8Duss8Doqrqud;q#CBe9,f'ad/!FG*?$6- +pAb-c?m6L4p](9mq>C0hrt#,-rVucns7cK:URdsTir/fT!<2QhJ,~> +o)AdiqYL3k%/[t^@Z.e;cH">TaN4A's2b5[(;n5;`Q6?KccCnH#Sn0j)Aiu_a2ZBHo#;iob0S/P +`k&3OB3o"VC7;WGbKA/M^Ve"/aND`Nb/V?:`q.8bb0/)F_UPu%gZI!Mf@S!^^r=^Qe&\D)7nR9G +XN9#If@A$'6pspYB3\2,5tS'(da$+^_77WcbML!@e&feU\];RtYgCP>`l?!6_8XL?f&,6*lM:JN +lK"J4Z*VKd_8jX)Gq"BSaNqoHafpd`4A&(EPJ4WB_8j^Dbf\/F^V[q6aN_T6 +qs`q6o^D8+bjjK9`jrh!c.U[t['A'3behTRU_:mVdd`9D^8D;c7jFW?=c,RW?aND`Nb/hZHbf\)LaMu6=`VmdpaMu*@aiMiS`kem% +@o?0+9O2%C\&5c&aN_s.b5B=;a3;TPeC#rS$q%&@e"I6_'p?npf@`h3$3no*bf.QMdDN]5`QZTJ +b/MEI_o.I3853j5mJd.cr;ulmqt0o=~> +o)Adjr;$'=`7<(iqiBDs6kgNs>Q=s2$kj[sH?+7QFEiY=lLaoP +rVlcpq#Ag`i;3?NqY*kHhqV)sp\40qHX)kD7q?[[FDPo9JC`]:i8NYQhqm;Ohq[#D`/SJFVW[UK +abAO/jOq.lp\jgbr;?Nms8N-!r;HWirtGD3p&G'gs8)Njs6K4Ime5r4dd[58!<2uqs8N#q*WH$; +s7lWk]5H!kqY^<^:*CoupAY*edNKh]T)/<^s8W)ur;Za-s8;osrVuiriTTagnGiObrquctqt^6c +s*t~> +nGa$us8MukbbMoLr:pUC(p&Bgk*uc+7*?QAso(r@`rrE&rs8W'"s8Mlo +rso&'QCsqGW2R`/s8;osq#(-trr)fps8W)ts7$$fs$QOWOk\XHI^f1Qq#10RX(bUYWm08QhV[,C +gtpfDfA9;=BlJ$,D,s_T<0Q;;p\Op[H*Q2V^Hnr;RE*ahPO._S*aMBQ&'B +G^Od[G'X(7ApS`PHuW\o_4t+UGBA4WH$sp\FaMWeDKp5IH$OX[H?spaH[gEeF*i+SGC@BN]YqY& +^r"Ius8Duss8;lls3o$Fq>L?iohOE$hGWn>q!Q"D=HQfU@rZC,C2Rs=eDK*=hr!;I);X30hqQr@ +_22]6U>tkBbD=p1in1egq>^9is8Dp!rVlfro`"mj)u9O4q#CBnrq!4dVkgMpY+*<%rqZNlrr<#t +rr)j>r;HZjrqX*?c27J>s6rZ"*bFs@rUnGT*?^gGqZ$Tnr;HZprXA](rVQWgkGb#DSB(U,s8N#h +s*t~> +o)AdiqY:'i%-sQpG.#'"d`fkS`lS,$*6,t:ahu*\%2KBP<(*_8X^G`Q,s;_oBd?bfn5L`PojgaC*07b/_THL5"=9gN9:KfZ)+b`f*VU +@[OpXfA#-;hV[;Ghq6pgEcZPNDer3B?9ieQeB>q[a_eNIeO.j6bJCs8_R[5(d)XGQ`PKC1b08N$ +bh)%WrUK3bOJK8$^r41jaT':u_7-nn\WL-1F`0pG^VnC:`m)5nAICh3.XReo]Y;A2e'H1R_T'X9 +_og'E`O51,l1OW7k24k_g;:P7_p6o^fse0,g<7a^cTTq6dm2F4cGc8S4ap0i?ZL./D/jTIfAbZE +i8EMJgYLfDf@8:h\pdLMM9+2uUM8/]q8O5l`lPm;bfJ2T_Rcj\ +=]\C#<+T6f]uS+kbQ,faa>h>``l-$I`mE(r8ug+Vb0\Qr&en3me^i6X$P*YoccF;OdEfeH_8XR@ +aMZ3Db0@`$?:mmkRH+&?rrW/rqt0o=~> +o)Adjr;?Nns4@MOs8W&nr;Q`erYkh8s8N&SFrVbL*$uaS.(T6RrVulrr;6EirqcX$p](9Yi:6C' +o]6#Orqucprqu$[8,rAaq"p,JhVI;M;2DWrSRP`ZbMV(-jl5+Rgu7)Lh;%#Mhl:1+E,T`>DJ)qq +V.+2*][EN_i8r^.g@tK_aM5[2nc/UerVca,p%7hBZ%IFHF*<=3+;PCirW!Z6!!NQ-!!*-*!u+7X +gu)L,(]aU:"9&9.#pqjmo]&"a%Km(=q>`na#RCM7#o*UnDf9fDFFAXrb4,<.rqlTjq>0HtgA:jE +s5RJ>h;$ja>$+^V[F\A^CNFT8EH?"p`oPk3i8!&Ii8*PNrnnRKhrNM3P?q*^FJddOiS;"qp&"^b +rr2fpo)8^gq>:-j%/BSms8V'Jmd]f8kgTJ0"oeDpq>C6ks8)^2s82fprVcE!,p+D`qY^BhBd+iK +qYgEno`"ji"RY.8lJ2C=!W;ios8W'!r;QHjJ,~> +mf*dqp\1AVh!k@DrVuors8W&srr2utrquirrr3N-s8DoMEYf`4'HS)5,.7CHrr)lprY,81qYp?. +R\6LLWN5gns8Dutrr2lrqu6Wqnbu/\qu?NjOJCR`i7q.b[`"hK=c1D[gY(`JhVR&Hh;d>Fi8NLj +@;g%#Dffi.;pV:JBpQE[UL2j;gM5O?rPQ[n`kq*Aqu?]qrqcQm9\dG(a2,F)Lh^pTI=-?cG^"U` +H@($aI!g'VLWIYEBleQGH?jg`H[Ks6bgOj?F*W4]G'nR]H@C?=^RZIMfSC3"?4EH?"p`oPk3i8!&Ii8*PNhVR/GhVm)*O^([Y +Ff=$Phq>MjpAP!j!<2opnc&Of(B+1/rr<#sr7RmHVQ?i"WLE&MrVZNkrVm$"r;?QorVlfp)#F73 +rr)Gq*Z,sHq"t*cA/l[5p\b$jrr2lrq#1Np_kE`pU$MXUrr`9!rr2QiJ,~> +nc/Xf;?-LWfP+cc[E$D3b/hH;`QHEKb/VE?aN`&Wbf7WDbKnG_[oW\G'G;Au(DN=^`5Tg?bfn5N +aMu6=`Q$!AcGdi>KNqhj>]4_t_8O74b/h[&`rF-[b5]Q_`pq,hc,RrJdVt>ug>q-dJ>T<";b__W +e^Mq(h:^T;hqd>KgYq/KX(66jE,]r8@SY(8<*+I?\s6[ak0m5;ce,M?`5Ah'd)aS_cH3uFb0IoV +e^N[Jn*TYSR@pRc\A651_oKj9]t_;"_k1F4DgFWnXT$7d_o9^;^P3(l9kPr$Vn]dSe'u[^^VS"8 +b/_93`lt^-r:0FOp%[b"kiU.+_8X^Jc-XJ._;!GSbIC6sh;-dT9gqu'AoMg1EH?"p`oPk1 +hV-WAhV7,Fhr!8Cg>'uaKhk$%B:[]6i7+`;cHF8H`lQ#hTAaj/,S +aMl- +nc/Xg"oJ?"qV1$/rrW/pr;Q`erYk\5qtpEnn'Y#W-QXE[)cHS1rVulrr;6Bhrr)iurqcTmrsR!@ +o'u//q>^Enq#'+M7eQf]oX'G6k1o(MX+GGYa55q0hrN_LhV[,Kh;$fFj4iMIh,%j0G'.JAF)4V$ +g;]V3BSPI$gtlVqq!Z>>^Ve1fs8VrlrVmE%o(UUlH?O.OK4ubQ%gW48!<3*"!"fA>$NLMA2dG>+ +b;M!d!<<*#r;[6H7@a#:`%iJF!=&T,quC%($4$V3"pYM?;J^Q*Fa&7_TBYqCrquZkr;H34b5_28 +s5RG@io]+Ig"#-:hJZ))FEMAAEc,hqfA5HCio&hSgtUWBh;@2Jgu75Gi8!)Kf&>ZEjPu8ps7cQi +rr2fpo)8^gq"amg&,Gtss8V]SmIBZ7k31FsrVlg"r;$-brr2rorYPJ0s8W)us0E^q,[pTMrr(1b +,:f2[s8;Hes8NA\l0R[/s8W#nrr3'!rVlNjJ,~> +n,Epsqt\O4Z17ems8N&urVuorrr2otrr2j3rr<#qrqlTms6\-**?Z.:+r!cMs8Doqrr)j3rr)fp +rqcTnp?7a@U84]acM.>\"BQcS%FfAGZIg>:`Bj5&MGio/SIg=oA9 +FEDS9FE)%hdb2U0J7sYngY:Usg\UE[^r4@*\HuF4?bfmasD0'rJH[:$dHuaCGQd*Xj>'"q/IWg9gH[gKkGBA"UI!9aaH+:f._nO%,\]+UJ +rr<#srr5@WcGf\Ps8V7hgu@MReC`:/f@t+7CiaZ5F`MA=<7fschW!JQi8!)Bi7m)FgtUcFg#(Q< +jOW;MgYh"LU]:2jrr;uqrUKmdrr`5sr;Q]q&,Pk9XJi5"WM?Dhp[S7ZrVca!rqu]ns82crqYU3j +&?cin*F/F?rqstX*@7!Is8;He#Q3PYSt2[rqYpKsrr)iqo`'F~> +n,G?Eo%g!ODn*p6aiMQC_Sa@8bf\#G_oBjFdF$1X`Pp!=a3`>UYW!(0&JQ2n3R5R`b08)Sbf\$) +`Xp50a3DE&QBASmjN`QH*WaEPkGd*^%"E7<_#l.`4cBo9d_j42uFhUpW>g>Uf?g>LuEhqQp^ +Bm"Q?B6A61:"._0Nc8bmZd6n;cI1"\`Q6.Go^hhMp[["_ +ma/kl`lufSccNAqj2fNc[8#B9l/:(Bd+cpuB1?QSFDZ/@Ci3/$gYglFhVd8Eg"P<aND`Nb4!FOas5!I`Poj:aMYQFAm/&(9h\l(^:hn;bfIcB`lQBJaMuBH +b0'_-(!F\9^WP#i$m-3Te'uOcY6GRRGgk"/a9f\S>tn.*Phkm,r;Qirqu-9hJ,~> +nG`^krr<#Of_kaK!WN#rs82fqrV?F)rVucnr:p9boq3]X*ZZrPqtp?krVZ]ps8W,u!;lcq#2eA$ +n+,r,rVlonr8R]Hr;ZWjs4(oAiT8qXfA,h&AjP/JKh;[AFhrWnSh<=1-=1R +k^5E.$Np8+%L*P346l_/Sj4A+"9Jc7r;Zm"#6b#+r(gYUrJgYLrDgumSThVdJUhr*MQhr(!h!ri)prr38^lL=?5o'4Wkr;Qlrq"ajes7uZortPJ-rVD*n,TnS_q"OgcC*4cI +p&Fp[rr +mf*Ihm\co2qYU9orr<#trZ(t;rr<#trVc`qs8N&rrr)Wjo^\Ls*Z5eF_#=<2rqufprXeu,p@t\[ +Tr4Zd\b#Ups8DuWr^ZndrVccHC>7V(guHr>i8EAMhUgiCgu7)Ki7QrKj5&JPh;6q"CN+$2FD>i5 +DEuP*hs8tOf\kZJCYAaK_o0O;g\q*NrVulr;Z6Ojs3SKt`50?uH!tT5GBnL[G^4O[H['XUJoc$6 +b/_JDDfU#GH@($eH[:'[I88/DFu_niqOrVo@arVuol +fu*(Sq>^@kf@Sd5io/YHb;_q6E,fi0G&_S>@,'Pti7m)Kg"bcJj4rMNj5/\Pi83GIh;6oJhV-^b +p%eLbrVulrs8DHdrr3*"rVZWmrt"qpYH4b%WNW7fa85Z4rVlcqs8;]l!<)os'Dh\&INTUJ--Z,Y +s7p7F*[(%Rqss^kr:RgtR[pGLrr;ur!<2WjJ,~> +nGa[2s7=BRAsUBXb/VNEa2Z*h;dJKgumPO +h.UVECNai9F)Gn^d+d%*ce7(5gXJp(g;pb<^::f'bK@uPb/hTEd+n0@jRhp)mGkOJ\AQG1a2Z?J +aiV]B[CFPdJ1bbEB0UU9]Z8(3^V@\(`hIer@Sg<-=c0i9]tr(3^:qY1aMkp/?c1$t]=IY+p@e"H +jN$''`Pfd=bf\8V]!'K1_o9b^cdLM$i8*#;`\g)'DK9f4G&_M:?J4,lhV$ZCf@o?BiSEDOiS<8H +gtLT9g"P':g=+A4e&oVP_oBd?bf\)L`pq.Maoof*`Pojra>L]9C0sq89itS!N5W`\b/hZDaN2TL +aN2NJb/h`LccsSL]>r<1(` +nG`gjrr;lJgAh3OrVlicrW<#tr;6L"p%a+j-XcfJqu$Hir;Zcqrs/#CpuCc-lM1AY!WN#Sr^Zhb +pA]lOg#_8Ll.b.Rhqm5LiSEVQh;@5Qin`8Hj5/_Sf5GYMEcQ/DDKg&D8"%o]inNMQhU#O&psmI+ +_T(m=r;6Bhr;HWp,l-AdKQ_3VLhJOf%g<+Pq=!!30(!W2p-"q*M?FF/1RH\\9VpAFsiqa15XkfDlbqYg;eQJp]]i7m2B7q[$`EH?,? +Ec?2=>M@uiiT&bRio/kNhW3PLhr!ANhrEYUgudPMiT+J4p](9gr;HWns76-kr;6Bjr;Qcorr3T! +ipl[3q<77qs8W&ts82Wequ6WlrW3&trr*N0qG&.T)C0.ss7uYt-6OhLq!n@_rs7]MkMlL@rqQKl +rrW,qrqHGC~> +nG`mls8C9:XRc2arr<#prqcZnrWE3!s8Dip#4hJ9.jSEqqYp?ks8EQ/qYnO#Y+DSfZJbc[rVccR +r]pG^q#?)OfAb]Akh=tPi83>MiSEVQh;@5Qin`8HiS<;KeST5EE,]`dnSI=6HeGBnUeIscTkEg=\V_na1/`6J;]8,iDarr;o[`o6mms8JdXiSWbU +g>CCI@rlI)EGolC]Ej5&_SiSiPJj5&MIhV[8JinreNjknhLi*Y^Bs8Vons8MutrU9aa +rrE&tr=],,s7u]>Z*(+-Z_ajpmeHh\rVc`srVZKj!WW,srt4us)&Er-C&@r+r2UqY-FW[Ko)9-t +q;.s +nG`gjs6ZOjE43a,`W!mSa&qoB>kaNDE> +N*("$@qKkV^rFI7hT/sAc,\FHQce.@gZI)>fA#*9i8<;Lh:pcDio&SBi8WSMimr!dEcH)s8`mEf=g%>44nEnDnXM;m%ccX;Lrl]?(`jiabR6#(c +<,OUO[_^#)_nWt*a2Y3A9ik(U?q>%1]#)"oaM,C-aN)9=_oBX0^U2JimIT`:m+KPJi8`l5s=aMl?9^kQB*r!cca>G`R**l +&JYZ`9$bo(duFtL&spYYo#M-V]q&8!9k1Hlqu6WqrUg,?~> +nG`dis8V?Dn,NFcrr3'!r;6Kmr;ZNj%fcG$rVQWpqZ$?:E8^cprr2os!ri,qrVHWnrr2p%cL(2m +m,@U8rrN-!iVlsXqu?Nmq"@kJi8*;Uin`\PhV[;Bg>CWDi7d&>jkStVhVI8F@rlX2FDYu?DJa?2 +%RSsB0KdE9ALdf'4Gq>^Hmq=sa^n?RdrGB8"P80nlOqu@9/!WW3%"9T/\3MGj:n>Akn +pAbX.$8Z,PqXWBG.MNO+"T/6#"9\N$rsB*>Ci=H?E.sD)o)&Fd6i?o]ouu"as7H?k:T3+(hqZ.E +4`YabFDQ2FCiF968_r=]hW3JGiS3)IhUpN +nG`dirpm@ma7oQ3rr3&ur;HWop](6lrr3H*q>UrVHNjs8N!-p$n?CUSauecMRY? +qtpEOr^Qhcqu?Eb=PVcegZIAHj58_NiRQZ>g>_&EhUglEjknkJimqOXDfKf5DKK]1DJ`@`g>:uJ +g#&?dr;4j]^;%_]rVufqrql^(f"/H/a2Y0+C2\KKI/\I\H$XjbG'%qRG\*;acH2;\FaAC\H[C-f +H?sgcF*MKCdEBRFD0'fDGBnRaI!U!]H[L9eI<^3]]>DD)ah>U*n,<4brVca[p<;(bs7ZKl9W?n( +hqZ.A3GrnTEb]c@CiF968_r=]hW3JGiS3)IhUpNGmp]('gs82cqs7-*e +rtGD1r;?Nns82T.XK&=tYGn/#p\k*jrr3#urVc`pru(h9r;Q`rro57E)'U.Cb4u#/^*FI1=7H7i +o)9*ro +nGa*rr7u[-MSREZ`l?!9aNM`IaSa'Y`r_o0F1_na.7jl5:os7>U/X.uc._T)PnFND\Lai;9,Q<6sa +7oWZ!T>&Ch`PK:)bg+2FXbSQ46U50BG,)Rea2G^+_oKg=bfn2FaMl?5o^V,2q!74nl.sP'b0A#N +e't\6d*9&Eh)UhIcI:4S7Q>=.E-6#CG\h>8E_"m@gt^oCf\bB7inW,:gtWXqe(<@'gtCH2fZqs( +ACSfO^rFI8aSs?^a8j6KaSj*paNDWGaL\U"@9ZZ)>[C`\\A6,,c-=JTrQ,#]rl,hscH=,FaO%p@ +(D[u&#H?&#cD)3d$Tu5J`q.7X`l5?!:/+c@hY@*Ms82HgJ,~> +nc&dks8VuSj8T&YqYpKrrqu`nrr)lmrX\r(s8DorrVlios82]hr;6HlrVlotr;QKmqu6Tp#NFh7 +o'b`"s8N#rs5O#DrVuirs8)`f=ch%ef%f'3`j)8/U8bE;h:1Q@inrVGgZdMSgfAN8DKU#@D09iC +E`?FJb2h15EKKkjqS^7pc.r;'`IUC]rqcTjda@shs7ZHjN.%Xj +AnFnQE-6&>G].D>EGokpaQML=g#_5Pi8N.\K5".Q92JAPBOQ41It(p0CA@i/r;6Nil2ChcrqlTj +rVm<$qXsmghs^+*p$;>%rr33"r;?Hhrr;`l('"71pTP_^)BpCNAbGbl*?udV.fT86rX&N&s5W\: +h#IERrVlrsq>U-gJ,~> +nc/Xg"o[;RVsF3Yrs&K$r;Q`qrql`qrr)lsrr;m*s8N#trr2rprqcKer;6Hl!<<#sr;Qcrrr!;1 +T;&'RVRQ*ps8;]lr8@QDs8N&uqZ$4iNR$8+f\"`nZ(de`WNjJ!eE,HEhqm&>kM"qL<,uhlF)c/7 +F)Q5@;InLrr2ipo`'F~> +n,G$4^h-rX`m)cJ_8*t4ccX>K`lZEKc-",F_8F:8bf7QD`5Km=aN_iPb0%cIa3+D&!Qi@[aT'E^ +bRhq:_fK-k?"%Dn[(s]!`QZH_aBQX*`5fs=e'U@,`RW;be^;:"cETaO"16dam9[]>V4jf#c+O`PBI3_T1-beaNB4,q& +F`UMM:"7eEaMZ-8`l?*Bb/hTBn&YLJ435Rec,[r<]qAkCF+KEW,.((JO(`pq+T_i7Pg;.mQ5rr3#qqt0o=~> +o)B=$q#CBZht$gIq"Oads8W)ss8N#rrV?F&s8Mrnrr<#sqtpmkHCij\Uj'Z)->H.GorThVL`6@6@rV?6gs8Mrlp$ftTI!TsbHr)=*!r2g+!>Dg$>FF)PoCDK0i;C7<`.iTAhHhQ^K`Dh*S*QBI>lO%)`/;Hul9m.^JRrVlin +s8Drqr:9jdrttY/qu6WqrV?']rr;HOnbMYGoBP]Bs7cEirr;olrW2oqrr3W0Cb$kYQmEq)8Lbc4 +)Bp7OpAOR]#lOJts68h=jQudD!ri,sp]#a~> +nc&gjrqaO,]);R-"9/5rrr2p'rr;urr;6Birr)j#rr)lrr;6Kn#Q=Psr;Zfms8N#srr`9!rVl`p +&cMY+h3"P0V4apCs8;opr;ZZPr^$G]rqcZpp%G4e5".b%78d*.CijT)=\2Vh`o5S0jPnqMgrrH1 +FE2)5G]%G@C3"8NjBl,,>H.Jrs6IbK^r+t)rVulrrr7E0^Vdn#_RFl#DKpPXI=6HgH[C'aF*`"O +?d6[8aKnicFFAO`H$O^^G^4XUI",mfeAoeSVd".`GC4[]H[9mZG'A1ZH$4CXF1'-+_T'O2^%_I) +qu-QmrVbQrr;Zfqqtp6*NL\S05\k@[E,f`1H>RVDD/#Egg>M)FfGiYN?qbKiLm49iOHGSl83]mQ +8]9lbqtBses82fqs8MusnbrRfrr2otrr2iprt55-_l]rBWNN+mZg[nnrr)fprr;usrVloqrr2p2 +qe%/s*KhK`+[RCi,nV%4,kh6;oDT7"r;ZDrStM^gpAP!ir;H9fJ,~> +nGbNGjd9Co_p$?J_Sp@al1rPANO0#><; +_oBa!J0nr'85EYeQ)qgCa1f."a3W)P\AYIW8nC:]?"QWk\Al_,^Wb!GrPr$`aMuFdFQm?DM#g.4)/n_F`q_?HY[M?CM0!_f\YZ>f%[?68o8s.Od2)mPEA@, +5"\X7\CT6]c-48N_8sX9rQ,#Yn&YOKs2Y2_rlkD^1q^DOB3JD7=B8OCYJJB-dEThQ`Q$!Cb/M9; +`lH6Daj/C7)Aj3D',)`Rk@s8W#no`'F~> +o)B'rr;ZfOhZ*WOq"amg$2s`#s8Mupr;6BerX8Z(r;Zfms8Dors82fq"T88urVcZo"T8&hq#(-k% ++aY3me#l@s82fjq>UBnir8uXs8,^oqtg?j]ML=90eH*G0p%ZdNgc&qMfDm%]A2,qi8NCGEH5u=G +&MA>Ec?,BCfkfJlIYA!p](-Tahbm;kkY8PqYUb_tX30s +8W&pqrYlfq>1'i2Y6h@ofdG=F)c;DE-H,@Dfp)>G-BKQf>WJq +YgHls8VoprVlcno)AXg$2aPor;ZfrqY'X^rt+/YmI]o=o\TWJq"t'js8;fjrr<#ur"K&).3KjHn +L>S&-6OKU+ +nG`^hl)CN5qtpBm!<2ut$iL&)rr)`jq"O[arr2rtr:`> +L2V$JEHH&9DK'K6Eb\Zun*AWmrV?Kll,UTVaQE@!rr2our;HWp,2:#R_oBEW>&8D/H$XgbH$Xgb +HZsaXE)4X&cG[VHD/XlMrd+Ti(O1.JG(b-aEE(-&`Q>oSA8up@G^+L[GlDnQH$=^`Fa8.s^rF70 +_SO+Ls8Vrps8DoqlH/f"rr;ons7ZEeofR24DJX?6DK]f;DKKl:Ffs9Mf#388@ul_8R$IZ8&X\lE +PVtBS0fE=3p\Y!fs8Vrps8W)ss7-*grVccqrVca-p[k_lV6R/$W0kj-s8MuprVlirrql`pr"JcL +)'!#M,o7C=(E+/.*$^C=s8V]is8NK#rmIF1S#5THrr;rgs*t~> +nGbK>a`LpT_o^0H`50C6c-+;PaNMoZg"P*+aMYp7c-OPVaNi#IaiDHHc,\)RbK.iKaiDE?`Q$!A +rQGns`k$"r=]SsENP39O_o0a?b0&_bGK.eA_9Ks@g>&Ge,UY,m9Hl-MPE_#nNg,B==&ulcf\>^:_e?d)3lAa2uQQg?[JMmd]i-^Q>P3`Pf^3_oKd5 +^V@J!Y(SNJ;+X8c7!k`@^;n4(\A?5.b&P2=^8cT;E_o;.C0YME^rF.*cdBhO^VRn-bfI]@\C'g< +o_A%Bf\Y?(a2lEDbgXV0bK.N?bg+VXf%Jk2BlA$4GBIhGBl\$1Df'Qse(W +o`+pi.Js/7io^:@rqQ2\>j@c +DKg'pEY`V<46QD:-is4k`9_TD->r;HNiq>UCaqq-dVDf9oU66mQX!E+)X;7ojCeQ^O2)Q][Q!O-u,pP'0SP5!Co[og@7) +s8W&trVlcno)AXg"TJ;oq>:0h!VuTjrt"AZoC22CnCdjAq#(-ks8;]ls8O)5rr:q%-R"]MQ7O(# ++s8'T.@U24s8;ops8Vupq>Lm%p\t3miU,soo`+sfrquEgJ,~> +o`+sjs8N9#_5=X2p\k-irr;p5s7kr+ARMP's82fqrqu]nqu?]ls8N&ur;HctrVc]ps8;uuqYpL' +r;H9;R&-OTW3>girr)itrr(dSs8OA@s8;`lq4K0%4=DgD-'aRUQBI_uQBmYtO&A_pUpd4:E,9Z7 +pi$IUF?/O[s8)Zmrs%B'`PTjerr)k9r;HKls7sIN_8F:+G%>N:H?O[[GBe:VI<^-`F()6"d*9hJ +95SotH?FX[I!0j[F`r+ZH?*Mg_TBL'^2.S,H?aR[H@'a]J9Z?cH@1-fH,.P:`4a1,e,B4Ds82ip +s7"5"s8W#ps82irqWBkWEVseTE@,UAEHH,,;+a;XC-%ZJQB[c#Q^Ei%OHYcJ8h)nb1P>3`deNkB +rqQN`rW<#rrr)isrqud-rU]*RVQm>(Y+V6Vs8;onrr2rsrql^8p\t0K*?Z8[p6$d>(`=/0*[I'I +r;Z]pr;ZforV?HlrsS\oW2#fS`:s90s8;NhJ,~> +o`+sjs8PUXP@npA_9^?J_nj=5bfn,Gd)sI:;GE:oc,.EAd*U"\air#Kb/h]HaN2NHbg"ASaMu3: +`Q$0Ab0eARbJB`R?s-`CDRdU`a8s<%rlX6A-cX6J_TL$Ff%Prt2)cm94 +]tLV,6=F7p7TsmjO12^:_T9=#^W=7)]thCeP[%Eq>?"sX9m!;M^r+^MaLJgq^*ge6^r44-\b5gg +o^2/0hVZGubeqTHe'"T)c,RZBbf.`Re&s%IDK5Ys!HE&WD'j(;Ec#,Y846Bi30]_nP*:ojQ'%Q$ +R$2Ya,r@;'E7>i+b0\>Na8O$BaT'E_bWa=sb/_N=\"mV9>#S1!=')fQajA5Sa2>p_o9gC +_91-:%2]Y)gNO>B)]fb0&eTQCb/_NE`llTFa8*dgb0/#DY?+Ij@%QNXs8W#oqu-9hJ,~> +n,EFGgA_*qpA+O`s8N#qr;ZfhpEM"9,9h1,s8Mlpqu?Klp\Fjgrr;lprr3&tqu$Hn"TJ>qp%SIc% +bTn/l1*^*s8W)tr;6Bhi;P,(q>C9mr9HK:VD:P.0NTYTPaRl'Q^F/,Od;Aq5[eb=@V9>"EGp!pE +X$](6-B*%rVl[.Bg"X%3j).1q#:[EWp&Fsds7uWoqu6U3rMq.\,e!aK=sb=;,q>8\s7uWms +8VuprVu`n&H);#s8VZLmd/m3s82Wks8DZkJ,~> +nc&jnr2?+=p\Xjcs8W)trtP(t+!DpN*H1lUrqcThs7u]hq>^Hls8N!!rVZWms8W$1qu?]qqZ$?Y +TVSN_X/+5Ar;Q]os5 +o)C0;qW)QoRCpJWb/hK<`lcNJai_NH":c@_#uK!raN2lXdDs_Ta3huJa8X'XaT'C"bf\#G`P][7 +aNDfK`Q5s,B4PFU@pY;5`r=-\aT'EAa=#*H`R3&W_A:X^+?)G6<$s8\Q^*c"QBmesPa7:m?ZK=Y +AnH=-DKP\oIrfaD/u6_:cHF>McG$d#\&[(NbJV9Bb/V?=h!CfOnMA:ZarXh)O!aiME0[D^#"^r""+]AE#GlfR6c +cJ-[daMl9Dcd&].c,[cB`](r\`R_^P@r$(*F)c2:Ci"66DfKc7CMRp0D)6s.QBmPuPEVZ'T9tq4 +A2Z7X/"/$ud*pIbb/F7ul,`nIs3*^Nc-+2Ka250(?r9us:0LMa^WFRC`5'C4aNDTC_o'I6c-=S[ +KaeA%S_;CM%1jEl'R8?cbfe)Oai2 +p\t6mqYpTQjSo0%rVQNls8Mrqrql`kAgSB;,:]epq#84Yqu-?ds7lWjs8)`orrW,qr;HWsrVH6e +rs%uDp#P/rl2:P]rr2cpr8IW%rVuosnbrAQ0ZQ@83a>0nR?<`"Q&UfkQBIQ#O#:fqG]mnEFED?o +EY3;5E^RtEs8DuqqtJOU`5^a2rVmT0qu$KloZ)N8HZa[J-lE$c!!3-'rW!T9!sTN"?K:tSm.K:C +5SO2#!!39#!#,P;!<<*#-UZ2IoC2;C!es6BU^rs&K"q=j[X +rVQU*rSd&+mdTl5g].MK9p\t3eE[`@fbl.D6E[ahYn,N7Xrr)cnr;ZforVZQhrX&N" +qu-Qph!FOerr3#rr:L#>~> +p\t6mr;QrukG,$MqY^BnrYbb8rql`i@j)I%*$qQ^p\i"Sq#'p^s7lWjq>UNqrVc]p&H2P)s8W&t +rpmmgX/;ks\b?"#!<2rsiVk2&s8W&eqtrc5`&oh7=@6qlOd)/sNK0BlP*VGq2/[GXFD>f9EbbAg +F`2>=6H]6+rVuosqUEC$a5[!rqtp^CdBH@gToG]S4]G^4ISFNr=]aj%_/ +Bl\EHG]S+\H[^BcIX-6hH#dt#Z,45c\@&A2C3suJIWg$dKQhZeI"$NlH%WuA]<\cUUpTmrs8Mrq +rX\)Os8W)srr<#ts6)LdCN9;lrGa3%Ci=<4EH5l6Cd*0.PEM9"O-GukOHl2nQ"!3j2+p>.8G;oR +s8W)ts6]gbr;ciqrtt_7s8;cns8LfWZ)b"-Whc?Ws8Dlqs7lWnrqud;p\t3dD^6JRaSYf.E$\/J +m/QqUrr)cnr;ZforVZQhrX8c*s8W#XURn$Eg%YLGs8DZkJ,~> +p\t6mrVm?'n&AdA]#2b7aMu30.J_Y6uJBSPa7SoNgQ,qQC!XiDK9rD +CN=K;C\VmuE,fYIU;tO#aiMHE^::kc]un[Ea2uWN]>h\@m*FhZlKcESYI1s[c-"8N_8X@)\t!4c +?r9Wg8nCSNYf"Do_oTs;a2GU1bKJ&C[Zr[b@8p66BREC/\%Kf(^V\+?_na"#^Vn74b5U5H_S=?m +R`X%'`l,sBdCZs8bJqL"_`c&g`Zf),DfKiVH]s\UQ'RJqR?3W"Ru`b> +6!5a$0J+a&e&p(aaMu3=aN2NHmE#7K5KCskaN)?B^mSeB<)67h=(/MU`5p3G^W+@;aMl'9`m)KF +bf3B~> +pAb0lrVm)[htmBMr;HHj(]XBh,pF]X,ppY0s792:;5WjVs8W)uqtg[2\KNB`:#QtJ7!!3'!'*JON.6uJRo(2MF]K@YS +!<`W9$Msi'"oeQM#9cHgl1=N;q<"S<*!??D!s&B%#7hRh)]TnE13@JF=A(tU5f3*krr3Q-rT`/5 +r;Q`rrVZ]noJ1Q/pi7^#EH?5ADf9`?F];S3Q'[Q"R$a("OdM;sR"In9/Nu +pAb0ls8N<&qS&iHpA+UcrVdW5qV*/5+;Z+C_tsE';'J`1me$MYrVuflrrW2trVc`urVZ]lrr3?" +k*W$AVQd;_s8MuqrVtjU-NEo7s8Vk#><4W-QrG_^T-Z3jBEc5f3EcZ;"=d>29O-uB&P<=nlOHZ#_6X2*&3Zqp>oDeL\ +rr)l`rW<&trr2p1rr;roqYgHoqT#qDZ*1.1PeHhjrrW0!s8N#srrE&trt"o$W"p-fp\k-lqtBaV +s82cp#lXc#s8W#srr)Zlrr36&oXLNbT!\:lrrMlmpA]X~> +pAb0ls8NQ$ifRSp]Z/+:`l5s;aSs=!c-3['&/l&m$`)8&atQ`kJQ[AmeqZDP=n``r=-:aD\1`5TKuWe)R4 +:cq6E;I!+i]Z7ds\\Z5`aEbV>_T'[jghUV=RY_8X[6\?Dg&R?a,(NjO^V:-h9C +/YU>4ai2?BdDWK@bfIZ;^VS.?dMc_1DfKi>EGoZ1Df9T8F)Z#7F*)M&>*bD=O-uB&Ps1@tOd),] +5Z]0c.h,3@dbDgaaMu3<`lQD(c(s8VijrV->B~> +q>UWts8W)srr2pGeCXa#rqcHjs8Mrrs8Mrmrdl:;.3fldq#C63,9e9Z.WW>up%SLbrVZZorr`/o +q>C6l!VuZmrs&)PpZq)#kPkJ]rr2p!r;6EMr[.OBb"hV?2'b"P7:StPG*SDWRl6+gMjTZqOd9!G +DfBcCj7iKJrr)`j=K%=0>#8F/F*(GS/L2DR'*e@7&eQ$/ +`U)p`rU8lp3#i,&$ksirqZ$X2'E.tm#VA-lmeQMKmG_M"%KQPA!"'A]00i--;,9qkF-NrRd`-cr +meZ\Tr;Zfpmb@U7rr<#ts7uTb3Gis:ErU5/G&q\DEcQ5DFDu5.3g>elS!9,$O=+h*R@08)Ma(NQ +.jud$o0fq[rVlcqnbrRerr2p#rqlNgrVlg*rqucqs4HW'mIBZ:c2R_ErqZTirW)orru1e-/14a' +qYL6ks8Dorr;?Tlqu-Qmqt^0is7lTnrsSW%s8:g?lf%mDq>9gaJ,~> +q>V!)s8W)srr;rhWhnePs8W#rrW)utrYkh4r-fV)+rqOOpAOg**ul4F-Z?]ioCi4`rquctrqu`n +rtYJ/rV6Emp[Z.iVk'rpanYc5s8MurrVtjU-N!hd:@r!N+>QMT@S/\(Pa@Q&2Mm]WR$*l"Q;pk% +E,fi;G].J;pi(7oF)*brs8Durs8W&J_8OC[s8W&srr<"#Ul'G+?#4VENb2mBG]@YIG'SCbIWTpS +=2i\4d*]bKF_GoEH[0d_GB&@_I=c`fF`DVQEGeXk]>:k[XK>W@Is6*hDgQeOE,B8u>ZOd)ApKE7 +YcW#2qZ$Qls8NZ0o]#oLrr)lrs7uWc3GWeXqJ[j)EH#i8E,fr>DJrlAP)tipP*(of-#&C+R$*_l +5$_;<,UA-87'ZLcrr<#ts8DKe!WW/ur;ciqrtbS2qu-Qnr:I.uXK/S+X-*&Mrr;cns8N#srrN,s +rr36#o-Y_cs8)Wls8W$,s8N&ur;6Elr;6 +q>Us(s8W)srr;N6E+#qDbeR8at*"`>_cd^C<"q1kI#Z.,>bf\AQ_SO(+`Q$!A +b/hTA`Q63IaN_l?[YA$rie9C+6[4`5om:a3_`:]X5Q#c,duF`ju.1&H2ZR$mo/!ApB6)UT(l>`lHc8kNGSI'LN([&9^o[*ln4be:?i^<4[#KK=6P<)?k6HV'4/\%Bkp_6fP\Ea1se/1ND; +6;D$3KN)s@fZD+Lai_iI\CAgH_Sa10`R3*W?>a\&F`VVDDf9c=EH#o;.<9NODfB)EPED&tQ'@Pp +->JU/QB7;d3a#E))&7/B,)F:\`l5p:aNDZoaSj9\a?@S``Q-$A`PAck@oQ0% +q>UHnrr2utrr4VJgtMf.r;?Qos8;fps8Mrrpa@F.*G/Snp&F`,/0#lU+[^u(4aiNZQ9R?YOd26!P*M1b +@!-L5Df9W8E-$-sE[l-NF#WdkrVulrr:ngZ`5Lg7r;-?gr;HG!j5]Ucca0'o@n&:+5;t)6&H)Ss +'fSkOp\O7Vn(:&]%KHMJ(`t+0!!!'#%i6N+!!!3E1njF0n+lS?LGTPF#RU\U+sfTgMm(4QhVRSk +pZgJ+G.@>?qYpL"r;,m>qYL3jrr3-!rq]'$qJuUX!HN2ZE$B:BF)l2AG!qO`QBdW)RX$nOPF.?' +NfZn<@k9;mM*Nfcs8Drqs76-jr;6Ejrri?!rVZZos8W)urs82Olg=E2o%Ed9rrDokrZ;+7rVu`k +RO3^Xs8M`lp](6hs8)Wis8W#srVuoor;$?krrDinrs.WHm,[O5rVQ6eJ,~> +q>UHnrr36&s8W&FWNYsms8W'#s8N#rrr*c-,9IX9@9I@;s7C4V'c\&0*@2qurq66hrVm!!rVQNk +rt,/,qYgHop@+BETVSTikPb;Ws8N#ss5Er)rVt&,/Yb$H+';oW5!44UQ'OWoJ!$"^Q]dVs0jo-E +FDYl5Df0Q8q/?OYE,RQ(s8MusAc'rm`Q.?Fs8Duss8W"'h:h#Dbd<^g?qjKtBPMC*IZelDM"4S\A,Yl^:LYR +MK6W5s8W''qu$$Gs8Drrrr<#r"8P?$EVOJQDuOW!DfB]8D0'ecOdVGtOIV\^2`-Y`N1c/k8QfIM +.l)fB0^o&@rr2utrr)Eerr<#s!rW#rrr<#s3r]0Yr;-H>XKAM0VlQ93qY:*jqZ$Tprr<#trr;`k +s8)SX,(f=arqHHfs8MoqrVlcqrqufps8Vrnq#1j&rr)lln#W%MT>LR*s8Mlop]#a~> +q>UHnrr5^ls8VGXB5=oud*9_N`QHEE`lQBPdL?j#%Sf,R`n&C6((V/f#RV.QI+ulg`Poa7`lcHJ +b/hTA`lcNNc-48>Yub@7=_;TR_nsL7`r4!Y`o>&fb0/8/+r6=g*un9e>WOihOHl+r3.I'UQC!c" +Otg?eEcl8;E,]`9F89g*E,fhEb/M<>`l?*H`4`jkaO&,MaN)<6V#XFY5r()C/2Jk/4%j=8OK#t/ +_Ss-dHSo@u7QF"=F#9,m]sb"rB8!S6`l5d"IZ_On`k%jS=CP*!@:s:MJ?$)t`3-(e3[upK5tkBk +B5M-a=_D,DV<6@Ucc*l@b/:jBd*0AD#fOd+e(QH^CiTDr!-A-Z!-%pU,B.XCEGfl@6^!n'QBRr1 +GW7RDQ&;/kNCmA`.4?`m.2'_Nb5T?_`lcNLb4*LNb5]OHa2Z*ucp!^WF^< +`l?*@`l?*Bcc=)N`6N]9>JS_/]u@_-b/200\\?J +q>UHor;R'%s4lE$s8Vferr48Aqu?]oqt.BE)^Qriq>('coeI=+,TnNZ+EcZJID>A2aFE2XeoDJXes8W#mf>PYIkl1S]@/g3*roS%go_n=NoC;/(gV'M@>W!Q.!!WE6 +7ucp,q>^-LTK4(q!!OMg<]h?%"ptY\.O5i4!!E]_?g7(Pk3h371*6r+!?N^KbhqUNnF5f1mIU/A +nZbrXYNtZOrVZZp"RY7Fq>UBn#5nN"l:>o5qf;^Y.<0ENF`_\FEHH;BD+eW/P*hT!OF0>cCm^NR +SUBjs76-kr;$6hr;Qlur;?Qjrse/Zo(;G9jO!r,qu$ +q>UHor;S#@or=h8pAXpfs8Drrs8Muss7N`@'HJCOp\Fj`o.:Li)]'[s)%7Z0g\UjIrr<#srVQNk +rtbS2qZ$HlpW\kpV5gH8pAP$irr2rtrSIN$s7uUT7r'n#1fIU020bFSQ&.@fC65!LR$!_`1hq/R +CiOH6EHZA +q>UHor;SVQiGD_\]u\78bJVO +rl,hubg+YY`OUq*>ZP*@NP&fb0J8b+#I@X)`:]%/MhL2PEUh\7V\$UP*hAu +I5G\]Ec#i;EH68ED"qu_Dg*\P`6#s?ai`)S_8*Frc,RbGbg"JW^5Dt^+s.s[2b..^@Sfft>B6FF +^!=`m?U7^K2*O93B3C_4\?DB.:f=:2ahb3G6V+/t`5Am;3-8J-;.F)u;:8njNPR@9>% +HU(&7Q'7H%P`nC:@mi*r68Hd/b5T?_`lcNLb4*LNb5]OI`l5p:aiVfMah"p"?;scu +`l?*@`l?*Dda-.Uaj/TKEl?2GdDsMNdEBJE_njO=a3VK?cc!oKq8`ubaN)H?\pRLR=DcU[oDa=~> +s8N-!r;HZqrW3&urVnA&fDkmMrV?p1@;=S_srs88i>,9n6Q*?lXL+se]9rVlfr +s8N&u)>s:)q>^Kns8;osa7AlnkMlOAqu?Wps8;lps5EtWr$D&f8k_?9>\>iGQ&qGuPBB2^BpXjH +Q'RYH9lk2lE-?5BD0'Z4!#\>8o`+samG(5q'*&">+=t8g,SLFn-SV#U('=O:"8ZR$*]&Oc;P53%7m#I676%rr2iqo)8ahqtpBjrrE&tr;ZcrrrDrqrs\#Xm.9W2hs17AqtpBk +s8N!>rVlfos8Dkfd/O(Er;ZWnqZ$?is8Dioq=MnerqcZnqYpKo!<2ut#lEWFmbIjBrqlBgJ,~> +!WE#ms8N!%p["lTr;-?js8DpC6krr`5tr;HTo +)#jL2s8;c[QEI*_V6B^ks8W&srr<#sr;H-as8Vrprr;uss8=;Bom]J'3'gVT0eJWNS!9+Z6:YaV +NgH#sP\*X2DK0Q9DfKQ4DK>PlF)Q,644XB1s8Murr78g)_Wh!tr;HNjrVcZEG2_E3gXFWsc-4>J +`4p;*GB8"SG%.8mcd9bQaAm2'I=ccZ<7>#lHus@N?_:2/I"6HgF&Jg?\@SZLUHs!BFaJ1;al2.1 +eBuRdbJ_0.];J`?^qojHrtkY5s7u]_m/?k^rr)irq>@rrCiaQ7Df>Sn.W99FDf0K4E,'N8CL'Z! +Q'@GrQ!m6c +!<)iqrV\YSrr;rdc"C%i`lZNK`P][=c,R`Bce:bu'Ga$cccaMZLC4k:(`*f%(D[`!%bT.PaiV`N +bfp(-s2Gqtb0/2T`3N?T>?4gC^r4IDai;<>`lQ6@`pq.M`qmdU`rF+/b0ADff4[-/2*tMZ1bOrL +QB./N6:YaVNgH#sP\*X2DK0T;E,oc8Dfb_oI<0UL0X&U>b/h]He]G\BZcg_9`6-9LcH3M1!%f*$ +)Bgan5=.k4@Y.ZtS$U2[U-D7K5/]6,pm``lQ3BbK.Z7 +SR,Am=&rX0Ge;&;b/VHBaMu6@bfn>S`llTWGG!%*ccXJMb/r/M`PTR;e'?(/Y0+W&a3)R%a:-54 +`l?'2P[I-_@BSkds*t~> +s8N/tq#:9m!rDfnrVlr\eE-]04T,*Nqu?]ls8VckkU%Gu-)CS>s82Xs+se^Kjs6i.V4'k!"93jK! +PF.StP%IEj;3mB6QBmn9=`JM&EccAFCi+B5BPMU,E,]l=GBJ"*T)AWfs8DljhSd@Omf!%[rr4hS +rV6/`O7E,Is8;]fnFZ>Fl.;4_+9i)o5Mc#1o_@[S1*?c$!"C85f75q.%i.>lc:K&ZrW"5Z3+Lk/ +n*oi$;)o0t.Rgl8nbrCco'c#9rUKX87ZrO]Ph>[.rVca`n`fiEs8W)urr;b/?#4Y%EHQ2@EaE!E +:0;@PFDc8BEc?,65a@\(Q^*\&@SpBuOHl0!Q'tWV:fq'X1c[Vgr;6Nlrr;Nfs8;orrr;io%KH@u +q>^KZjlu4&o^U?.rrDuoruV1;qu?]ps8ViXs8;`nq>UEkrVZTls7Z9)K./+!rVlimrW<-!qu-O" +hWO7jn,NFcp&BO~> +!W2fjs8W')r;$3-WP8-$rVl`p-MdZ@q#BFt)''fls8;omp/W+R(a0qB+Vtt9(*h!!s8N&ss8Doq +qYq$$s7l1F_bT&EG]T2EH#r;DGH\us8N&srqbHh`Q%6Arr<#trr)lqs/hLHeCE.L +c;;L#_Sj$rQXXuTG]?Krc-F;RaJi?_G^b'aBNjP_Ed)YGDb@`?DLHn]H['FF^Tk2OWi/d.D09r< +^>Ro/eCMmibfIZ-_73(A]tqMYs8W&sr^?_Sn,N:brr)iqs8$J8CNF?2F)>o9?!Brr=);erD09f: +DK9>QPEhK"PE84A:g9 +!VlWms&T*pqY9ses8VcQQXk*F_Tg?L`59U=a32T>eC#3M'b?#Mbg4Yh6P1.J(CLWe',hr,(U)?4 +`6#s@bK@oKb/hTA`luKN_MDGsr(?bf[rE`W!mIa99N%`Q$!ub#$0sb.l'7bgF_nf-m4B +;DT[k>W-\dQBI>lAP?0%Q'%K"Q'Y?ME,oo;F)lA$$6^T`SZB,=dE[A\U8M_:(+ +_8X2FC58:.AT1.^nC%bNRX'a2Z-?d)<]Caih]EbKS/Q91ioC +EccJBFE(Gb8P<&uD/j?4s)ATgF([_'QC*u&N^I/K=dG&1rfdq]:g$Lm=t(pJ+O\`^b/ME`a8j6W +a:H80`jp+o=]SL'=\c?@aiOG#4N5=]b0/,Vb0%rJ]$SXAd)!`G`Q?3=_TTmFU2(JUAB`'4aN`&R +`lQ6@`llKBai)-+Db`l-LueI1s8Vlm!<7Q~> +s8N/rp\t0ls8)fprVlrPchIG="T/&kqY^?m2#71FOWtqj/b]#?qZ#;#,TA,7^k!^W,9%mSf_k^F +s8Durs8W#oq"XdbqYUrr;QTnnc&RdrVl`p8G`Aap&FJPCFUlH>@KfW+deLY +M`[)B7VFrKRZ<`"PtPG(F)c5=EH$&H-u<"F@6egTDKBl@E+DfAs8;oqr;#6g`5V*@q"k!i2#d1J +nBcTRqu-]0[q\!!!-9/2cAM5<'l<1sFNL*-4(b\:>4t" +mGrU^/LNQ`lMgSMs8D`bo()\We6.liI=@4*o`+mhrr5CWm.gMYs8MlpqY`3_G&VJJDfg2:2C:7S +:O%#(Ec6#?EH>hUQ'RYuQBsaN4aW/YJs)7]PFPNP?=d@o0KrORpA=dbi;O2_p\b$js5WG2p%%h3 +n+cndrquWms8N#t#Q"K#rVuosqYpNpp^=Wd-Rp8`-78H\s7lBg!WW,srrhTHkj.-ss*t~> +!VuZhrsSf)r;5faWnI.DrVcTm+oMB9M]3KO.J*?7q>]"l*>BZs^ORFN*>KM7eGB.As8N&trV?I% +p%"EBW2?W,mJ-SUs8DrqrUKmcs8N!jrVlisrqZTlo`+ANBdbE>>%'TS+-r.UM`[#>6tSNCR#I;o +P=]"uEGof5Df0W@->HS>?TrCLCiO?2C1'd3s8;oqrqkQj`Q%6Crr5^krr;`ms5f93gs40nbg"PX +`4*Lq\P-d_Df]1)c-sbOYukdbG^b-eD-5of??'q#7_u`=Cj:;TGBS"F8$ob0V5e<L9ks8N#ts8N&rs8)`haJGDuV"4H]rV$8A~> +!VlWms#U,Tq"jmbs8Vc8H=N&I`6HNL`l,jQc@$QC%M7".bfe_U)&3PnQD%as)'9_9'YDi9 +^r=7:bPfR$aMu-:b0%]@@q/S;?ZiKc`lcWObfIc@`Q%Dg"NJF"`lS/%;96eu`PKmC`n]*&=rSSg +mMsPY,5$Ec?#9E,TiD-YleB?pAUPD00lBC/ch/c,e#KbgX_G^UVM4 +`PT^9_oB]FeA@Y.,ss".3C6A48lA>b@Wt[d_?#2fd[C!Q`Z\pG/8If3iME$fN2N,/Z +_8*UWJh;.T='^,OBVC824!+n?%Nm;a7SZ`VC2>N.h='UVlds8!aMuBNa1f[:aiMTFcH+9D<-<;* +HZ!hHAM>5[8PF8IEGo[nE[>[FBKDHEOcYck3b^X"MF;rTNfoKl9i>2)=Xb[L4J9sCaMc':i5e[; +`kJ$T@9-E(<_e=c_og'?`l5p:`lQ6GcHFAUb/V]Pa2cEFaO/Gga2a-G$lBTn*"^6+`k]pHb/VND +`l?0E`lQ*;^P,QR:28GTrVuWj!<7Q~> +s8N/rp\b$js8E6&rr2rqf@9d!s7n_Qr;?Nnr;-H`.O62aIf06Cs7_*c*@!93q>Kr&*uuLTmf3:b +s8Duqs8W#oq>:0jq#CB]e*lhnhtI'L"TA8qr;QZpn,E@brVlis9E"n`s8)`pf/e:22E,)J>q%^\ +P*2/"23&WBQC!l#5\4tWEGp&>F)Q&$0d1%#LN7HSF`_\GCGkterr2inqVT90`9dEtqY^@u +q!HG)>f,h$pA!q=m/$AFp>s^p5VGH[pZh&9i@?W#$NU5-$8"1%o@$H/:R9_a;^2JK"U>A?-;&(% +j7(ou<^es\nFlVKs7Q*bn+->?d;",SH?+:ie+E\=rr2p"o'H2Mrr4#;s7uG*>]aq,C2\#Z4B,cm +Bk):(D09uAF`MM=2ZAs_R?i1aBKVHH7k9pjS!/ne:gREt0.S_-Y?(]'rVQWSrXJf$qtpEnmHU^!r;?Nns8MurrtkJ1rqlQip]'rlKIJAs*$c[R)^ri+pAasf!rN#srVm$"hrX4[o)F4~> +!W)`mrrE&trsSi)s8CHEYOqShrVQQn*rQ'9r;Z@6*?-,JqZ$HmomR\n*@p^VrUOY@(E+Ucrr**$ +rr;inrV?I$pVE)jV5^ZKpA=acrVu6`rVulr9E"kfs7ZKhrVtJ0H7Lg/?W^P]2LCOKQUE]kO>Co/ +MjT`oPEA%=E,ff5F_u,8Dc\S6@7l5mEG]c8DJa#Aq>LH;IcGRB2o`+sirr2lpnF6JUs8Muqs8;_0>B=Y%BPhWS4&]QiBOZ($Cijc< +F8p2(C,D-R78ZlPF@YpKMPiW7P62G/$E"Rs8Dfoir8rW%K-&!^9"B=W3)nhjno)U +rr2pWrVulpqu-Qpq>^KmqYTs`nu[Ef,p*g@)BKP9a8G]3rr)irrr2rtrr;rrqY^ +!;cZos8o>DK9W6=>1k,987G,DK^/CD-IUqbPoR;bgaeI]X>i) +aMlgQBQPUAN>g<6n":^R#m8Y9jM!l.O-/C(6^N*d)j5LiQ2&A% +E#lkH=0fR9itD$WPcjWaSj+;aN;WMbK.iKaM#[4_oU0Mh:Im(%MBEf)A3es'VNI[c-4GR`lQ6@` +lZHFa2Gs:TN+NY?H2I2p&BO~> +s8N/rp\Xsis8N&u"T/5bgZ8A6,l[Z;rVZ]ps8)]g`[)]K,K0QYs82@2/0c3hp&4X[=W]"5>l=U$ +'`S(2r;Zfpqu$Hns8;osbNA9\lfe"`[nSNn*h&rVlfr7e5pBrVulss8Muhg-BOtFE;_J +?ntGo92]_HH?=.FEHQ;AD_dQBQ^F"1=C4deO%hZTQ]Rc*R>=(5@6Hq0BJb,(qu?Qkir0#Wqt^3j +$f^[Bn+?&+lMpe^s8N#tr#l";rr<#tr;6Hks7cBfqnI#"-6j]R.3fu\)^HMXq>^3brW;rrrqufr +j9"c3m.:7-~> +!W)cns8Dp)s8N&q^SSdFp](0hrVmr;s7lWia<)6:+2RmQs8)4+-QO(To)AFY\$`]L\#iDJ91Ns8NZ0s8D`HWirP- +Y,\&&rVQQlrr2os,Q7Q=rquWirr<#nqYL!!BdOrB)\aG6)''G4)1_M^q#:9ms8Dp,rVufnqtg?b +[A'@g_>!m#s*t~> +!<)co2u`aOq>]oHB7IM'`lZBIb/VK?a2Q?HUCe%F#+j,[c-"04'Fb7XdF?Ot7hcpP6.XN.b/hWJ +a8O0[a;Dq9^q*icA6<2bXLuKmbfe5O`l5j7`lcHoaT'9[aC`T9aMu3>c-4ba7n,oa,9p2d?SG*6 +Q(""g0gCt`:K^;*O.2H#OuI/qEH-)@Ebp#:GW%TDB/*;,E,]o=E_'EUa3;WEc.'nJ]X,T%bK%fL +cd0\Uh:BKY*+)0$9M%<8:0:_/@fmF]S%aMuBOa1fa=aiDQKbfRf4.r0BRFEh_2 +01]eJ:MjlkEGfT3FE)8;0p@id*gMjYd- +S7#W!:f^_"H,IQ!b5]Q^`\tlZb0.oI`PoX3^<"dVU/i*F&eb`s*>]:m(Ca`ocbIWF`l?0DaN2BF +aiMNA`j9;Q:LKdVp@\H9~> +s8N2sq"t'frri;rgtVc*rr`/sr;-Bl)ZKAG+sS:3qu$HgrOXHu-7@=Crr(Xs)'C02rqlitrVc]p +!rVrpr;Qupg?%kij8/`S$iBYnqu6WqrquZjr:9jer;HWos%<4gq!pV%1Ij8O=^GK5/rc6ZQB5NI +6B[[?:iS[POI);u2/mMSF)l5@EHZ8BEHH5@EAN`CQ'6>WFAHM5RS?gnG`"Z +ec,RLrqucm+T26 +!W2lps8W&trr2p*m&?`8q>C3jrr<#prr3*!s7L:/*$J2Tr;QKh\0Dh6,16GjrnJS1*$2B^r;?Tn +rVuior;Zfrrr!3(ou!/iXJW#NrV?Hm!<)Zlo)A[hqu1a4QAq,i?qEYG +Q!-q$4G&TYQ'*q@DJsN6DK0T:D/<]S/Z4eBCiXE2Df7qjq>C9mr;Z`R`PfaZrr;usqu-Hfs8UNb +]!tGbbK.WF`jE7aZ)O_2WCpW#XjP@3T"i%S]Y_\-`IG@-iTp'uflFR9\4s.YH+n0X/DBM +r;HWlrs&H"rVuosrr2p!pU,;G*=`o-'c\;6*[+R6+!)Qrqu$KlrXJo)r;HNlqTkq/SY>BHp&BO~> +rVllrrVnVMq"X^=FC1QM^Ve.7cHF/G`5]sIbtel`$oZPVaMQ;j%0[4MZJ!RP^'k>\$Bi`Xb5TQa +cMkudaSs?^`YQ.C>[M,LA!XmB`Q?9Cb/VE<_o9X@hqh!Y>K-;-Z/Jf^/>+qt]mH_CIDI(ahQK8n2chaRo6"o^VM>hSro7 +=o\Ou+&O$_#SJ@.1Gh6c:h`R4^?4YOq<-2nfZM7U`lccM^!"O>a2l?DaZRhq.;!dFEGf`A8O#[_ +BR+61DK0]9F)c/<16@caOE*R*9Oj3O8lIC&O-,ZlRX.%s>t-1b.[qd+cI9noa:c_;`5KC#HX0BB + +s8N2uq>C6krs&H$s8VN=j8AoYr;HQms!%FAr9>aY*\!HQr;$Bh@O2sB8,rJ^pQ?UG+"mBfr;Zfq +rVc`sr;6Bk'%H=7lf@=1s8Durq=aX^rr;usrqc]no)A[erVlis!<2ut8,#e42C_:$?t!:s7[9.0 +O,Gr$:6^uk5Aj^rT9bh.1N@ARFDu>@G&;,ADJX/u<-`;%FE2SA7eZf\rVlcoqr,N3`8pdlqY^@u +nE-m&ItWt`iUcp6oDALcn,*"Fj1afjHJj[(K7\AqGB.\HJqleMp\"4La*uaj:lg*IEI)qMEH[P= +=DPbBp@2i?="=Squ6TpJ,~> +!WE#rrser)rVZWos4O*Go_JOcrVuos.KBAHrTYgR(F57@r;$Bf?Q^(/6iHlYq2lXA*%L^]r;Zfp +rVuoqr;Zfqr +s8W,r!<)lr3r8XFo=SXE[D'SraN2ZLaMl*6c-aTH'b(atd)s8RcThmB&1H8Xai\Z2(CLc#bK.rS +bfe/Nb0%fHrlQ+u^U%*Q?X[>cYJn5rai_ZF`l5j7`lQBJb3d:L`b!38dG*80)'p7e:KUk'0gh1f +T8n^a=A+jAHp2CO7\5m2P;7)qE-#r=Dfol5GAV,3?rM;cF)u>A@kuETb/MB>bL=SD]X>W$ccO8H +`5p`hnDDs_fs2E-=AVI\<`iO#@;&qP=>aMG!*1Ul_s-mip\".Gikd&t#RhCe"9;//-HY]Gnac,1 +k2bB~> +"TSJuqu6Qo#6+N"s52W+rr3-!s82`lrr3u9s8/T4*%36"s8W&olms5%,cpk>s77EY(aFD*rVuos +!<)oss8;fp"oHg;p$(N9s8W$'qY9j_r;Q`qrr2cpr:9jer;6Kns*"5%3JfjS@Rsp59JBY6Q^3r( +GXbS.Pa@Y)@r4DfQ'ILgEH6)@G]%P>HZ@FEhItq#: +!<2or1&_%Kr;?Ti^88gErVuirs8N#trVcZmr1Y,F+X?.Ls8DcY-lO$HW;-5hoH54i+F*e_rtk\5 +rVlforVuorr;HN`c]b')VQAGFs8;`n!<2lqo)A[hs8Mrr4T>*:2hj@I?UnL/9.sD0Q'@MuG=>A* +P*M5!@;@u^PEV(_DfBZ8G&2,6H#IG>EGff1EGoo8E-,SdpAY'k#lal&i5N^Thtd9OIf9[+Uhdrd`4*FaYI_3BRo7Y[b/8.-\&,hi_8O@1_S3^$^uXYQBm=K2F*M;=EH5r< +rbs6'E,KZ8DE#7f?Sjns/bo/#rr2p/q#(0gq80G;Wi3"t +V +s8N/tqYU6k%/oqmiK[u'^W+7/aiOJ*3Q/_Kb1)7V%2TPoeBQ+W`!lqZ$]EEVd)lS'#Rsk[b/hoU +ccsGKaNDTFb08#J\WBTi@pj)@]u@qhaTBN(`r:H>mYBEc6#5Ec?,JMd*0_S`Pm>Md`Au2 +\&Qk=_T'O0`QR<1f[f$Ggn-`F;ccOg93,bA>u1N#853)!.&b_bp\XdZmH`KC1Ed>C$NU_o!(83H +m.^DMnE0,kaZUgJ9Jn+[!rsYT#9,6Q6;(^+5f27@m-4-3kKiGEaMu<@b0\&@9"Q`QliKdFVP9'lDIG_8!n- +bg";OaMlELbK@oAZ#WZ=@?BL?rV->B~> +rVZQm"T8<"dG4a$"T8)pqYL-is8406-6jXKp&Fshs5@Q@,:;jUs7X#K*@2rWrVc`qr;Q`prr<#q +r;?R*e`QGgm-OcPrVullqY^6irr3-#r;6Bho)A[equ6WqIJQ2q1+l=.>[^`"EflWL?=f@294LMX +QC)t_G#2>,PE.M=FE2A?EH?;ADg?8@E,p)?F)u>DEbAMOqu-QprVcTN`PfaSq>C$crVufpqWb/6 +FE;_aG_=u?m.U2BiniU9f(Jt8nD[\LNf/U=GC"alMP=n4s8Dutp[[l_Q<937MM?h`X=`J!Z@fPCZ&+>[9!F;`ssUir0Jdq"asiq>UEbk4SQE +q!HQ0rsSc#p\=[drVuosr;Q]q(B4/'+X&=V[dWnes8;oqrqO#I-rKd;qYgQorqQHls83'#p#G]/ +hZ!QMrW)tK~> +r;T^prVc`qrr;8YVq^nErVccrr;Zfqs8Vrk7NrfjBCc'"rr:kb-QXJtqZ$<$+W;LIcMdbBs82cp +rr;rqs8W&qrVH2YU8aoi]^ksts8W&ts8N&srr)lfrr;uurql^drqJ]B/h9S#>@:MsEK?[rq+ +8n(;SPa6PWFA>o$Oc;)5Ec>r7DfKl9D0Ki8DK'Z7EH,o:DIQWAqu-Qprr;rT`Q#pQp\t2`@:`h8[l9Ec#i:D*E?2OuI2r1l[icOoA>o>E4+[I?fq_P_)8.>$EL;:cnLOir8rW&,lP(s8:ZX +Y,\G,XI%H3r;?QrrqlZlrso#,rV&c")'a")mIU2Rqu6U"pTth^9D/5]rt>>0rr<#srVZHgs8W)I +St;7Ao(E$5~> +s8N/tqYU6ks8=qKaDYXV][+O5aN)HJai)';b189`'FmmacGn#Q\O@/=#Kk?=bE`PE'b%%a`Q$0I +dEfeNaNDTFrlPbh\Qr9A=(Zol_o0^?a2uI%`Gc!1o/FYmH`lojijeN*u"tf!@oP(piplU2o'l58dHoK,a2l9Ccbd9:b/q[QaiMKDaO!Fa +DgQ5?F`DJBE-,`:CN=N4FE;>@Ec+*iP`Rb;DDI-8OcTK?'NpBA.>!qMQ&L)S?!Ubd1-HW(bKAkd +'#qo.b0J&I\<(#t:/"bl:R8i +s8)foqu6osr;ZcLh#IEPr;ZaLNsrV6Ej +rVm#Tkjn'"rr2utrVQZpqu6`sr;?*as8;`m-NEU%0hFK8?!pS\9U(j/CGKdn?qjisPa.`#A4pi$ +Nff)\E-5frr2p"kj8*DrVm'"r;Q:t>jcVaG]7^mD3p)=D)I9?PF%J'?XHQoI6'i]QB[Z"P!E8Y +@6#i4pAOsis8N#rr;Z']&H)>#s8W)qqu?!Mq>KXEn(%F;"8hohqYgF7rqu]os8DlqN[#fdq>C9h +s8MurrVlcb,T\Djr;ZZnrqlZos7u]p"Q8h>kO&6J"9&5urVc_G~> +rVm?+rVc`pq>^E>SZh_`rr)lsrZ_C>s8McL+rMC>[Jp.)r;QTgjGAH_rVuM4*u>tiq>L?nrr2lp +rt#).qZ$Tgc^Lc:W2SVIrVlcqkPkM]!<2rs./s2En38Np3*]]q;CP5$Pa#l9Cm8:#>"Fg?R?(fK +D)[E7Kfj6oATmT_&TM`#9_nYcs8W)urSYZ5`ROh\s'Xj(`Pf[/\O&W6YdCaE\$(OHG^G&D=gCmKl9Cc%';P*V8#?=$?kHoONVQ'7N"P<`;V>rF*) +pAb*ks8N#rr;Z']rr3Q,qYpNprOo52Y,\Y+SFlaYrr3*!s8Dops8Ms*r;MQo*bb6Cs7u]nrVlg$ +rTkRA,MDtmrtGD1rr2rtr;6Bis8W&mTUqUGc2R_B"9&9"rr)kI~> +s8N/tqYU6k8,*&RTjDN@`luND`lQb.eT$'+1,WaiDEFeCV`W?I-gAbZPJc&iA%Y`Pp'I +dETYJa2u%F>@`r*s[aN"4u"ieX+bfn6#aT'B`aN"4u.*0Z`d3p)"2-X6i:a\o" +Q'H)=D3\C!=@SL=RZM#ODE*W;L-9HsApd`Au3\%0u.`Q6-;_SaUQeD'E[ +lf-5[1/i..An#Cm2ulTA6:XNQ(dA".VO5]^cGZ\="99AM#Sn9u.S38['hX.GP[d`B9laS@9f"Ii +84NY@5>G'B0.LVYir8;Viq<$Cl-o"NaiDKBb0[i9aiaV(#0Fj%b0WnY99XZ^8!9)7NY"H_@9tZ)0[S1gbKIuJa2Z6daAg0s`QZTN`kSp"&lmZ5ccOY`bJCm.bKg_3(VIr.^;It7c-")HaNVoRbf[r>[8p+$ +AZ"\ds8W&os*t~> +!r;`krVnSNs8W)un)a*>s8;ckr;?Qnr;Z]pqg]k4,V&6^r;Zfrq>^Kls8N#on/rhs*h3!*q#1]u +r;?Tpr;Y[AjPoOqrr;rp!<2fon,E@bqYhi=s)0>I@V&nI1dRFiPa+fuH&kp+CcRWHP*)8!BKCX4 +HTc"aG&Qnks)\fe:AXtgrr;rqqV]?1`7Y+drqg'tr;?B[^4glVG^G*tQ#KK0Nk39ZCUF\q#1-ep@\.Lhm.NCmJl,TgM3=!FCc`dQ95\ut +I>ubKs8Drrrr_KOq#:9ms8E0!rUjN)mrBmtC34JeCQs917qn9TR?Nt#BNe,pKf;8@R?a/'R?9X@ +>Xpt?bkV&6rVZWolM^k_q>:0k$N'Vus5j(KmdKYsrr3)tq"OacrrW,qr;Q^3rVPG!+><<`s8Duq +r;Zfqs79>G+HlNrrr;iqr;Q^&rqQ +rVlrsrVc]p#5>Hub4kl6rVuos*rH!6s7q$`)BL3jrr)lsrqQNlq>^HnqX>LF*?(@?rr3*"rVc`m +rser+p&1Y]VPpZ2nGW=brr;lp!r`,sm/Ht`./s2@s(j&A?=7&=1I.1cP*8BmGE#O%CH.BBOH5hn +AiP4,GroSYFD^Jc&7nN0rr2rtrr;rT`PfaGr;QNl!oUl2rkhpRVPo)H8_i4Y +OBbn*B66sIZ^m3;k2"eFgXXa#cc;u+?#+_T]"kScQW2PbbJ^l%NeCSJLT%`#]>UbAMn$dH_SEt[ +s8W&srr)]UnGiFcrr3&o?XE2?.W9!@ECXc-I60o3Q'I`"Q98e_9Tt,f5'<6WR?X/&4'u&W3]bL\ +qYpHkrVu0^rr<#q!<)os$f7ncWNNM)QgF>@rr)lsrVccrr=/f*qV*24.e!97rVuclrVm&j;^`ND +p\k-jrrj~> +s8W,r!<)os8cAPdkC$Qg\]E";`lQ6Db/;?;cd6)6'G;#!d)edacR_aNb,)'Fo`?bJhHE +cd0hQ_8s[=aNDW=_.?tP<+C9_`lcO)ao]Z(`r`lcWVj&me]F`-_hHuEk/37?$i`Q#m=d`Au3\$j]-aNDTB`50IE +dbscblKdNQ\TTka6=jnU!(f.B6qooH5U8!)(,/]\=>;"2-ib;##T+X+,W81m>uNF(4A]X.BN8V4 +!(K">#e6s +>ZOS%]>;J-aihfG`P]U5aSs=:aiq7'$5V"3a2cKMbJh94aj33r&Tc.5^;It7bf[uIaNVoRbf[rC +\8G2@?&@J0r;HHkJ,~> +!r;`mrVulrs8N>_kl:\^qu$BjrZD%:s7l=4.3Kdis8Dusqu-Qhs82`ks8S<2*?6^"o`+des82up +r;Q]prrggHk1ntqrri?!r;Q]is7$$fr;$=$YDj6>i$TQ"3?GI[!l:F#9,GPFmqn1e)PK +GsQXpEHCYjF`_eB:&+bfrr;rqqV]?1`7Y(dqu$BeqY^0[^kmMdH$aXfIX?m2FAk_XQN-sZmH98J +o_\1NkMaRn\`2lIbCf!Sp\b!iqYBmWlf@*fkO8'2lL4<*GLZ$QqubKs8Drrrr_KOq#:9m#Q=]#qt=0%EU[uqE)^Rk8o0`A4>;kaP+7c#3,DhoPDD/*99>@%Q'7Mr +10n.4/5?!?rri9!rqlTWrr;m+rr<#tq>^K]o(DA:o]599rsAAls8DutrqlTjrr3f2s7[o`-+s3S +s8W#ps8VrqpT,\^8H&MarW<#pr;Q^&r;$0es8CmFle249rr)orrr.E~> +rVlrsrVlcq"mDSSkP>,Vs8Dp?`jJCm(*J@RN5(P#>>!0TqT]SW8I\ +6ue935BUp`EU[oLEb7r;rVm9)s8Clp`5U:*rVulos'X]s^VRe*^!+C/_6A]&8S`S+e'Q+MA$+MF +g"=KbZEggY`m_)5gZ@8Hf\"QuccO5Oc,ml;^V77e\#i3,ahbZtYVD-G\[]Ae^W3mJMi5'`aM>a1 +p&G'jrr2lmk4&ELrWiE%s8Mdr@W1aT/oFU%Db4`.IQK3DQ][c$OuI/\9Tk/h?V6BBQ'RZ#OYL'E +H7MYbrr<#rrr2fllMge_(]F:1rr<#k^9FcAXfA&)p](9ls8VrorVccrr>P_4s7IWU+LqCKs8Vun +s8W#sor&rJ6i6l_s8DrrrtYM1r;Q`rrqOj1T:_tIr;?Qorr2rsrr7K~> +s8W,r!<)os:&F\]csg.Q]u\F?aNDTHaMZ!=`mG#0'+J[,bJqB6`QZP=t09_T_Sr\[`7<4K75^%-dEq+/LDgGeMd*9SL`l6-LaLSskZHph@bfIcC`QHi_iqMj+ +n`]K#d`SkJ="5O(6S:Ml=TAmP()8Jb9h%B6@U!q_@UiYA:K_0-7ScTO +=(qe^YeeQ=l0n6(^::i=oCD/,cg99*a2l9Cd(R08b5TK^aT]Z(cp:iSrGhgXpMhg(;.j`9Bp!d' +/WH$VR?:YcdBtX`kS]s>#\L&;bqVN +_o0L7c,[iC_o'L8b0&#Nccun'%@bPY`ll]QbJ_*=cArbO/_%bU`Q8&$rl>bqbg"AS`l,HI;c$G/ +`pENurVlfos*t~> +!rMopr;R$$q>^!DlMph^r;6I7s8;l0+!VpQg\^pKr;6NoqtU3kr;Z4V-Qj^Qn,N:]rXJf&r:g6g +s8V!?o'55frr<#rs8M]knc&RdqYhi4BeV5H@UMPP6%+iXS5*ETI[=AADEEo;T95J-4ZmeLHp2@d +/TgN'6?@XrqeAKqt^'dq=cZ&1Ao])6%OFMb,F`q@n&-;nH;f[)$HApAG +s8Drrrr_KOq#:9m#Q4W!qY+!#EU[uuEC7rjlL2+!UoPa7S]6Yp.-P_M28240_mR$3`&KKi[2 +9K8^r;$0cs8W)tr;)'j*d%AZrr2rrs8;co +robdQ/D^7&qu.-(rr<#tr;$6es8Us@lJ)77rrW0!rVleH~> +rVuor$3'u)q>Sg8XS2Sks8Drrru_1;\f)P,*7t#`s8Dlqs8;]ms8Duc73WZoD!q?#s8W&srVm<& +s8)ZnZ^mhmZa'/rrr;rrrquotrVlcomf*4c.K9;DnRjI+>[Ul(-U2s/o_e[crVu0^rr<#t(&e.3s8(WR[Ag+/XHN/Prr;usqu$Eks8W$(r;HNfJ/fDF +r;Q]q%K-8)r;Z`W,8_f^r;Q`orXf,/r;?Qns8W)mjeJB;SC7?6rW<&urr2qJ~> +"98>squ-O#qsX![?t$L]aSa1'aMu3>`m:+Z().1id`]_J_T^=-*HO-,o+?9N_& +=]&lkNf'EiQBs]qEftc4CN(hGnSo.YDdbQMc,[cB`QQcR\\,>Wci2.$b/qcHc.^\,p[R_Hl1!m* +lJL4@5QG@X1dP"l!%A]=\&Df9]u+6tT]l7Kqu$Ej +s*t~> +q>U^!s8V0:q#CBnrr2rsrX/W"r-g4>,U^D,qYpL+q>:3frr;iof.@gX.^/jOrV?F$r;QKkr;ZfB +p?h,&m/I%br;ZcorrN-!rr2rtnc&Rdqu.u93&`?l?=,W71PV0cR$KdF5Cnu-p,RpA4R[s8;ianb)88q#CBjnE]Q4lK4&*lFLb7JphfaEdMe4'*\F@&63[g +EHd;io`+mhrr3)am.gSZrs/K%qtg%eA9%-[06))#2Jb^)P_gttPaIi$Q;gt)<*toG3,1F?O-Q&p +Sn_ +rVuos#lXc&qu".'`qfW6!<2ur!<2ut+8c"_-PdXE]DMC&s8Vols8)cqqu5+q',Dsurr;rss8Drq +rs\f)qu5oJWL^&pci6Kq>^Hns8N&^rW<-!rr)d-s7Nh)XKA_0S]LEts8Mior;HTo*W>p3 +s8;o4*[2lss8DorrVlcqpAabe)'tRFrr2rrrWN9#rVc`ors/Dk[[s(b[.sY"s8;uurr2qJ~> +"98>squ-ObqsWL,A:_G8`l?0Fbf\#G`Q$$M?Pa:i'rBX1cHOVTa3)-4aMH$&)\!5lP1\.%`Pop@ +b/hQ>`Q6'E_o&QVAQ2rJM87'RrlY8^rl+rZr6"NM0ZqV`b/VE?b0SBO+WXKc?8j#^KThjiP;cu6 +I#VN3D+eZ1O-u>q;D`Z]HUMd>q/J'*EBc6n5BW*C +.U%t"Q&h,+ +rr<#trr3-!s8UX"rr2utr;Zcq*r,^+Afr6C-RMHRjnJTMr;Q`mq#CA>+ri'Wo`+sgq#:uaHePa[`%LmL295C\o>8oSB/Pa@]' +P%68"Rt*P60gT^IEYC6krrhrNm.B33s8DqI~> +!<)lr%0$5)rr;8`UZ;(Js8Muqrr4&=s7TtA(`OS?7[E*-p\apfs82WlrcK7u-6`$]s8;lrrr2iq +&GlG*]V2.!VQfgos8)`prr;oqrr;6^s8OPIrUMWk1L+0b8P#)7OdCih3bCR&ODm[*@R-*APa7D? +/qTL?3+jm/D")CiEb7r;s8N&urVufQ`PfaGrVlipqu$Kns8Uul_SX4/_SXR;^;Rk)_j=A'@EO:N +iS*;UhV6]2b0J&QdDO+G^"hQ%gX4BodFZjhaMtm$^V7+d[^*#Q:K^P +"98>squ6UgrVQ'%F(D)]ai26Ac-=JP_o'@;d7k#_)&Nu[1QAC9kRra3)KErPeiYr6"KL0ZqV`b/hTBb0eKN(FN9d;b'kqQBdf!@kWJ'IlV0r5]-%2s)33k2pfgj`lH-CeB5D;]"lt=_8sdCcHO\leD9cjp@[n> +p%S.Xq!d1/3uf&`1F-QP#osj$,;1l;4%E%59E6:K"W&O91,:gP4$#Z"92f%f7UU"JG>p^f1hN.f +iVN'>jm9dtc,@Z4lh'N8im6uCaiDKBb0[i9aiaV(s2t_fajECXE,ff5DuO_VDu"B+DKAB(?9i2D_[<8S!]P*PEh8M6TQqS`5^$Ca2Z*@ +aNMfPbfIg'`Au#^c-sAHfGP)5R*WXbccjJMa25mAIM*/^bJq]J`l6$Bbf[rFbfn)Ga2G]P;+jbn +cM$u,qYC*hrr7K~> +rr3E)q>C9mqZ$NDf`2!Nqu7fmVp%n^ep\X0ZWVQ>[p%n^go^VVFo)AJ2me$5IjeQ:M<_B0cSQg,[G%+Gb"T\W($5?EW +Fa/=qeF`e>rr2p"kj8*Drr<#t"T85k?XN5A.T8`+4+WZ]/T[5APaQV^Df%UlQ$5N10p\H!P+7f( +QBm\@7k[!jq#CeGoRGrVuirs7uE`qu?]ns8VrqHn-7UpAY$jrr)lq +s8;o,-6Q%Yr;Q`qrVlirrr3,sq#(0krr3,Xm.TN1qu?WoJ,~> +!W2iort#)+r;P6@ZL[ehs8Mupr;HTo*;]\P*YfS-+;l:RB!h=,s7ZKmr9u'X(a+\8qYg?lrr*?+ +rr)lns7Mn^U8k'*rr3,trr;utrVl`plM`=6rr2iiBdPoL?8a^(P)Z)sR?BIC6ZJ?G2em7gKohXa +P("[7OG>`)1e)KRE#rR`q#:6ls8Duqho3OQf)GXHqYL-irr<#V_SjF3`W!_U^V.V'`3qt(Ui +s8W,qrr4YMqsC1hFM#H2_o'XAccjDF^rFOQ=:u/_'cd_l'MFeFdF5tVd*pAV)%mHsf?))4`W*sW +a:QA1`6H?C[p*BF?t=i)_90gtaSj*aaND`Nb0%fF`q%2)b08)PaMu410[p:1lm`VSWK2" +1h]0oPDD26E&NH5R$3_`-&dtB2e=j:Eq+,^Df&i@d`fbOa2cHSb.GC!^tR$3`XKi.bgYCrfC&8( +p@.MLmoK8RjipPnQ!'VAUD,7')^cRL2*=2p69n(,'`]9i-8$c'4#JfX853#a>Z+F#ATVWf\qt=6 +W17e*kPji1Z*_Np`l5OUr:omBcg99*a2l9Cd(R08b5THibf[rKcpq/WDf9K2rc&!XEHD"ss)0Jc +5t*b^P*%55PE:omEC+JV3Ju4'h=\tEp^Wb*Lc-"'*`W+!g_SsO3gLq`@9Z4oebKTt+(!4A=SJ2JdcH+5Q`l,m?bf[oDb07m) +`=9_[=@l"a[IX%cqYC*hrr7K~> +rr3'!q>:-j!rCX6q#;N:r;QKkplm9T+!hjN+rqsR.>6@RqYC0$,9IpQhY[3Ls8)`orrE&trt.MinauYWqtp0[m-soNn+62EmBKrUH$G7/1oH^$MK)]0!!W?%$j[_LCj1&S +O4 +!rW&srr<#t%KH7GUrW3.rr;urr;?NmruD";qN<0G(*!r,)]'S9,_4GDq"Ocp*?,kAhYdBNs8;j- +rVZTnq<=3?W2-NNp](*irr2rrrqucsrr;Bbs8OSJrVZ.44\Ag<0Jo&ZRZir%O?7,JB9&-1DJ`0V +OHu)oLa8+KM)RRn8T+EErc.dR*-#n/:&4bcs8W&tqqoB1`Rb%drVQNks8N&uiPYZ6>J\7t]>h\% +_nC_AT7:p8P,s@+f@SF+f[/!gbeqN>aK9+,fA,0-d*0b\c-"&A^:V.fZEB1"]YhV!Y"#[d9"i*Y +P)c#pNK/pV\])S&_8,aDs8DrrrVG[Gs8Dp&s8Drsoj_6HEVseUEW:"XEW'i0Ec"cR0/nKMP:)'N +PEqG->&[n=Od'BMBfqK:Q]dGsPEqDuM)7:Ln,34arr;urkPkM](&e(-rVZ]fc`aIWWNE(np\k-h +s8;ios8W$(s8DusqnX3k-ft=,(&n75rVuc:*ucL"qu6Wqrr<#trr)iqs8W'.s8DGfU7.dip&4pj +r;Zcqs*t~> +s8P(UrVuorqtoH8?Au\BaMYp%il!aV_,<&"V6U!n)8i6Su*@ilq1,q3u(OZDkLTa2Ym,lMpnRjNm2EaiDKBb0[i9aiaV(#gLK4bfrXSD/]Dn4*,C[ +D/jQ6DfKc8nU;NP+@u*R?NktP_qCc/^Vefa2Q'>a8O'Z +b3m>Pb/hTBbg";M_oTBL@oZDt=^,1>^rX^Ibf[rE`l?*>a1f.%e>j5s%_g3.bK7]Aa2?!CZP*i\ +dEBbU_nsF8bf[oDb0%`C`Q6*,@o#?jRH4#:qY:$grr7K~> +#5eE"s8;]lrr32Xi;@H#7SBFE)A?FE;MCEckr$q>L?ms8Doni5NXQe,0+Cs%WLmr:oiuKm.TZH$=OU +H$+FcMDVQ=3/VE:%N@)aiqr9;p%\7Urr)NXj)OVanFZMSr;?Nfm-4'3nE0H6\l4f>I!1.$;.un? +;I^CEqu@-0)-L]mFF0"so`+mhrr3)am.gSZrt,20rVubr9lkArFE)8CDfTjsE\_QWE-?>F($grtP;/s5`J< +p@7Y"s8Voos8W)tr;$6hs"sTPqu?C<,9`]Xs82WlrVuonr2Cbf+o2'8s8MurrVQNms8Mopr;6Kn +s7YR=le_[Aqt^0fs*t~> +"98AtrVca$rqN.\g\q!Krr2rr,l[iDqu?Biq2-CA(EFD1)]BM3+!+CYo^Gm+)'W#Pr;6Nhs8W&s +&HDb+rVQWgYFhYhX2Of0s8;Wjrr;Bb;uQarrr<#oqe.i8?q2H(PEVE"Od;/l6=3hmOI'*NCLfbm +QB[c"7$*ss1,0Oapf`e(<:!bg">M_o0O.;UjRSf[A0mbf\&Ob.t^*Z+@N7;np/i^V%'u +IB7I>\;lc6O-,WhNek6b`5TU0p&G'jrr2lmk4&ELrXf#-rVu_q96"leEGf] +!rr9!rr3<$o^gmJ=e?bKc]"uS1anNjVb3R,Gc,IQ@bL#$C-6-)R*g)YMR[0,'PEA4?=]:HM>$#NO +6]dY!R$'k!SVf0Y>#&mTH#[tQC2Ig+DK9]=FEVbID,*:=bL"AQa3N5X\\,Gaf$"'6B#i$9dG31' +nFQ8@mJ$2=k3M6[>cjl$cf!EUST?5f4X_jF76`t&7S?TW!%oWH/h]%B4?Gbr9ikV.;d+-d;9[e[ +kjdbiJ?OEriO-5,^<=gB^p`S,qXE@fm+9A"aMuBL]tVV2rl>\pc,n8VMDf$`F*`%PG%tf2E;jT5 +G&_YACf!qm/VfCOKp7pkNg)A +#5J/ss8Milrr3/]k5YJ[r:p74r;Z]hs3Yd6,9@pM*ZZFF+s\6[J05mU+M[aPrV-?grr2p'r;ZfK +o()5(nG`IFr_rals8;oks7;-o3a+p.Q][T$Q'mu+P=&hm6&;"Z3-T=%P)u;sP)tujPq>$rEHl5BD01&<459Z4p\t3ks81`p`5L4(rVulr?N9otoYQB/F`i(QG&_MSI"b=;Ui9gl +70`qq)a\N/p$VVOp@eF]p$_@3a7B!!qtL!cr:oaInFH)DkM8n(J9#RTKS#78SXh&b&c`1;"TSN) +(0PKoF*W_oo`+mhrr3)am.gSXs$utas7KW.FEVVDD/sW9E-6,+F`VhGEcYJY:+hWpQ]ml&PEgJ^ +E)p#(Q]4:E?UL!@R#mDlOd_T!PCl+S8"fJRs8)cns8VEa"TSJsq#:9m$iBu&s6f+Co_7_6mf!1c +rXo20qtpBmrVccps7VWu,TupWrr3W.rqQNmAgJTMq>C6lrr)ipq>C6l&cDY+q>L9lrnHW!kl:\[ +q>:-hs*t~> +s8W,r!<2ut#QEk^W9+$Ws8DrqruV1;s82NicYY!N)B'S5(E=84*ucPT*?,n9]D)@)q#:B0+iEs7QWj&=i\+ot&s8EW/rr<#trr)irrr;YP)BKgio`"jurVu]nqd:Kb-2.68qYpWpqu-Hm#lXMG +T:qmNf_k^J"9/?"r."~> +s8Mus#l=/]`b&ST`5hl"s2b/Ys2Z;0bK/529G%pK'GqT%*#0A0&fPQn#Rh!3dF-"Hai2:!aqDe8 +`m2cM_ld9N=Bo:$_8a[=a5P*>b/_H:b/;f[G82`.5;8IhQ'[`&QC!b$@V.l\RXI,:ai_rbdbF9_nabu< +o'?#3gP(Z`GaRLF]YCYMIOS)S-U'm^5"8.=;dTM>0J>%40g.ij6q'[G=]o<9Fu[S"lKS$@l.&_4 +Y[F-/\AZ,+`lGs+l1ai>i6UcAaiDKBb0[i9aiaV(:Wgr&aOJEu;/LQ&H?+%@C2S*+<,QZ$D/3og +8l.-tOd)#sPEM/V6>ok(PEq.mB4"#hPaIPoOcc)uP*:M`/3/I+ai;*>`lQ0>aNVlL`p^t`bf\)J +`l6!?_n1M.;+X_c=*M6raj0n.r5^q@`Q5p=a`7Ut$Ja%Wc,@90^X_+9'+Y`-ccF&@^r+46b08#N +`l?!=bf@G_=%l7qYjqbjqu6Wlqu;0~> +$i9l&s8Mons8VEEmJd+cqt^45r;HWps8;`kl_70!*$ZXG*[)XF+s.jL+Y*-[s8VloqYpNps8E6& +ps\p)mc+0E!;tgT7Jd#]rVQWp]hCIj<^(hkPE_GuOHPip=]9-$N0'Bi1il9#R#mc)R$=,&1dY,C +DK9`6G$-qQDfTf@EH?,@FDc@tp&FmfrsJ`)qr#N5`7=eas8N!Os82T`_MC-_o'b.do)JaXrr2Znp\=^](%CO?Lm*%)H$4O_LM0tbD^$#(!!``- +!"098EHlSNN7@M"rVlfr"6f+Hrql^bq#15q8p#&kFDYo7EG]Z:7l!S=G]%n#0k;tmOd;8uR@9IF + +s8N,tqu-O!qoP_Bnc&Rdrr)itr;HWo)>j7+l_.&r)'Bt9)&sS2*?#h:)^Y%Ks8Voos8Dp/s8N#o +rqt*,X.u]#o)J^err(gT;Z6Xorqufr\Oe\\<^1nnP`h>pNf]Eh=&E]qMN3sa12fWlQB7Q'R$=,& +1dFo;C2e*-F]^_MD/jK;E,ff9Eb]bjpAb!fs8W&sqr#H3`7=hbrr)orrVloT_#D5U^r=11cb?rl +.H'cd'bV`5BR3];K,`gtBd"ccaAK`PfR*]!f1^Nk +!<2or%K#b[UhFVM`5fp@b/h[%`\tr_cHsn^e&d4t#mLtT%20Qp&f25o&do5ud*B_Iai29Bbf\#H +`m2`J_N@])='o^H`lcEE`8J^Cb/(s3ce4mL.o&i"G`e;UQ]dDlPEo`e]YtTb/_WHceQt'nFQ6Vmd]f; +r8uYI>-4K.i4-G1^Vm[F5=\!o2a0Gn8PD]M$tPE_?"R?grT?UUQQP(5K2>#gZIQXF9kPF.Z#QBtB-/$RLC_8FC8aMu6@b0%fFn&Q9gb0%`D +`Pp'?^RSe28lAJq;mO9_b09k-rQ#2ba2Z'BcH,tr0O3M_aj%rOe(9in%gcCgc,doB`5]pAb08#N +`l?!u4.!P3i5Gr;Zfoqu;0~> +!W2lqrsJc's8Ua+p](9mrV?HmruM%6s8W#srV6*9I4H*\+U?m"l8)- +m-+*@rrW0!rSd`Ss7H?krVQKF.6_!7;O'p^p@RtLqY^9fs6Im-RXoa(Cj(,MLP%4>U-1%E!!*E* +!"0-0EI)hUNR[V#rVlfr"6f+Hrr2phrqufos82LLEHuMCBN9"iG].J27YsQtH#c/dGq+uHQ(",( +P&*I)3JNBUPYPJ(9jEsPO\ohJQ]dT$QB6>R2+[9;rr)lrs8V?_s82lrrr3#uqu6U"kN_[/p@cu7 +s!7I +s8W,t!<2ut#PYBr`qfT5s8DroruV+7s8Mops7uE=Hn#jU*#]V8*u5q;)M@\^rr;uqs8;lrs8W$, +qtd@`X/Du>r;HTjs8V'W;ZHLks8Mokf-WRa;,`gDQ'[MI=-/Z1@8:Z'G*J2RD*N/!MjBWkPa.Mt +.o\btEGone-U:IHDf0i3?s%AjEH=7Oo`+sfrVulsqr#H2`7=hbrr)orrVloT_#D5U`50C3_nF6% +OfW8hRYZfaO-#EXJ8Wo_cd'_T`Pfa6]t@(^dEpFkccaGM_SEgq]X+S2[^jGt]u7e&a1"d9XBp=8 +Lm+-_PEM!@`50@,_"Ia-rVlfpqW@;IrVf:bqu?WpqXugbF_u#-;fQ`"DJ`oOL-guEDE_f[.[6Hf +R$WnrC-Z\rKSPbS9NlC0>a:b?;/(fPP*DB#OE`oD8+Q][rr;uss8W)t!<;Ne!<<&ts8Dus$iftn +\ZDp3XK@lHo`"k8rr)fps8N#ts8Dios7ppV.MI7*q=smao7nS7'-k!^r;Q`rrr*'#rqu]nrr3?( +s8;]b\>#RdW:p2i"9/?#rI=~> +qu7-(oA5.4K=o+Aai_cIaSj+8aiqiIcd9q`d*9h<>n-iI&.oKn*"s;)#A2B6bfI`>`lQBJb/hTB +bf[i:Cfk%J@>)A5bPoQ@aDoYFa2Z*?e%QVR<(p&POI)>qD-2pcP[[F+5BiBWPAWX/1lR`cP*D5s +P:KX!5B:^_3u^(MF*)>E@9ciNF)>kLR)mUsa3)HAcIL"G^::f*bJq]Ia2uKMgsXsHoCMYDo(2M9 +k&$0ZFh>T&]>qk.9"gsD1KZIo5"&"=:.\&SC:K(._85;uYbgISEFED_Ca:b?;/(fPP*DB#OE``61<@_Z`6?C&`rF0^aN!\i)9U1GaMu6@ +a3)'#CfO5&/a([:02SsqYU9ls82ZmJ,~> +!W;rqrri9"s3fNurrN#sq>MK9qu6Wqr;QZnqtKjbp:"`_,oRm@+s@aTl21M[rVcclrW)iprsR3A +nEf07s8;oqrr(gT;uQ^ms8Muc1I"u=.?0LZR@'+@0U7oeG=QIZ7ZNk&R9i]d@?Zq[_=>Z5TVDe`/Hs82irr;Z`oqr#N5`7=eas8N!ls82T`_Mdro_%hDnFuk[s8;)H@uPqQE-Z5@DJX_Y24'1D//8$_ +$j@#4D0UAVO4]q>UEo"9/5qr;?R(p#,3%g]. +rr<#ts8NB(n"6H3rVufqrVl`p)Z0O6s82cns8Mljs7a!9,U+!D&02`(.H^I+rr)otqu6Wq%K?>) +kE`'DWikI]q>L3is5O#UrVl`ps8;=?4&o-+Nfoj!QB,0$PEV,O7;?7!N0]`q>Y\%$PE_2qOd21b +?%abM@l[*E87uITCiF/o;K$>hB2JL*qu?Wls8N&qi5NUPec#IGrW)oqrrLulrkhsW^V@\#^m/-& +OC+o9I>3]@P)ti^D5+toc-")F`5T[0_0;hY"`GJ\KQVrI% +P)YfjOH.)p_SX('p&G'jrr2lmk4&ELr^Qhcs8N#tr.IpfE)jQ[@;KdnEHO;2JQP?S4-+\EOd)/l +P*;(iCc.*8R[K3gG@s6fNg5kb9q7K4Q'ISuOu=j;oDe^eqYpKos8W)us7-'gs8)^Qs8;onqTu@J +WNW1n[.=4rs8Muqrr2rtrVuoqqu?KR,odjK7$X+*@2U+,*[+/Fqu-Norr2lqrr;osrr2p+rqcTk +ps>V)S=]'GrqucrrdX~> +qYpuqcZ!Wg^r4.6b0%fHrPgh<`Q6BMbK\5P`P]aGc]q07&IK0[)Arkq_pHfR`Pfg^dK_n9GqFDc,pPWEY>MjBj$O=kck6@"TVPql((Q'7JuPa%=f,n\>F_SsO;`l5p:b/hTBn]2ZhaND`L +aMu6D`lu91LK[YM<)d"@[DU/2bf\*,a>CiUaiMTPd_lP#%i7-TIXY3+&e>?X/]u>[aMuQ +bfn5N`l6$=ahtQD:esu#ch$u3rrW/qrI=~> +s82lrrr3-#s8Ua-rr3#rs7uWsrVucerVlg5qYpNnp\=RVjc)n[.iKT^Pl:UXrVccrqYgg!qu?]` +fCSIqjo#,Zr;,CO7K*5cqZ$Sd-QQk[0:S)aOcl/C0T;3[O#:rq0pn#iPF"jG5C/QbP*hMp/T$_; +C-c3em7V&=F*MS'XKY$.GX9@Dq>L0hs8W$'qr#H3`7=eas8N!3s82T`_M>al&,lP< +!XB0.CNb&TO4:'N6Y^O<;cec_FEV_B6Mn/l4D6X5O`-GIQ^O>&2/5Hs +PFIJpIRIgo1Qe2fBI-68PF%MtP*qGA4unJrrVuoqs8VEas8;osrVcitrr)j)jR)X6n`nR&s7uKg +rr3r:r;?Qmrr<#rr;XDN-6sf`-Qj][,Tn +rVm9)s8W#OT0s[jGZYT-PdaOOo,+RrVlisrr2lqrr2p* +r;FR$X/;o1q"X[arVtmV;Z6Upqu?\e,o^DS/tA&aOcYr=/rGdSNAGNi0:%TaOd/F?4aN?`P*hMp +/SgM5Bg#a_mRq&6D09YpX04g,GX'4Cqu-Elrr;utr8>T4`7=hbrr)orrVloT_#D5U]u.J!`3;k* +W(EM!GC+afM3a?fN.OREbfn/J`59C-^::aSa3)lXc-4DS_nERg\ZJfE]#DV*`5oj>_J=6pNM^6+ +Kp7sgOcPL:`PTI*_"Ia-rVlfpqW@;IrVlcq8c&>^j?dKp;,C8I??(%)C-ha)<]O\HMihqAPEhK& +M_f$3DNU?DP'fT-G;GAONbB_1Q'7Q!PEM>r@QQQ+r;HZqr;Q]qs8N#ss760hs8W&srr+X.gG)]]h<+4'ucr;Q`ps8E&trr)j-rqcTl +qW4E@T:ad6rVuosrr7K~> +rVuop%KGq*BQ^Vu`l#m?b/h[&`]1r\`P0I@c-+#Db/_QGd*BUL1_L`8'cD&?ccF/Ga2lEIc-4DQ +`l?0?_h:rs=^?6]`6-EN`PfdUaBd!3a2,mKHOp]q1+JWOOHYlr@PD(q<:R$*b+><[@t +SW]A*N\,(25A*)UE6^7CIX?HZ:o:?ZBPoT.d)j>FcH+&Fc.'hE^::f*bJq]Ia2uKMgsXsHrps@j +nb2b2>bnE&`id%raMu9E_7?e"!*Vrc;-$[q:.n,M@K8YJ3]]Vt6:4II?XQuC36U@VoC)8HrVu_d +UO/Z>Dh=[o_nWgm]'T1`o&J'_f?)(S`lcZA^<+OsaABq!`l>g7d)@VDC0"D>M.(^VE+:KWR6`T> +3g,\DOcbrsRZ'(;6#VpTMN`HUAp?+oS;q8/8X5L+P`q8uO^L'oA'2j7bK.]B`Q$!?`l5sga;`.? +b08#LaMuHGb0%8f@TH6!<*E8-^<+UDbf]n*(rjP;c-OSXgmS +"9/5qrr)j%pYP-6s82irq>LEnqYpL!qYpEjrqcEfrsnW"`eS5B[f?4(s8Dutq>1'sr;$Bmf]2Jj +kkY2W!r`#miVldUr:pVD&%Q^=,+Q<$"^Q'RFgDfn]YQ'.MtMEQ)>L7=EiR[02,O@<&9 +9\B2P?Z^=,AVE`FJm`O[kkb>Zqu$KorVcWO`Pf^Fr;HZprYbb5q"2FYH$+7SF`;MOAo">\66-42 +!s&B+r;])21$eB#o^qkOq=sUFm_4qXnFQJOp[e(Mo'u/*7#-;-I=$$UCfD2X%jj$$SK&m^!!!',% +oI1eH%(b&o`+mhrr3)am.gSYs$c_Ys8W)uoKI;(:M=BZ7riWl?=Wm'AnWkZQ^a#&Q'%Ao5&XY#Q +^*r.P?q7,@6p*=P[R$OQ'@]"QB[YsO?,Cqo`+pgrr;<`s8;os!<2uq!rr8srr3Apjn&$9n_=*Dp +\Facs8W!5s8Moqs82cgpU_[m)'pIM*[;sM/]7V_qYgd!s8W)rr;6 +r;R!#rVF7$_>*j*rVlotqu6U"qYpEks82Tjs8W'1nG^=XA7i.Hq>^Kns8Voorr)iqrr3B(n=ubX +Uo`ANpA"Xcs5O#Us8;]mq":LM-Wi!ZQC!r+Pa#-+C6Om@1i7;*>Eb/7OGGu>1PD0ZO-l/pR#XO2 +6:oi,@ptSU9D+/;YE*QoOoO_bh2jBelR$E_sN]_/] +9U1g-RZUiRCgTJlOHa0C8!T=,P*V>tOcVI[U%\Ncr;Zcqs8W)trr;Qgs8N0!r;Q]q(&e%,s8)B* +X/r5&XdIZ8s8W)rr;HWnrtYG2s82cfosc(]&g&,5(E4D2.Dc&YqYgKnrVlcq%fQ8%rr)GlS=lLe +q#16lrVqB~> +rr3Q.qYL3ZO^j-[`5Ta9b0%fHrPgh9_T^?J`lc<>`koU9da?Flb1i_*921]'bKe;OaN)3@bg"AU +aMu6@_R?GC$^rXgKcGdZ?ilHPpaM?$:a+l8g<@WiiQ^O>0PuTeZPa.4cDKJKUP`_;pM*,l: +Kpn3eR?`u(O$lc,33pq#:O%5-@Xgd6JQcS3aj85R_o9^:`QcoR\A#Pde]YtTb/_WHceQt'nFQ8E +oCMG.V0]1sMlOG2dEKVV_T0R&O9B,n8l&;\:d.ZP=]T&f!)#XD69mUq85`Vs=*R!Qna?,=lLb,M +_7-kLBWeXJ]t:rFp[dt9cg99*a2l9Cd(R08b5TIYahY^6bfJ;\-"C+RBk_T[FE;@s8(c-[ +?8"L3RuEYsOHkkiDH]c#Pa@l&>uYZK6'ICp@7EbPPaR]#Pa.Ak1FR[jcH+)N`l5p:aN2?>`q%24 +`lQ +"98;rr;HX$j5KD*s7u]ns8)^#rVuflrVuoqqu-O-r;$?hs7lHjq"aperVZ]ms82imrWrGts8UL6 +md009rr`5rr;>OQ7K*5cr;QQa0j7p9Q^!PtPEqJ78kG)4Q:kJ$A4MiPP*qVt1N?3%PaRZ#QB[Y7 +->%MqqM86iGB?_T=)(<5E's3qr;QWns8W$'qV]?1_q"\`s8N!6s82T`_M7L`?!>-o"S6I0PrW!?3 +&lNUiG'o;!o`+mhrr3)am.gSZs%31hs8D]lpA%a$B3ASY>=3IUF&JG$pPET-B9A=EPa7`$4^i4f +O-H#tQ'O7AF\-22P`m[t?'CJBOd)2sRuL*.qu$Eis82irm/I"^s8Ni5r;6Elrr2fps8D!JnauA9 +j8])Tr;HX#r;6Hmr;Q`prr3N)_(?rZ,:"N]-&:a\q>^KlrWrK&s8Mroqt^0grs&K&oBYo+f`(mR +q>:*hrdX~> +r;R-&r:m+_c27MU9kp\Fj_p\aper;Z]pqu?ZprVlfrrs\o* +iKC1+s8N&ri5W^Sec#IGrW)oqs'X^!_o'F0a2Pj,7&6YP +BlnuJG^F[\M3+*eMcdI2bK7fA^::Y_[BR&9^X: +rr3Q.q"O^NEaP!I`l#p:aNDTFrPfnta2Gj8bK@iFc-=GVaMlBFeB,tgcdC4dai;K@bJjJ)(Adq?P*qH"Q&d\> +:1TQUOHu/qPZ/l3@E?T%6uINu:IJ&q86K@NcHjML`666A`66ZM\A#Pde]YtTb/_WHceQt'nFQ2; +o'thj:oLL-QF"cG`QcNCb/M=j]9k9`=@u:_9i+bj?!q;[!*rc#69[Ip9N,"s>\@'hmJ#`+oChdc +]#MRgK9NBcK;Z<"^qRSQp[dn7cg99*a2l9Cd(R08b5TIYa3)TD^a(;Ecc(]GgO]K +>TdgIO-PfkR$'R>D)[K=Q^*f#1MLr%AsS[F/Q5r=PFRc"Q^!u!7l/iEai2QG`l5p:aN2?>`q%22 +`lQYbg"ASaMu<@`Q?9Ic,n)Jc-W1"&J5?X&etjh_9BsCaiOD& +(!">8b08#L`l5p=ai;3)H;mU7F4^'_rrN)qJ,~> +s8E&pqu-O#iSOV7p](9ls3goHrseGUmd0B6s8N&ur;$6eiVldUrVZ]nr/iX64)gLROIMAqRq>&H +NKf`d2fNdmNL#otQBuJKEAW`DP*qT#RVF-MZhjF+7riir7tP;`4)AY,p](6ls8W#srVcTN`P]UD +r;HZpra,X%q"2FZH$+1QE-H_.I@XOm'*8.6!<`K-!!!*$(eV@+mdTc;p](-gnEGp*459H.r;69_ +m-a0,U1TL9G^Xga<>boE!!!rr2p"kj8*Drr;lps85$F9m&'k +ASY7cH#GP:p\=#;07o@QRZ$5E'Pa@MqS=!k[G$RY,OdLVU1Q7QdOI),sR$*_[4]M=UqYgH\ +rr2iqrtbV3qu$EmqY^UBn#QFJts5iY6h>[EWrqcQlrdX~> +!<)lr$N9hbTV(uWqZ$Tnqu6Bjs8E#snc&Leq>UBn$i@T*VPgN:rVu`irr)lUr_`Rks8W%Z/lXcI +PaIK#OcYuA68XU`P__27E%m37Q'IT!Cc62eNL#ZmPEVAI,ZCuGqRK%2E,S*n@UM-.BMJ:%s8Drs +qZ$QprSY]6`7=hbrr)orrVnM,_8F1/a2#a/EJ^H1CNFcKI!^*_I!LI/P)!_Kbf@lJ_7dIc\$E8X +>uAbfb/4.o#J7je]nC=7^Abtob--AS=l_>q#:3kJ,~> +&c;V.rV6*[dq2^p`l$$@`5p+"aSfcaSj*ZaNFJ*'["M:`PoT?=B\j: +J\&hFdEftS_oC]WGg4=Jbf\=R*)/>0Q'RK%PEVGH6T'gdQ&.D;EAp+>;=LJ`Pfd?a2Z'@d`/f3]Xu_;`lcHEai_rbdbO?`na>N(eolb@J!@(I +^qRP%a3)38_mkk!>?`%792/&V>Zb6bBMiM^?lRYXt3ER"$tLN0K`lQ]d]&P*L2D1sX.[bfn)G`Q$!?`l5sgaT'7"b08)P`l?!C +b0.`:VI`do:/+_^ZbXi0bK@oGa8X*YbV72Z_nj@:g +s8N,qqu6U%qr?c;s8)]orr:IHrr3>_l1=E)s8W#ss8N#piVk8(s82cno;"'B17jbqS!K>-Q'=9s +DO$QT?rV)[6&q@sPa.Fs:hhqPrf\^tPERF_jo>2W6Z$pf<(1+eAoLA9r;6Kms8N&urVcTN`P]UB +r;HZprY#8.q"2FZH$+7JKmS/2Srr2p"kj8*Drr;lps84_DFBNL* +GZK$2EEd)Oqu?1O@?I%EOdDJA +!<2rs$N'VNUT4"erVulqqu6Bjs8E#srVlBfq#1d'rr2GaSu8Wij8T)UqYgBmir1A's8;lroV=*> +/tA,hR?j,)PEIjkCm1-L?;bZS5E(qkP*;"k:1uMHrfJOoOc_%Wj8])X6>17V;*nJX@Vn]0rVZ]o +rqu`prr;rT`l,gHrVc`p!<)lr!T(Zl_csdu]rY,,Ue#HKH[L0dG^"=SJ:ioBDM,sOb/2*5Z*psG +J6I#1:X$Sn_T0I,]"bY5GIbW.a1n[/H%1-aI=,pSA#tDdIufVRLpY"?_8F+^s8W&srr)]UnGi4] +2?!&d=DW)%;K?bp=D%F0s78NaO-u;sR$q8YC,(L.NLQ5nN^72k6ue3RO&&k:Q]dH!OID:1Pn/^> +T`=ujrqcWns8W)ts8VZhrr<#s!<2ut!rN#rrr3;q`j)SGWi2?:q#:3ls8N#ss8N#rrsSf)rqc<\ +q"":\qYC-jr;Q]qrVlcq!W2Zjrs.GXS=QA(q#:3kJ,~> +&cDV-s8)EV]ObN`aiM]G`Q64#aS$G&Cm +dEThQ_oCZV-dKWKbK>V_:bA6&Od_Z(R$m7q$!gJ^MBQ`5]pA`l-'K`jidr]@G*Eb0">:ai_rbdbO?`n`KH!]hk6"A?!;[^q77q +_nj()]XjP25$:KN78?fY>?GcJ"hL\<(rIfb07uLa2Q*?`l?0FaMl!1_oL-Vg!n?rbgb(`_oBg>aND`LaMu3:`Q$'Eb/hTA`l?6D +_7uXN8P +s8W,rrr32hiUHmIrVQToe,K@H#Li58n_=*Dr;Q]trquZPr_raprVZWic7_#.Pa@YtQ'IH%M`tN- +Q][8o4D8XoMNX9iQ(3nZ6XEWUPb4,'Q\S8hq>0j]<`aS[G@!#Pb;!!O&ZOJ"QV)@6BX9lFuqJ;r(Ns8Drrrr_KOq#:9mq>NSXTQ3D"AS>s[ +5Y_4Wp[lX!SW]A*P*TTOF>0)NR%'8)P%%@,@nMfNP&3R(1lIWdP$=-;PEV8s6g+1As8)`pkPkMZ +!<2ut(&@b)s8W&Xo^25Gk264=rVQTos8MumrrUBn"TJ>rqu6Tp#lF;p +s5rV4iUm-L"8i,urdX~> +!<2rs#l=83VS)R#s8D]kqu?Nlo)JC^%K5:PUo(9!q>UEmr;HWos5O#UqZ$Qns8("m1P:jUP`M#l +Ngkkf?8\"/Mj6>8D)d?5QB[Z)NHINl:R%$5P*D;f8_O">q>!rfDKKH4CMQ=&n,N=crr;lps8N&s +i5W^Rf)>RHrW)oqs'X^"_o'@/]!u43X'][aH$k!dH[0maH$=:]Mgfuo`l?0:`jiUbRpTuPGAp3e +ah>F*[_T>WIs8<>]th:1Fa/%SI9k_o9L/p&G'jrr2lmk4&EEr^d"fTQ*7q +@:X.K4A#MOq=i*(S<0&$Od0BKE\s8)cp +rr<#trr<#hrr2rsrr +s8Dut$iTYXS7H]ObK\5M`qd^Q`rF-Zb5]Q_`r*gO`rF-Xb5KBn`P8*H?qQB.Pn4^U+5OGoJeB5T_dOd;5sS;qbZ>u6fMSs#>)Jj@2s`lQ[u8nD^> +C1Uj6.*KrR_8=78bJqKDd`/f3]Xu_;`lcHEai_rbdbO?`oCV1uFHNbNS%d+ha2,R.^qme'\@>&' +Cd;Q)9Me5X9j(_6@$@apHn8r=?=-f,EbGi%9`l5p +s8W,srr3&Yg&1jL!r;lrdf0:H%e&-Co]t`@s8Mros8W#piVldUrr<#ns5#:VOHH!$P!"kqPF4aO +:gTu4k0Ye)$jI%L0MosVm.L5J +nEZ9bNd5SB$3C>2!!ubKs8Drrrr_KOq#:9mq>N\XoD6Fe<('E? +p%eLaqYQmrNKfTnQ(0mH:1fNMPF7Yq9j_[T3KfbpO?I/\99Gd/Hm3ErPa%N%?E4#%s8Vops69O^ +quH`prtY;(qYpNpi9p(,qLp$qu6WqqtpBhq>C9mr;?Tirr2p.r;6Eks8W&r +pAb0Zl0[Zurr3*"s8W(K~> +!<2rs#lO>#User8s82Qiqu?]qoD\pls8N&jrX&N!aI/j"X31D>rr*#urr<#Wrr;rss#^)WhC9t7 +O-lAu3ffYjQU#1Y>`bA;N&>Hg2ia#qNfofl6s<\hO,oKmP*TLHs8VomTQE=p=\(YH\bQ.'%fQG, +qu?ZqrSbc7`7Fncrr)orrVmAa_8F1-]=XG;UQJMgG'a+6s*77bGBe7ZH#n#H_oBI7\%95d6Z@?p +GB%_4]#_Us]XthgG_N]EbI2J6IXcNhJTlQjH=KsTP#?%JMiY'U`5o^0p&G'jrr2lmk4&ECr^-8R +`/[_^8r<*4q>^?jT4X%FOHu-#3FkfoN006hP)N%>Bl5kkQBdOpAR.rkSWeFFD46]RQ]t^Rs82ir +q>UBns8Muts760fs82d.s8N&urVc)fZ*1C6URq&Qrr<#trW)usrr)lsr;Q`rq[!2uqYgHorVccp +rqucurr)fprr3W.rr)lrs7sF(T:`F]rVuosrr7K~> +s8Drs$M<#)@#2D;ccX>Kq8iHQs2afO"3AL'`r4!Xb596k`Ogh(?X%#k\AQJ6c-",I`o5!Gb/_TF +aP+QO-'+.UR#a=lR?Eq'BMVorRZrdiDJ_@oOe[r"RZU$C=](9BPF7Ss=,>PTaOGlM-p:$W.lajgj`EN,OVU;bI&aMl!1]Y;)%`P%^R4D@Mb +7o_uTAqVq#\\PkNIlVY"Al;E$=_:$Ug[Y=6[(XZ+_TL0@`4`=*C:pKdPdSb/hTnaSs1"b08)P`l6!@b0A&I^o:aE9hS2U=LH,jaMu3< +aNOP'1WIDO_7dY'bKJ#Lb/1s3`l>p7b/h`JaMu3<_o'I9bfn5L`Pfp@bf.W9HrNg?HJ.odrVlhI~> +s8N<%r;Q`rgsZ3%!ri)sdJj1G"P)`,o]#lM#6+Mss8W)riVl4Er;Q`hrO=s`Padf"HS0N.OI9TK +D(hKCPaQJXFC[CrNg5ouR?BsP3KoksR#RPq:%nG`q==F]O*d\crV?Kis8W)trs\l+rVcTL`59F@ +r;HZprXo2-q"2FZH$+@^P:qia.juJCquH`urr>Cg!Ws94OR;r9qs3S9]f%e_!!`K5&1fcCjm2C' +lfG9UM/u-%#mgS3#6=f4#R(qe-\/'j2A?H/=)re0H]?PIs8Drrrr_KOq#:9mq>NSVs8Moiq"FFU +rr;ljqs$P1T95V0P[7-t5F%\$Q'db.?upESI@$+U2f3P:;jNN/M_n=qPF7T#D2n8hq#(-kli%%e +rqlTjrVm?*q"ad`s8VKJn+6>CgA_-PqZ$TirW`E#r;Zfpr;Q^"rVQNls8Vims8W,s!<2ut$2OW" +s8VcQmH`d.s*t~> +s8N#t$N0.fVWR^Qqtg?ko)AIbn,E=drr*K,oqnL[VPrh[rVlisrr)iriVl+Bqu?]jrjY!^P*qAp +H7X3'NgF0CCFu';P*^&PEagtlNg5osQ]==B23F5kR#RMm9_\Mcqt'^]N-CrTqXsj`rVm?+s82iq +s8Cor`5L7*rVlcrrVcb(hSI+I_S*`VS?5M$I&??(!KH^0\O2f3P:;jNN/M_n=qPF7SsC5hoe +q#(0krr<#drW3&urr2utrr)fq%0$/%p;=#;Yct'pg%bOGqu6Kms8Dut!WDrqrrW2trVlirrqcZp +r;uuus8N!/r;Z`or6h=2T;^uOs8W)ss*t~> +&,Z>)s8V`2E*o0JaNi#P`U_(M`r,\rl4uZ%EcSs@U<;G?_k<4@lT^5Q'Rf)O$RA9P*hQ&NL,>[f@&*kbLbEa>(aiL +dauae`4s=5d)sDJaj@u9^V%2/bJq]IB#i$9ceQt(nFQ2:l!ga-Asg3IaiDE>^q7.j^s:3ETOgr7 +<(0SV=(uSBQ*7g;[_/5`7;$=;;c$G$?>%p_j1i4E_8=F4\\GSYYF9X$Z#tr&\[_%onEoDdm+9A" +aMuBL]tVV2rlG)]s2[aNaN2WQe'udpeC)Ugf$)Ilc7Xd +s8W,t"T8<"g"$*%s8E#udJj1G%*S24o&9WIs8Moms8V!Us8PI`rr;YFB98CCQBto9G*SM^QrI4+ +0U//eRS-n-DDmoKQB7?!HU;:+NLc)rOdgr;qt0pgr;HZnrr;ons8;onrr;oqrsJZ%ptis+_peP^ +s8N!0s82T`_MEJ[H%B1-T5#l"&eFmIrsV='$OHn?-:4Kks7H6Me=Ar_+qY@n$iphU1JWn`jQ>gm +a\%:N,U=BP*uQ(?*%<-_,r.bAUR38J'cKJaG'8OueF`e>rr2p"kj8*Drr;fn/cYP>p](*ir;ZWk +s82^^Ng#isP`D"`DEUBqp](9[rr +s8EK+rr;iGUp'FfrVHEkrUKmcs6]gas8N!-qrsBEV5UKms8N#ts8MuRr_`^ns8VeHAWN%`_8F1-\:AY(Kj&A7Gl;pdH:iR1FEr4;OhJrMaM#-A94i6dI4Z&+'gKnbM?N/E:IKSkA;J4QQ/6#D(+WQ;omah[TLs8DrrrVG[Gs8)`ls"+!Bq>^Bm +qu?HfrquX\N0BTpPDbVYD)mZ9OdVJn:0DFO=&>0GQ&IS=9P0RhQO8IL:6Uj/OckN%qYpKsp\t0l +m/@"`rr3-#rVZWnrVuor$N/baYH>%0S[8"grr3-#rVc`prr;lpr;QlqrVulrrrN&srVulrs8Nr7 +r;Q`rrr<#ss82ZjjJ8? +rql`q$M(9-AurYbc-FPPn]:^K!li=&q9&`Yqo\r[rPnlY&^&"j:Ld[=B"#Fpbf\#H`lcH^aD/i6 +`QcV@c,mrHd)V:;Ds0.[(s5`Y-FdT5?tWU9[UPj`kog@bL+MNa2#a/\"?[$W`bReZIAF2oC1/of?)(S +`lcZA^<+OpaT'76`Q#p@`5p$Nc.("fa2uWVh(O87P*_Q!QnE)3OH#ElQAn[DDJrWSQB[\o2/c0# +Q2[*bL0.37P*qGuJN;$&c-O;I`Q$!Abf]Isrl-&&bfn5K_o9X>cHXJL]9QSq77g9WGe_8=`5BR: +c-4?0`W4*ZbR_e5^r+17be_3:aNMfN`lS+u)T^(B`Pp!Dbf[rE`l?'FbJqGp>>@k!Z0:`Qrr7K~> +s8W,u"T/5jgY_o.dJaRSo%3R,n+6SXr;6BhrVtgT;ZH^os7U;^P+Ru*PZgLMPEM8nRQ,/(6Bn(( +P;R8p@m,j:Ss,Y0A56*5O-l6"PF#IWr;$'as7H?kq>^Kms8Moqs8N#ts82cihSd:Ke,91Err-7( +qtTg#Lj=,jMC5$Y.=-&B?sR#B?!LQ:>@:W7<,,FVmd]r(b@k=OHuEk=AnGphCj_=d;Sq>Yo$g-q +H"h#4Bm+6$CN"*1Dea6;;JDk9:j$M:A8Za;NR[V#rVlfr"6f+Hrr2rnrW)ips#TlMs8Vrqs8Dgr +O-Z*#OdM=uBKLU.R[98)A5@5c?9*n)Q@LZ0=A4sFP*:l";bE= +%fQD*s8Vo4U;-['rV?Ejrr;Ths8Vcks8Voor;Zfr#PuW5W2?Q4qY^Bnrr;rUr_i^prr2rlD1Rh? +P*V;76qi`)Q&V.hCMuJ$S<&dgD/*QDNg-&rQ]b`K;IGQQQC!Ys=gA#+qZ$Tfs8Mcms82iqrVulp +qu-Qos8Lut`5L7*rVlcrrVcb(hSI+I_72k7TLuH%[^`fT[C*HQ\?WTT]",+TZ,OJo[(0mh]t_@q +]tMA2_SX."LJb1[[C*&)]=kqp`k0@2^;e1._8!Y$_L$^1Fb@NMT";YX]#"(>s8DrrrVG[Gs8;lm +rrDurs$$8Ws8Vlns8DgpNK]WqOdD.nAib:(R$Ei!@SLf[>W7J!P^Y<,=A4sFP*:l";bE= +%f-#!s8VVP>B[Ec`m)rSrl4oXprWf^`l?*@b0'\,s2tA_s2G&]rQGAdaN2C#`>$>5b/9*:@UtYc,7fI^;7e1cHXJMaj@u7^V%2/bJq]IB#i$9ceQt(nFPkj:U$["bi7UF +m.C&Fo'G]-oC;>;a>mO2:/k;=7rm>Kp%S=Sp\jRRld(2=G][_1CHBr4p\+@Iqt]p`qsa7Wq"!0j +I^=m(j6OeRnb:kcm+9A"aMuBL]tVV2rQ,#Ys2@RI`Po^;c-*uDbK7`Eb0/C#J;fSTPF\+1B/Y%$ +R?j&%@nq#_>r[\%Q%(K.=A4sFP*:l";bE= +`luZMa2>2m;+b#akO&!Bs*t~> +!<)os"TJGhhrt"XQ'dVu:hFQD?B:88PaddrD)mB5S!02+PXP$9s8)Wmq>UEjr;Zcms8Vrqs8Dur +rVGBh_o'purVlisrET9rotlH/H%Sn6TjD2`FEM\IF)uJFEH-)EDfg)Q;;CN\[ +q>:-hqu?Torr)\p?BpkEQ'IPo2.&_;Pa%H#JNmpc;bEIAQs_[eD`cR +q>^Ens6Tabrr`8rq#(-k(B44,p](9js8VNRn*K]Df`2!HpA=miq#1Bqr;$9gs8W#srrW2us8)^# +r;6Els8Mrrs8Mp&q#CBms6K(:j5Tt9J,~> +&H)S+rr;i(VTf)7s82fns8W)ts8V?_s8VrprVm9)rVc`lVl$;fX5`sQs8W)urSdbUrD`gprqU8U +Q]RT!P#>19PED5uNJ'^Ejs8DuriQ&mUf)GUHrVc`orsml%_ns3/Kr]-J^qRq1`W!^n_o9U3`PKR3\5gDa`OUCuT=VJK +]t_M+^r=:2rkC+j=D">2ZX007a2#X7]>_k-_nX.(aMYj09VeR\[Dp&#bItg0p&G'jrr2ilk4&EL +rqQKnqYpLXrr;rsrVZJl?':M?Pa.Gk10m53P*2#pIm%L[;+R%9Qs +N)9EOq>^Emrr;?a!<)os"9/8rr;Q^+rr;uqs7jL>Z)t1.PO&#Crso&,r;Q]qs8N#rrVuflrVZ]q +r;ZfsrVZ]qrZ(n9s8W&rrr;usrVuoqqY^9g[A9Ch])2O,r;6JD~> +&GZ/"s8VD6=bFK%aNW&QaN"5#s2P)[q9&`YrQ>)_rlPSh`l?*Bbg"AUaN"4u!65#Z$Gg7X>@(j3 +]>r(8rl"u\bfn5haT'4ra2?'G:N)DYS!T43:,J2uR?rqf3c7,TPa@Dq:M"BB?B:56OdM.fCcI33 +S!')"L+^`nbJ1p=`66ND^r4=4`PoX:bf\&Jc-jP=]Xk`+bfIlF`Q?9Mgsk3OmGE>IX`pDoj6l:) +qYU-aoCGiMp@7hB_BWr.A8":mUuC\6nFlYPmHsB:o'>#88PFGKIS[*,qXO4Nkk=lFoBc2Js6ngh +;6I61ali'fs6J[ilIX.saN2TP]thh4`lQ0>`W!kK`P]O1^;S(4`Q5s<`Q$)\98f$uOHl)p3F4t: +PEV5tJ3I^_;G!7=QX;IbD` +aN_oG_6nDf9L_f`;R=3X`59L9bKS,K`lQ +!W;inrr_BBrVHHl!;tjUrr36$qu$Hnrr)Zkrt#,/e+*.tg].Bm3WRQC=&+Q>Aoq:Q_04R$EtdC%qB%rr2rto_o0prVGBi`5Bpo +r;Q^HqY:'ho=fm(H@nATQ8jqSF`D;;EclPJEcH5BI"$s5?Iul97;[d0IXucfrHS?f/UD>\I!gcf +6<0FtB9IggG]n4NF*;hSG]mtKG^O(8Vg(BeA9N69Iu)_JrVuiqrs%]To)AUbs7-(Kq>^?b8s#L1 +R$F#'3+"b1Q'@W#P +&-)V-rV,WTUu_4Ks8Dors8N#qs7Hhk*_3eD+P';/_^:_D#_Sa:.^qde*^W==-OD:MIC50==`4Nt%q#:3k +qYg +&-)S+qt8icbQ>r.aSs3ZaSa1$aMu6Dc-=JR`Q,pA^[gc-"&D_oD\uilFL,`Pfa@aN@5$M3jU'P#YC:I$U%_P`f]QECN`kQ'H;:Aoq!FPF%Dt +PA*9e9TGO*Q^!VQ;:VDgn+$&Do^hV?mHXH5hQAYe@l$!%e)]`^rq$urmHa**p$D>bf]:n"Nng,`lA#! +'?\D;`O_O>:K("^:PQX+aN2?A`V[^Zb08#NaSs0]aNDTFr6#&\r5ScXs2P)["3S^+`r='Zb5]Nj +^4]K_:hI]3qu-QpJ,~> +!VuTkrsJ_cjo>;Xqu-Qpr8R_Trs/Gsr;Zfrr;$9j&G=`Ip#b<7rqcZprr2rtrqtaS48o3ZrVuk1 +H^U+cO-s-?S@b)R?a))O\s:#q>UBns7H9tr;HKM +`Pf[AnGi=`s!dmGp%$(RI=aD;SP4?hLiRM&&FFA\%eai_>$3'u&kMu@9s8Vlar\jfL +s.WqeP*2&qQ$c"rUELrr2p* +iTT\&p$LQ7s7cEgrr:IHs8N2[jlG=srrE%K~> +&c_k0r:o'AVssT`rql]ps8N#ps7uZorVulps8)`prVum:rr)irs8MupqYL0HR\Qg^anl&9r;HZq +rr)irir24Crr;uprqpARR?X)"QX*-_@$ln@P*D8'>%hJ.PE))i5@eS3@#L;4Pa+pK/s_E_Q'R\s +:Wre7s8W)srVlfrrr2iq%0$2(qr#N6`nL4fp@eIb.JE`$_8NidRA4#S]u\+1a2c*7_Sa=3`4s:* +\9<%%@[agG^W+@._8=(g_uIRQ_\9u*_8aTUFC[s*]Y_b&_8=.._SH/f&\c?#`O8d2WEsPY^;%h3 +a7fK2rri)npZ:Z]nQ@24u<0iu9Q]jmHCJJ/uPEpDM +CN3$ZQ^F&%P)r4H94^Hns8UsT&H2Il\[&<=WMZN^rr<#rrVu'[qu?6d$iA\U +U7nC>q>U?krdX~> +s8No6q!GUo<3XHiccF2J`lQ6@`l5j7`lQ=%bl5cbblZ&/`rimZ!Q'Y'HBkBGkO.2(k@VSnL +M3F!`P=f(2P_k]kQBmFoXO4l%_oU'HbfIfFb/hU%`?3+@b1,+aZF@6TdFc@N`6?ENbhLq2nC2$9 +Tkh$sp?qqKD=R5hnaGl0kkXZ#Jmpc*KY-+*q>0UQo^hP;lKdj/o^hV?n*d-!@SB;Cli6hYq"+%I +o^h_Ko(_M^Xe$8Ng#Y_ +P`h,N5tt@GRuint6saS$>EFu3FYd`M9P'QXQ'7Am87kM'OH5fmQ?u!Eaiq`K`l5p:rlX3@&&uJc +@T$*$8PWa,aNVfH`obAA`WF-!`q%1Y^R&,$;I6Hgr;HZqJ,~> +!W2forsJ/Oli7"_q>C9mrSmhUs8Vm!r;Zfrqtg9irt*uBo(;,>s8;`ns8N#ts8MrTr\sfTs82ir +FENk1Q'.MO9klJCSs>S*PE\7JDEUdfOID@nCi:nkSX>h,O??6:S!KA(Q^DEDo`+F[$2jbui5NXP +c2[eBs!da8qYKs"H$b':Rts^mIW]^KEcubVH?aLNGBJ(QHiPES>(D*NFEMeMrHA0_3-KLlI!BUC +0-MoQK33A9E-$/EF*2_PG'8([E-c\WDFg7Q/pVS_F`W2apAP$fs8N&am.^/Ls8VWg2Z3RL=GWN2 +RZX,'85_Up\t3err:dQrr3Gnjm2^9 +o$7:8qY^l/_U;rrE%K~> +s8NN,r;4X2ZMOV$rVZ]qrr2fpp&=mhq#:^D6F-ViPP*ToVB/5@7PEV/lP!!Mr4&)9+R$'FEDCh'CQ^Ehp4%rSAQ'RW!QXu*JrVuiq +!<;urrr4/@r;QWP`l,jGs8N&sqYgO.5&c1F^VRk* +_o':h_>qLQ`"^,*_8F40a-VU;WPOh8]u%e,`5]dp_]?M5]ue7/RUW:e=gbiWa1f4\s8;oks8)c\ +o)JI^rVm!!rVc`os$?Y_rVlisrVlUnL7+-jOe%\-;a$G.NLl2e3,W=tQBRDd6#U[3DO-ELP*_\Y +4)7T(P`qB!PB_*Brr;`mrr2rthYn)bqtA(9WirJ(POJMNs8DlqjSf/ZnGWgnm])nRUriT8rVcbH~> +rr3`.m%dcm\]W4@b/q]CaN2B@`Poj:aSO'ZbQ>r.`r +!W;rrrsIZ?p&G'iqYpNor8R_Ts8Vm!rr<#tqtg9irt*H +s8N?'r;*pu_YF*/rrL=(r8bo27A6\XVnKgba2Z!4rkB5b_o9@1`6#!;Kn?)>`lQ-7]u7e* +_SlGm'Z@l*^:qaYM2@.la26!C^raO5`lA"r?Gj^o`PKR8]3C>fBpHBJ`l#des8Vurq>0sEo_\[g +rVQWprr)fprr<#trr)fps8W&tmmNM,OHu>pKK;)DOdD8tQ9o(p4cktnLam.W?Ug6FQCF%tPX];1 +8!0+)rf[\&NVibQrr;uss8UsT&,lA%fsRrbXfIiErVlisrR(TPr:dFfU7esns8N#tJ,~> +rr32tk)EYf\]4Wm"Ne[$`lS(t!6G)\rlG,^!Q`:[`=Ku0b08)PaN2B?`lu]Pbf9Y$'$8>;`kQ+l +>?kd>^WXsG`l#^8rlX6A5/tX\aj&#OG$g5oTqIWs2JZ5uMOBWoR[&dcG]["dO-YlV4_n;'M3tN`Q63ErlG&\!6G/ZHcaXc`jECg[aN%4`kp!Ia3N5`e'qF"ZsUZ+kO\B; +n*ff:oCMMBnFlAAcEaRQcLUAhlg+*=p@RtFmHa0.oCqtPrPl%DZde@(me-&DlfdEjlKdd'p$VD; +oC:USQ(W6%lLaGud-TT5_Tg0EbHAe)b/q]C`Q$'Fbo4gI`Q$!Cc-=DN`Q-KO/W5gVR@8q\1c'WE +R/W="5[e7dNg,Z\-tmF&7$Eq&S!&er7V?s9Od;AuPE]Emcd'MPbJqN?`lcH]a:?2&MHa"U:JjoZ +`lcEFa7.1Ib36nP_6mlM;-8D3qu6VG~> +&,cG+s8UX&r;Zfrr;?QnrSmhVrs&Juq>^Kor;QR%r;Q`rcL(,fmJm4_rVlfurr<#Ur\slUr;Z`i +]NLM`R$*_u5&tL$N0]QiQ][G4<-!"L=co#7G"$=2KpS-lQ]a=78O9dJ*/0s8<0!i5NXP +ht-jICB"2-rV,]oMd^FqD,6%AF_u,?H@LEmH?jaXG%tkc$jm7R5&>(RFEr+VF`V\JF)uABEHQ5; +1(j]p$or!?F)Q8HH?j[VG'.kLH\-H^C/Z!!0WpftJTGj_OjNUqs7ZBjs6/_?s8MrrnbtQKo>Odp +Q(!r"Rm9SIPa[`&NG)((4+`rdLcBKs +s8E9%qsgY]d.[D9rWE3"s8VflpAb$h!rr9!rr<#srVmK/s8W#\R&Hm^^&.g-s8Doqs5*bTs#9rS +s82N"=-\u:P*M1kDJV:iP`ColO-!@>E,\6IO-PoO6uG&=QBmf%OZ-Q9PaIZ*OH`Gcq#:9mpAY*l +3r]0Xi5W[PhspaFrVlisrr<#\]SCR#H>U@9`l#d4_8!_!^qmn*a2#p,Ll[X\W6)fd_oTd8_Sj@1 +rP^\2_S=*ZN09TnZ,ac%^r=.,_o9U4_o0I-_Rm_.^Q!h +&cM_/p"4RuLUY7Fbfn5L`5]gpaSs?]a9'B#`W!mV`W*pXb5TU0b/hTA`Q$'Ebf[rE`Q$$B`l5/e +@pN>Z[(j]-b/VE>`lQlkO]GD#ECO&lPEBoQCcI$2 +P`q>m2-WM4PEDN#O$0eoaMYp7aN2NFaNDZLbf\#H`Pp*P`jWUl_oU6FaNDuV_T1N\^m'8KMhTsQ +nac;@n*ff:oCFU)oDJ4TgT7p%alNKjjm)C0q=aFMn*TN2nacJMrm/3f_T:j3mI'<3mcrrskjAB> +Dsm2]o(qa\TNnt"M`m;f(6&CbqQ]mh" +78oA;OI1o:956G9R$!([EGn`7PDc$!Mk-,*=DL3"Q'7K!Q]jn-cHO;QaMu3=aNDZH`o4uL`P8'T + +s8N6$s8U[%rVm$!qtpEniVjYnrqZBis8Mroqtp6gs8:U@mHFYF +PEM#mR$MeYCMQ1oR[oS.R[./1F_WsfPadb&A8!raR$=&&GWS$OP+.Z'Q"ZBXnG`Id2Z)FO`5U(& +rr;ooqtg9gkJE66V5c51JTYsJEd2t]I=-p@rVuirs7-(Kr;Le_Pa@l+ +P(YhRMisWnO+p);;Il8YP$V.1EE7g[SWT"uQZb`:D)RN@R?<_uQpp-5qu?Qls8UmRrVm)algOT? +l-oY3rr(:Es8N5nkORutrVllsJ,~> +s8NK*r8aZOi;*BPs8Drqs7lTds82fprrE&ts8W&orsnqNR&Hscc2@S\m#Bg.EARu`l&PZ]PYBK1I)RZBgGB/bm1*irr4A+[8!Hq7_HFM`PKI/^q[Y"_8=(,`lYNDRZU0WkPtS[rVlisp&6WE +rr)h:G*/&XQ'-e]2iNohO,eo^BMi9.O-*^IF)Y-5Q(=&!Pa?P\Ec!^sPaR[5PR0_=r;6NkrVlfr +rVcfsiVjAfqt7b/WNNA"U%nWdr;Zf]rr<#arX/MNU7IaJlMpn`s*t~> +&cMb0oYPNXR_-S^c-+5La2Z-uaSa0caMu6=_o'I5rP]#]aND`Nb0%a'`?*%Abfn5L`Q#p?ai;,] +>\%,KK=8M7cH=5I`Q$!Ab2LEk`Q?*E`mV[ZLQ7[kSaNDZH`o4uMb.t3! +<_?.b;HUWRa2Z +s8N6$s8Ug)r;Qlsqu6WSrY#81q>:3lrqu`kqtL*ikNVO&kPkJ^r;Q]qrr2rtiVkk7s8Duqs7K$L +R?Q'Rf'8MkjZPa%N#N)Td#=*L0J@=<`QE.;nVH?sj]G'.tLCJ5i25u!Q5PaInD:g-SZR?W1^EGIFtR?a/#Ss5:,?>rAINh);qS!8t0q>C*hqu6WMrr2p%nEBH6 +o^^H0rr`5tqY\hA$ig2(jn&$(oDejirdX~> +%K?D,r77aJo)/Les8N#rs7lTds82fprrE&ts8W#nrt>.2SYiBmi;9qu6Kms8DuRDMO^!L:P:@^sBa7_86,frkfDdZ&4g.R#m9!`PT=*b/_97 +`5KRm_E,TTbFaiTP*_2fZFe/m]"c5!^r+(+_8*n)^W4:K^AVR$2tZE,%4pR$rAINh);qS!8h* +q>U6jqu?Zps8Doss5Eqds82]>Z)t+0X.&JTs8;lrmJct^mJ[=fjeA04UY5VGJ,~> +'`7k/nZ6PEZ+n5ubKS)J`PojEk)3Q'%5u5?`2@3g>\dPqR;B +G`e/QQ'4ZlHB4/QR[8dpe'H%M^W"4:b/hTFbg"AQ`PTL6dDWQ2^:`%IfZhabbeh3Sb@H@$I\GTe +o^i+OoBY`2nalABo_7IX^:(bf]@6WKlgFH>n,MqVmh,*^q>ARS^;J"/_s$CTkN240rpqB,q"XRQ +mHaWD]YqIhVHp@*:sA(Xdc]Z?ce") +s8N6!s7tO%r;Qluqtp?NrY#81qtpEnrqu`kr:^-ig[t%$kl1SarVlisrVlisiVkk8qYgHmrqToW +OdM5nR['.;EcFNfQ'[c$R?B!"U)%>Fp11KnP?9nb;lt@RrINj7WHNs8DKe3Vf"UPa7c$ +R#s9dL6\!fQ'*t@16RocPr`]"3K9)eQ'@PtOA9&">!S19PEDDuQ%`]Bs8Diprr<#Prrs8NAdo_%D4s8W)tJ,~> +s8N&q#0EdJr;6Ejrr<#ts8Voop&Fmfrr2utrr<#rr;RK1s7MeQVQ@>urVuiqrVc`qrr2lpiVkh: +rVlioqt=qQ]IA5:3'T/OdqST6t\QCS!9/&F?E-[Q'7JuO\Nsrr;Zfr +s8W#rs8O/>s8Lus_nh":nb2bXs8N&uqo2L5Th;u<]YqY$_86)frko>e[Z$3+QC*MkVS^0g`kfIh +`&trS_8=.0TotS+PDYEW[)BYp_83k#_8F1,^qde(`6=1%O,]3RDeu,.CqRNqq>U9jEFh[!8`ogH +qYgFR$!_t2E?PYP`h5m1Mee.P`_1jC2Z(jNgGupQ'7;)>] +'Dq_)m$VL-^V7S)bg+GO_SsO9b5KNdb/hTBpr*ssaBODmNt300Jj +P*9oI8!&guR[TC*YLU_3^Ve(8bf7ZFrldCD`PTL6dDE?.^iW2ue^E!m`P'IQ\43] +rVlrdgZeY9"8r∨$?lr=&W&s8Dipr;Z`qrVlijrXeu)s8W)rqu-6cs8UdJoB#TCs8W&ts8W'# +r;Q`riVmoqrr)`os7_=fQB@N!PF7SE3cT1'J=;alP*_Gu>#fQ1FH`#U?;`e:Q'7`'O#f"\NgZ8u +P^mB>s8Vupqu?Qgs8;oos8W)us7cQL_SIa,G)&?Up&G!crqU&aThBHWG^+LZG^+CTG]dkBE+VcX +$3^J0!"oW$CN=W@F`qnLFE_qVG\_.J'E%oX!=0&tD0C,HF`hkKEHHGMIX#s4'`\=9"9o8[,E/<` +H\n!4p\'VKE-#u".Q[8#qYpNprV?KlqZ$QprVlcps7uO^PaR`!R?EUe2342mR$;>V1-hs8Dutg\q3Nrr32[oC2GIi8O\8s7lZmo)91"rVuls +s8Drsr;QQmrVuogrr;m&s60+Lki;^Crr7K~> +%0$2)qm`BDq#13jrr2iqrr2rr!<2ur$i^2*qu?Torr;uts82fors/Q'rr)fqs8Mus#k*qMWN48; +rVuips8E-#rr)fRr\slVr;Q]gLM`<=QB[T#O^g@hE'&N9PF.GsPEK$HDaST/Q'>QO3.mHYS!8pn +0U@`eQ]RA[B_VK*#Q4W!q>^Bmqu$JtNfB"&`l,a3_8=+-`Q#j2_njU2Q&:cfOc>6O +:n"OiV7XS3s7VOXEcc+s-opkoq>UEo7K3/`rqcZos8N&ts8Vlj7?X%$OdM8l1H(>_QBm\J7o`]Q +PF,QMCJ&E(R?Ei&Nfct +-iNr@kCd3%]tqV+aN_rK_o9X:b08,TbfRoD`6H9?bf7fEai29BaSsC/b/hTA_o9^>bf\#H`Pp!@ +aM4iV@:E]$[_Kr)ai_cIaMulM'P_]u@e%]Xk1WUSV&+f#H\4g3Q8"Ame%F,h(,^b/q]C_9Bm:aiMWD`l5s>b2,%2PE;$" +QB?+?k:.]ZD_TU$Cn]26_a2u?AaMl0>`5][;`Q60la:$#/[U;j-?&[b;s8RT~> +rVlrXh"9/2qr;$?krs\hurr)fps7ZKhr;HNerWN/us8W)tr!<#ps8(RIn)F$>rrE&ts8W)u +r;ZfUrr;orrrEgW/ZPb+2'3GWUeR$UEgs7kG!LOk51LO;nqrr3o6_IK['4c"E,G^4RZG'.kDFa.M49G7X3 +!Wi9#"9pbsEI%P+$?U<6FEhtOD)`.0r;\SR"pd8'EcQ5AF)ZA@F)cGSE`3eX"9AKbi"0q4%c +O.4nkDG>(fEGp,>8QkogrqZQn7K*/aq#:9mrVlfns0H*rQBdc&Q'!LpQ'IK#Ou[)5NguAo3-8;% +NL-#qRZ`t.@r?*ENKo]mQB[Z#PZkHkr;Q]qrVuoPrW)iprs%]Sn+HD;g&D$Oq>gHarWrQ'rVuio +s7uTlrr`2ns8DNf$iB\unauJ7i;`iVs*t~> +%/p2'po1(;q>UBlrVl`ps8N#r!<2ut%/oo!rVc`qpAb$grVQNlrVm$"s8Muqqu7?-fp&5/XOd7G +s8DurrVlfrs8MuUrque2r;3QuQ'IQ!Pa%Gu>#8pI7rXcYQ'.Z%O#Lcl/XMZcQ7uZ?NL5]mOub=N +RZN\sQAnVsq"Xjgqu$Kor;Zfor;-Hnq#C3I.>E8&I#*5Gq>UBnr4#h+P@2,A`507)_8F41^rFO4 +bIEN1N_P\$P`q3.`l#^2_ns7*`kK=)`Q+[5OHGipPE(W^[)^/(`59F+ai)98_TBd.P)PWhNf'*a +Lj)drQ<^i6p[r>tEGof2FD= +'E7t*iG`(f^r+.1aNVlJ_o9X:b5TX(bfRrG_nF.7bKA5Ja25d8`QHEKb/hTA`Q$!uaqDe8`Q60B +a1[d8?!h-+]>DY.ao9EcaMu6@b2:9Y`Q$-Je;d._PEhW'P*;29;/0i:EL2rVPF[u#3,3=]Q'%5o +/mV,.QA_&j3%olNP*_Z-M*Jr'_844/aNMiFa32HA_8XI0daQ,RJp_rgJo`p&bJhWPY$%QcFPuBO +o_A4Rn*B9$oD8%Uk.AUPrkVUM_SP.-p%%P@p@[kElgaQ@qpE$c\\5o!`5T^YoBki3oChYJn+#f6 +nEo>R]Z.n)\&6.lQX?GLEm2JdhGlgTC2@L$ANN**d*9VTaN;B( +-W6(iNgZ"f@Ps(3P);,:<`"[ +rVm8[h>@6Orr<#tr;6EfrXAZ%s8W&ts7lWcs8W#rs7cNjrt#,,qtL*ijl?(%ir8uVrr2lr"TJ;r +s8V'W!WDins'Yd)g..EqOI2;rRZWk#C3=,RPEVB#N0Tlh3cJ).O-l/]3AH;ZQCO.I085pVR$Wr' +C5;Q`q#(0es7ZHjp](9mr;-Hhni:l@LkL\5Lk>C#s7c4lVl)\'H?aUYH$FK2EXHr5D/DiT"onW( +"TAB5">s_0H?XOREcuPREcPkO'*S14('+OsAoVg3FEVePD/Xc>BOVta"98E)rW!lI.PuL@PF@Js;d!`nOIM]' +P*_M$A8Q +s8EE'n"?T=r;ZfqrVlfps8W)urVuj*qu6WqrVuolrq$0irVliprr)isrr2lrrr2p,rr)])RA?ab +kPtJ[rVulq!ri6"hu3ZVr;Q_>qZ#5;PaIQ!P`V;oPkR>3b?<+1fRPC>JFL7=Ht +P$fnrS;ru&OdKm^Bks7cQfs8Mfns8Mrms8)=HG'esoMLUM4nbiF_o1bUK;67RN_na((_o9X6 +a2Pd9[#'m,OcGNdP*;!-aMYnd_8=+,`50O/_S`"(MiX-gP*(fcO1!'K`Po^2^W=:4cG@02Q&1W` +MjBZlNJiR1PGDcM[Ij/O89/lnD/aQ7>tG"irr;utpAY*lr]C/Zs8DccAUou.QC!i%N\s1cOdqPG +5W"XlN0R:CAiPj?R?Nc!QU,/!EAr??QB[Z#Pa.Q"7Gn(DrVuZl!<;'Xrr3B'pX?IPY-+jpn+ln\ +s7?6hrsAT&r;HZqr;ZKfrr2upo)A[h$2qf7R[C&Arr;tJ~> +-ia)7dUZX[`5]g9`luZH`Poj_j +]QR1W?YQ=P_oB[:b08)PaN!,YFN_YC`luTV\i,V8OI_f%Q]RFrBlmoNP*2/tMj0Zd3GhZ$N0TNQ +2D0ZNPF7M=/;'IQR[]M,?ua]F_84=2beD'7^WFaA`l?KUdj&UOLOY,1LND(kb/_q$T;l/:jQl:, +p@e.Ilg!s4p&F6c^;e73_8-r'_SP.+oC22>q"O@Hq=+.Re%N9'^;%Pa`-95bp$M&3o(25`lZ]Tb0@fBaN;N>n]2'U^4BB^;JX2 +rVm&Xh>dNPr;Q]ur;6BhqYpNp%Jou$pAFsjr;ZcorVccjrr<#urr2p,qtg?mf';kokl:\]rr2lr +!ri)orr;$XE;]_0s8N&ps7JgAR?Eo%P+%o+P>#.sBL%iGR\#q.PZ_"%0U%`bQ!I$XN09Nj:-Fi* +QC=#!Q^C#0p\=dfr;Z`qrr;oirr<#qj?@^9LP(A4IXPumh"UTAHDkseI!9aYH$FIQEH-&@EH+V]% +KZP/(Bad>!!Y>oEdDtTF`VYKFEqLQ$jQk:"T/66#!-C;EclSOG^FFJDeNW#":5&/#lXfF"ooKU/ +"r4iVV&dSFDQ#:HuX%AF_ASCGGaXDSPa7W"Q'IItp%nXbs8;lrh#7l_qY^?ms5o^C6.s8MupnbrRdrVlg(q +tg0fs8W#sr:g6^rX8Z"s8V +#6+T!ihWLErr3*!r;HWns8W)urVulsrsel'rq6-frql`pr;Q]qqu6Tp(B4:2rr;uss8N&spS4CY +X1@p'rr2lqrquots8V$Vs8P=]s8W)nrpiC9R$*c"OI;Q$O\/_kAj2E?R%0M&P#kUt09VN^P[$gT +Mij__*^qmn+ +rl,,[^r]\4s&r8\aW15&kCZCisK+CiEoDq"Xmbrr;lqrr)iqs8P1Ys1V6nP`qDuPE_>b8!TR+ +O??$IQ'[_a4)7!4R$EktT8lNJCihmdR>I5oQBmc#Q'+B)r;Z`qr;Z`mrW)uXrr2p*r:oEZYHG(3 +QJ;66rr;Th!rr2trr3?%q>'sgs8;oqq#Bpas8NE(d@d##U>c(MrI=~> +.0'/4_.6iZ`lQ6?`QHEE`PojaN4A's2b2Z*6?:FaMu6=aiDNB +]4"cC@<8ir`Q6!G$=AifaOHGWf +>"D;CO-G\u3g>hoR['&%Ot>2.`5op:ai2NDai(p9dF-I]-=h=PJqel2J7'P,bL28_W/6Dem-F-4 +p@e+HmI'N>s6@25`5g!<_nc8c-/&%`nF#i?p@@kJs8('N^;.S'^qRY(`5Up2mHX*.n`fH+me?Hj +pqOPd]YDM%_SjX)XjU:VX]2slZnQ<6G]S7PEcGhm)qNHea2Q9=`l6!;`5]j?et56jP*D9!Q'@J` +7?a.#OZc-GPEh;Y3GCR,QBRGlSW$0FCihmdR>I5oQBmc#Q&RQPc,[Z>aNVg+a90Z/aN!2[&BW,= +^7AD%8kMuUS\rLf`Q%Mj&B;T*aj&#ObKJ8`dE9VM^Wc5h$HKoB=Ai.+Z0V>fJ,~> +$3'u)r86E3rqZHjrr`2rqu$1-`q#CBkrV?Err;Q`rr;?Qo%/Tr&s4$K)lgOlQ +qu-No"TJH#qtpBmj8NHarV?Kls8Dro;2CR)Pa.N$P`V8q20EYJ4IMA!P+mr(4Dn2*O-uGr1cL;Z +QBcQWR?6#CdhG^4[iFa%\0B+k:G$31&1 +r;^+0&mS7NT5%ok96>/pEc5`>F`_tLC,l(grVuoqrr)iqqZ$Tms*ARNPa7T!P`hB!P*2&pE^;mN +QB@V3>[U*gQ'dW%N_EVsBg%Q>S!B;)QBmc#PDr3.qu$Hnqu6WNrW<#or;Q^#hsU40mb[I4rrE#f +rX\u,s7lQmqu?BKo_eahq#0d_#Q4K!s5`G3i;N\+~> +#64Preu#VErr3&ur;HQns8E#srr*K+rVufor6=s1s7?$cs8;lrqYh--rqu]os8DrsrVuiaRAZsa +`Vf`8#QF]#rr)irs5X(rr2fmpeHX2QBRPsQBI8oO>CrkB0)B@Q&qYsQTK%a>`P2>N&*AK +Q^*eVPF%>uPEM>rQ?.EKs7lWor;HHes7lWop\=;IJ;9#7K6iB/J:M3]qXd%MThDc2rkncQ!Q2kT +`GiW1Zu^hYNK]QfO,oEdO/U(8_SO+-_o0@0`1;1(M2m[YN/Nd_P)Z`d`59F,^r3h+`k9KDG^bg9 +OHPN`PE2#i[sED!F*?h=C2Is1D.Rg0EHQ)548JdOs8W&srVlfns8VrqG\`\2QBd]#PaRpKsCoDARfq=4IarsAY\Un+3QfDY^IJ,~> +.0'&+Z"%7Q`QH?B`QH?E`l5s=b0A/QaMGd<`m*&8e^E0j`luWD`Q%\os2l5#`l?!?`lZ3+='8O1 +ID3eFai23@bg"AO`o"j_bJqK=bKA&Z4b/ZZR@9G.PE2&m1j!GF4.).rOeI`$3GVPsN0]ff0f4ZN +PEKpMRZa#"OI;5nB4K?<^WF[=ahtp<^Wb$Ie^Z`l4KO/3?eLd`'@*n-&lg=<9o^hP? +o()hR[DBetaMu39^V.4fddmD*Ie!(&p%/(ZfXJK1`5TX-]Y_V)_;k+PlL"*2nDj'0p&Dn?^Ws^4 +`P'+)^;I>/P)Q\kG2kYlC34W&n=?OH>rsQBdc%%$[$@LcO,5`P]X7bf]q+"3ep-`o4uMa32cGX'\Rl +9N+i=_T]s8`q.7_`l,j;`6?f\f$:eGc-FSL`ULqT^Rne0 +$2ji'p>#$7s7lEhrr`2rqu$rH9QI-P*M/t=@-)P +Q^!o"QBmc"QC!huP=5*@s7uTms8=#=o`+YhL5C_4J;8l0Jqo/84k>.0VeKI`Is$!ZG'3b)"F+`e% +1E(6'*SI +Rt5!/tSq%F'Eg1G\hVRE,fltQ'R`#Q'7))o)AOdrqcWoh#7BQqYU9l$K^[Jn*TGss8W)snbs'tr +;ZcrpTn`g0V8.;rr<#hrWrH!s8V6CkiDR=s*t~> +#64\qbbMiErr3&ur;HQnr;Q`r%JKi$s7%T^89+Y/s82cos82d.s8Mons8W)ss8N&qgmP1BXO@%F +s8W$%rr)irs8MuVr\4BOs8W)urr)RpK9VddQ'ISsSsGS.6p_SUEoo)9$srqu/aSY)Y"r;QVE~> +.KB8'U0qrI`luZG`QH?E`l5s=b08)P`lbm4b1=iJ"Xcsnf$)+Nb/VHsaT'C#aMu3=aiDQBU/tJs +?AuV=bKRuEb08,S`l6iVs2eZd_TL-Id7J\GQ^=81Q'7i,PaXsCG%!h&P*^uoO`rm-0TVBWQ;p.K +O-GcmO-uE!OHPlpO,GaBccj2GaO8>V`Pp0@g=AT7JUr#nL5:J5KS4b,`,'4cJtUiclKdj/rq-6\ +>P\'f[_oko`Q#m:_S>kRZ2>Q<^i.6Od;2jGXH7j0NX^-P*VAuQBmc#PD)BQcc!f?`m2`JaND`L`l6oX&BDr=`NsAT +7nloaB#2a/^rGue&B;Z+air>]NCjH`G0e@UbfB7p$H9iaB2_]/O5p'9J,~> +$2ac&kM>q5s7cC*g&-)P,r;#"g+s8Q;o_SUfqYC*jr;Q^.qt^9lrql]pqr-i)kl:\V +q#13l"TJH#q>:0kj8K/Yqu6Qms&o,'K9_ddQ^*i%PEV/mRo<"#?p^9KR@9M5;,0euPa[bp4ue^m +PEVK%R?Nu(Od;H#9%C"PG(G:&N/31:KS,,?M0D9WYFRe5H?jXVrc8R_5A!!33+"9&9/"#OV1H?a[YF)>_M$iBu+!sJi+!&G*RDKTu?FEi"XEFfjh#64r.!!rZ+!!N?-% +:=Hl@%DL-FEr+OE,ff:G'%kEF`;Rcs7cNm5Pb3 +KonpR?a1l4_]'nH'+PXQ'7JuQBd]#P`/N4s8)cqr;Q`Orr;m+qYpNpo'c5^KiWZ<<*GPqF>s8)9b#Q4W%kiCphli-p7~> +#64\p];3OBrr3*!r;HWns8;lrrt,,.r:eb]*?6X-oD8Lequ?]nrY#81qtpEnrVZZos7XC"WNNGb +r;Q`rrr;p#r;Q`rrr(jUAcMc0rr;urs7TZLQ'd]"Q'ISrOcYZm;+bb55aRe'R$O4<9hT,_R?o +1-q(hPE@h:30K\lR$%c`jLR +Ybmo_rVccroD\ah%Jg#'oqrZL)KbiRs8VrcrX/W$oWt3^Tt(%"qg\~> +%fcC^NaI1Aa3;cH_oU!Arl,hsb08#L`Q#^7aNh0s#65([a2lHE^W"46aSj9]aT'BmaMu3=aN;T? +N*'(Z?C\h1bQ#Nbb0A8V`l6iV@`cg1`5p0JcUrPDPF%l-Q'IMqOcc)195n6(R$X2.Q^LTA8S+$N +O,?"VO-PfgR[Tb/P*1flRZ9J;bf%N=`llKHaNVWJdNi@KJ;B2?KRe]&JVf/)4?TO8@,gM9jQc($ +rq(1$o^_IY`kT=3_8=%)^qmt._Vb7`nEfK1oCMq0]"Pi"^rFF8`P]R-]Y*.nnalJMq!dnGoXVQY +`lPI(cc*Z5a25["l/A:TTS5sL@r?4$CLh1-I!KXNB4Mq:aNMlQa3;]HbKnXq99b^.QBdYt0Tqfb +N1-#m1I@1fOcMD22NX8dQBIP`3bEOhH'+PXQ'7JuQBd]#P_VKRd)3i@aNa\+"3ep-`Sno +$2FQ#f%p0%rqQ9frr`8tqu$AW +qY^Bnrr2rsqtpBmir3B`s8;oqqu?FoLR+3hR$3i(PaRl)P*SLFF%(,4R?EerPsT+IJs;UiC,(7) +Q'@T!Q^EH>Duqu$Bkrr)irrVl_BG*82YQ'IYsQB7?"Od'Z4O-u)rF$ri2 +P`qK"QBOaGF>Aco`+pds7-*frrhBEm- +#6"PpVP_N5rr<#s!W;rrs82d's8Durs89#C*[5"err2uprr;lp'*%t.r;ZfrrVccrnZnX]YI*j! +rr;uss8<*"s8W)si;R*`rVucjs7TNIQBdW"PEqPuQ^*htPX8bt6ZA-ROHPZh6"W92PEqSM0Ro@P +PE_2pQ][N"P*;)TFSu19s8Muss82Wko0%STK7\c#KS,#0Lk'r+HUa*n>d1oVaMPjo`,NW2_S`O# +G'8:^G^P.$NK93cP`Mf`_o'=.`Poi]H[1!fH@C0iLQ7IYPEV!1`l#[3_8=%.^jL0QG("OdGC5@2 +P)YQbN5EEH:S=a\C2S'1E--,>Df'E7DKKl&B))9$rr2lqs8DomGB/h2Q^*glQBIVuQC +.KB+qG%6-8a3DiG_p$?E`Q$!Abfn5N`PKO2c..pc$O8uGe'Q7Qa2Z-tb5KE]ar/4<`Q$$Bb.;k" +:f_53_TU'D`Pp!Ec-48KhoKl\c,7TCaNr*tH]F;WT9Y_0PF.Z%Od/:BE^Xo0R$!SlP!ZhE'[3&OcYikPE8+;EAEH9Q]d\uR$O#'Pa%N#LGRH,_SsO;bK@p*ao]Z(`o4uMb/hfK +\r9W[934qc]>_P$`q.7_`k]^>e]udI#mC`%d*p4Vc1/j^a2,B0=AMV#hY7&#~> +%K$2*g"ZQ,qYC$gs8MrhrXAi(q4K#X,*Mg$s8W#lrW2rrrr;rrrr3Yin*fK$s8W)urr;rrr;Q]n +rr<#Vrr;pXrr<#rqHecDPF%W$Q^3f"P*_K!O=+dS30TMnP*hAd3)EY>PEh1b9p2$-Q'@T"R$Eu+ +P*h,/o`+mhs"!pFs8DUZKSP84K8+u4K7Sf3KSP>9K1^/h]SCQPH$Xa]G&_D2;@j3@!Wi3!#mCP8 +!!!0WCM\4oFouD.&cqh/rrE*%rW!?65B(dmF`__CAeP4Lq#Fk)!sAT.&QO%+Gt"Bs9Qb8oEH-&D +CgD%*DK']=7)JWsrVc`qr;Z]g>DSK/Q^3c)O-c/qOID=j7$EjtPWEJ2P`qH#QB68UE`?#%R? +s8N5gV52`@rr<#ts8Drsqu6Qo&,Z*k+<2D^p\b'krVulrrVlfps8W#trr2p.r;Z]iTV&']_Y=*. +rVccorVcp!rr)fRrr;pXrr;uppg&EPEh1b9p2$- +Q'7JuR?j2,OHbQ%o`+pis"!pFrr2RYK7ec(JV8N+JUrT-IY!-(KM6T$f>GA@_ns.)`5BR/Z?CJ< +H[Ga>hLV>c!iZEH$#?E,T`+L?arr +&cM1?F(CKKa3DcA_9p`O_oBjubS\LD`P]U9aj>MH$jUe%d*BbN`lQb08)Pb/h`Ji5kr=BZeTFbKiIoPa%`0Q^=#$Q'.K"P`R8-AN5m:R?Er"L,`"1 +PEV8m1JO%&O-c9'PEV#hR?<\\5L@fs_o0^8cHt(g-uO6WI"[?2M2$Y9U`PTd@aNDZM6@=l^Q^3c)O-Q#o +OID=j7$EjtPWEJ2P`qH#QB68UErT)UPF%8mPEM8uPa@]#R#u\UcI'q[aNM]H`r='Y`o4uLbfA#O +_l-^29heMYR_ct_o#MB^_SX[Fc-XZ:&eGc3c,RZ@n]:aN#eu3u7RLM/pA9@~> +&,ZD,g"cW-qtpBms8Mrrs7lR$rV-?l@NcjBYl+Csrr;fns8;iq!rVrprr3,VoCD21qu?ZnrVlis +i;WcTBE%r2rVLPZR$F#*PEhJtSW];%PaRamCJn8pPF%PtNBq8GEKlTSF=3',SC#"G_([&L5L\5f-bK8MRBV,q,HF)5An90b:: +A9E'4E-Xq2qY^BnrVQWnohUR8P`h?%N1,usR?X%t.tX.YOCV0Z@[*+@Q&q;"@ouQdPa7`$R['5, +PE_C4PR)DXq>U?lrr;rNrW<#pp\k*ukO7p1o[r[5s8DKe&-)S,rr<#h/fuAed/O(Fr:9jdrrrAc +jRMj)rr7K~> +s8NSiUo*,Ms8W)urqu`os8Vuqs8NK+q#CA#)]Bs&qYL0is8W)urVulqs8Murrt52/qX^2MUoho< +rql]ns8;osrVliqiVioYrr)iqAGl7AG*S/RQ'7K"P+@c%P*DB!1i#ukNg#fpP)VbA6ZJ?QRWKp: +N1?2tQ][T!PE2)pNDB0Hr;HZjs7uNdATrWXIt`]2HW,!:It`N.JV&H'7dSdH]ZIn*^r=4-aKBf4 +G^945GCFseIuBJQNj$CE_SF1+R=0:$H$k!cH['d]Its#GOcZia`4*n,^qjl4KR&)nH@'s_H$t@* +P*Cfa`5KR-,\PTQ*SOHr:E=AXs@QC=&-Q'[l%PEqGtQ$.KKrVZZos8Dcnir8uX%fH>(r:@P*YH>%$aS#E0 +o)A[hrr!6(s7%TV*?`T)s8W&frX/W(r77^6S"o*Es*t~> +&c1k-DJ5]YaN_lB_pd/U_8aXsbVI>^`l#[.e([4t$k89IcH4/Ia3)WNc-48K`Poj>b/M97`QQTG +\62m1>`-54_8aF:`qdd9a90H$aisb0A'e%^OHuH/Q'I]!SW];%PaRamCJn8pPF%PtNBq8GEKlTS +F=3',S=#_7O-#?]OIMDd3RcHs`5B74a3iI0@rd$EK8G>5=E]7GMhcq5JU`#2i7dJcqXZ*a@-rF;iD-g^m4NGje`6$-?aN)F`K9hgdQCEi%Pa7`%Q]3MI +R%07K:e>,\PTQ*SOHr:E=AXs@Pa.;qPEhT%R$a,$OD%b=ccjVUbK'FuiQ)PR`m2`IY[gL%8l&!1 +]Yhk^a:QA0_9LBQc,0ku)]5p-b/qTja9]_K +&,cJ-g"uc/rVZZps8N#ts7uWopAY("nKfD,+k?Vmr;HZqq>UElrVlrsqu6Tp"P<88kk"]O!r`&p +rVlisi;WcT#6+Z%rVMpprg#:+P*M9"NgQ&pQ^!ng1N"q1Q'dc&RYih289A;KnbG"pG)3"U,#1!!!$&#nfXBJ:;EZ@N,ae!!*3&"TSQ,"TeQ%*sNNcG("rn34,VP +E,%^0A"rAO>Zu,aF`hY5?haTsrVldEqtWmHQ^!`#PuX-6Mk?/sGU8Q9P`dY92NjDhRZs2#3,1L6 +RZs&%Pl?dUQ]mZ$P`h;;Y5A1qrr2rqgAV0OqY0sg$1[EPnb(brs8W&erXJf*s8;in@NH^>ZMaRt +nc&Of#laJTnFGf@s8RT~> +#QO_TU9!_]s8DrsquZlts82d2s7cQnrpCmL+<8i0rqucqs8N#rrVlfps8Murrt52/q<4-?V6AVN +r;6Nms8Dutg\rf)rr)irrquSXAWr7?Q'.DsR?!Z!PF%N%J2;'tP*MDuR$rmeAOqrMQ]3AKPl?k* +Oe%T%SX5J&PXP3Er;HWps7lEQ3.lj;JVSM/c%\/XH&$g!ItiSfA*r*i_oBU1aMGj@WdJi3rd+Tk +s*>H*H[:!mOHbfr^;%V%_304jG^4[cI!Yd;*-cg[L5h7TY._iq^;mg0F+J7SHZFR]H?ja\I>7`[ +@>MM3]t.*+Y+n@(CdUa%S`em5=)`&"F_kDip](-irr<#tqFHR2Pa%K!F`-'OIUOtLT0 +P*_<"PaILkC-%?CPa%GuP*(lnPE_H!P*TFWqY^6irr;oqrr<#Trr +9DI\RC2C&ga3;]B_pd)S_8aR=bfn5N`kBR>d`i+2'F(nrd)a2GaN2TMc-48K`Q$!Ab/M99`ll`G +XAi>"?C/LG_8jL9a2l?Eb2(-R`l6'Bc-4DYG>aHdR[fV-PaRQ!P`qGuR=I)20p7fhPF.er0kEn< +Q^<[ZLm4*gR$3npPF.f)P`7EKeB#VJ`lH0Kb9_@[Jpr>p1s:P.;0@\GJ9uou?Wc+jF` +-'OIUOtLT0P*_<"PaILkC-%?CP`h5lNK9-gQ'Rl'OHE:qbg+DUb0.fGaMu6Ua:HJ6c-"/9Dbj)" +:eGZ;_8l,f&&uH'dF-4^bruRQ'U?q[a6q"S`Lg*t6X71ipOE~> +$3'u$g#E&3rVlfos7lR(s82]np+%@..J*T>rVccpq>UElrVlorqu6Tup"8m)k5>8Yrr;oprr<#U +rW)orraPj(b#OaoPa7N"PEh;tQBmbuQ'jF"3f0/cPF.H)9N!m%P`Ck]=d#5()*[KS+qQRD-@kMUk1IMMHq:F[k]7L3.KYF),Z-65'G-"8Mot!s/?#'+R?JG].FV +$3C2/!WrH)!W`H+!WE'7"Ubl-E,oi1=VLrO!!!6(#Qb#."U5&-!+,g<(0>U,JPS^XWbPa\3jS;; +li-[5;KQtlI!7a:q>^ +%fcCOUU'Rjs8N#trqu]nrr;lp%fcG's7.KV(FASMs8Drsrr)orrr2lrrr)ir&cMY&eX*,1YNl,b +qu?Worr<#Rrr2otrVldRrVO`9PEM&lPF%JuP*_K#P`h<"1J'WaQBIH!OJ#9F3J!ETOYU(&RZs2& +Q7RrPQC*l"61k-S.K9;DpfMfnK7JH(:78i0M2KkJIYNT/Is=``ikiOK`l5a6`h[p"H['i5HG&r.THZsa]G]n7UJ:s#HLUP+; +_0]!tV.WtT41"D8kP=b%;KHnjGB,_+q>^?ls$6JZs&"Q7Q'dhq-]==[OI)0"4b]8_F@SKJM3sNi +R@&Xd4a*3TQ'mi'PF[r'Pa%N"Q'P,#r;QZprVucorr<#Trr<#ur=&W(q9ZFOY-P"%pAFs]rX]&. +rr;upr;Vj&)'5.Ds8VTf$N0r'mA6>CU!EN7J,~> +7JPraSs1ma3)WMbKm+NN0]j"Q'[]"P*_K#P`h<"1J'WaQBIH!OJ#9F3J!ET +OYU(&RZs8(OX>d=S"5k*0%JIpb/M69cIYF$I=crrIR]I.[=NkR5(A9\sR]"Z&"_nj1,^r=1*]tD.u`PU^9qYBpY[]dig^s0g@`l6$B +bfRlA^W+=1nGDb=PZDb&DI@]HUXm9"g"UL;DJN[0FtLbT7*NNia2,aH6A1GcR$EUXMjKloQ]mk$ +Kp[jA7m2Q_R$<`$R"RC]G*nDWR? +s8N/lgZ8>5"TJ>us8Vim&,H2(r66N3,"_h2r;Q`rqYC-jr;HWrr;6Kn"QSA0mcFHJ"9/?"rVl`p +rr)lOrr;pDmn/b2Pa7N"Q]Rf&QB[N"OcPe`7W=HXPaRMjQoe>CR?igiOHu"-PrFg\KVXosQAST3 +rr2rsr;ZSn;0n4WL4iorhn[1NdAS[SKS,/2>);g]J:DW[EboAV'F50P"9\N%!!<#t"q!5)Chb[5 +q>^Nt"8W!)!X0/oAnc$b#71b9!!36+!9mR? +%KH7CUV$?ts8N#ts8;fns82d.q>L?iaWMNB7K<2]rr<#qrr2lqrr)lrr=T&/s8Mih^Rh=&ZLn1o +r;Zfqrr:dQrr;rrA,Z>o8<9%!P`qH#OIhZ%P`_ArO-VOjE0-NQR>m2n4'#(DQAmb`QB7AqPE7MQ +Um-q)M,3^?rVlcos8&`iFbbO"JR"8o_8OCBW%!FNJqe\ZOoO+Jc,.B>`PS?nDgQVOGl)biI!U!_ +J:`Q9R`*%[Oa(u!I=6HdGBnL[H[U\kOo',Q?s7fT+Ecl27B1VpqrVuosr&JD9Q]mYtOt(jGOIhc%PEM)nPse/AQC!f&P*M;U +4[>9mR?Ys~> +7eYi+Apq>+`lQ6?`m)cJ`Poj`m)T? +JQH#VA$a4n_oTjm2n4'#(D +QAmb`QB7ArP`./DUm[O8KKR`4c-=;HbL2D:EJ]C#HrGXFZadWcS0iuAJ;&5GId,))o]u)FrVPK^ +ZG=/kqSdd&a2Gj3]Xk`#qY:$7\[]VtaN2BAaiqiJaN2B=`Q#j:i;``Tpo_-C]tDD(`P]=#^;S(6 +a2,C([_hn9o&clG2lN]JF#u84`l-<\ff`ANG'A"80[[hZaMu$8eld3^Ockii.X[SESsGS(P*2&p +6qC7BQ]mf"Q'E>44[>9mRus#"P*_#oQ'mu'PEUb^dEBeYc,e#IqoJf[iQ)PQa3;ZI\VaB`92JSf +[)9oSaT'6i`6?]Vc,kPF&e[s\_og*kaT'9d`O/rA7p)>Fp4*~> +s8N/ehWk(>#6+Mts8W)rq>Lg"s8Mr"+h$i10M#Qt>;#6=uH7qG+4 +((:cT!R11Y-uKhlko +Fli#erqcI]BQS9:F&n.ms82]ns7h^lR$*`!Q9nc;Q&h&nQBIZ$M(^M-JrZ1cPF@T"D_lQlSX,P& +PEh@uOd)6"PEqM^@/Km"rr;oqs4[GRr;6?grs.`Sn+6"ns8VTf!rr8trr3<%d3p1[8H8_hs7$!o +s8N&[lLF)us8RT~> +%fc@8UrN6+s8N#ts8;forr;lp$N'l%qQ(VV*+o'Er;ZZnrr<#ts8^&=+Za'Q'@Q#R;SIUOdMH%S;]]qD3C-KQ^j8)FZhFm]!Q@^3IQ&:om +G]<J-C+CGC+[_rd"Nj=F>UJN4?gK^nX&"AtsrP +FB*DAlM1>RqF>7@DfK\qM>I8Lr;ZfjMe8<=Q'@S$>*5)2Od;;rR?`U^07o4NR?O)$QZ"['LRj`r +OHYro6'7D!Q]m`%I:E3R"TJH!rr:^Os8W,t%/^#$k-hOtYHODWrVc +8+tkoA;\+8`lQ6@aNVlL`Q#p=aNDZHaMlQOdu=SC$qJ^ic,[fB`lQ)=`W4*Yb$iQG5'E3[RZs#&R;SIUOdMH%S;]]qD3C-KQ^j8)FZhF< +Q'7K!R>m]"P^XR=Q][l)DHP94bg"8Nc.!thN.cn8;LR9B\$iQ7,\D[ZJ;/PJLYpM6jm;d4hoE13 +\@T;crP/?F(rGr]bL"5D`6$>P@Zun;P*SFb*PEV.qOd;H(PE_2P:"78,b0.lIans0Zb2LDPb/hiLaLmdA;+aSb +;5_=No#MB^a2Z +s8N/\hXLLD#6+Gqs8W)rq>L^!qtg8m.jld!krWN2srVZTl +rr<#SrW)orra5MQE0uuZPa%Al1RF8gRuinoQCC]bP`q>nS!&r&,X-C8S;W_uSW0)$>=+L:Pa[hL +Q21FXs8DrlG\DVZLPT$,qtB$f_8g8#LP:YFIu$k2m`'s&Hu4.$5Yam<8432@(d15X8kDB==#b,+ +=]8I#;c6Oo=BSa/='5H&(0+C; +&-)@)UXJr8rr)irs8;fos7uX#rVQEgW@&l8SbE'_!ri/uqu6Wqrr2rr&cVh1rVZ8]V5p]@qYpNo +rr;uos5Z)kC?\$`TLZa-j>Yd:^F[^EKK[E=iL\@B8Z\@]&O^UCDX['onA@CE\V^U1;`^po.Y +Cd=hl8o8Hihs(1:s8DOJGACu9E&l_Qqu$Kopq9OgPF7Yu?oF(1R?X;!PF%D25t$^#Q&h8oQ'?D9 +NM)ApSX#P0O!\V,QBm`&PAH'Ms8)`prVccMrr +$hW1q@@"[G`l?*Bb5TH^`r='Yb5]Q_`t$5nS!&r&,X-C8 +S;W_uSW0&"=?i"8R%9@CH.'sZbKJ5Z>?6!!Kn;jTj4qk`[(BLAItN]>I=jtjhq$?Bp?hb)a4f8# +iSXRnro+mSjlY[`gYhD3n`AflnacA@lfm^"l0.?rlKRR3k^!'Io^D/;kO8-6nG`(Jo'>W.o_87Y +p%%V@in`n_hOcrD4f"lHChI@s_U-3DaiPWCE,p)6+LokA_SaF=Valc-Q]dG:2NO)jPb*\pQ&em1 +7#dV"O-buoP]\41TTG>/Q'[hs->Jm7QB@Dk@<0Z8`lQ9Ba2uEDqo[m=&')f:aiM5n@oH&p<_epp +`:Ct\`l,sEcH45Vd1-Wt1rRMUa777N`sBYrEDT8-I+\%@~> +s8N/Wh=U[G#QFPrs8W)qr;-C's8DunrV6<;irArQrr;urp&>!ks83K-s8UI.o&TcLrVuoprVQQk +r;HWps5!\SrA=NRpnqSdQ'mo&P%QM%R[0,'PaIc!1KTa,Q(!f#R$)hT>*,)0ir;ZaDqpn,iN/*()D#*l(gr@=..>O+P*CDCPF.PuPF7]#OZ=nPPa%K$PF.W#G"\*` +Q'RSsR>m.s23j>hPaRS?V"Xicrr2urg&;'Nqu$Bl#3P4@o^^N*rr;Nf%KHG,r;Z]l]%m/Ws82ca +rr +&HD?sU>#GCrVc`qs8Dlps8Vrp$ig2*q"saZc/AX"qYpNkrr<#qrrQ'RSG0nYp\P*_E#QB/iQ^Eu#Q'RVu2Hl31Octo4 +Z2ak%rr)cF5_FfBIVWZmq>K3l`M4o8JUr9%J:BcCr8,3-_8X40_8++1_8uSo!6"lU(rjP/]=u/$ +ai208a2>m7_SsF1`PfR.`P_\lG/M28`kop6_S?Er;HZV7$a%'P*CDCPF.PuPF7]#OZ=nPPa%K$PF.W#G"\*` +Q'RSsR>m.s23j>hPa[\CVYC,frr2urg&;Q_rr;uqrr;`,Z`gU:REPF)o)AXgs8EE(s8;`&f_>+> +r;Q`crX&W'qn])#SYYfTJ,~> +"nC2Y>b/\0`WXB,b/VI#aSj9\a:ZS8cH+M`gTJ$3aMc*@`Pop>rlQ5%`l?0Dbfn)G`lQ0>Yut1: +?&lY>bK7fHa2uEDqo7U9s2P)[s2AEdc-_DINg?,tOcj?3K:8*hQ^!l'OY^(%R$F,%QC*h_2Hl3/ +R$3`!QB[Xn>EtkKQAeFsd`TSPc.'3SHA7'$@TM:9h8HY1R2gF%LkUYU-gqKVc0r;HEap$hGCp&"^`p[[nIoBu/?oC28n+uYMnF6#Dqu6WhrV5mRnFQMS +r;6?fp\=[RmGci..s#AqUQRoV0oX,q`Q#p@aZqo24'PlP*Li)Nm#bfai_`FrlFuZiQ)SNaNhoK_6%EP:/+\\ +LV:XGo>hK_`Q69I`lZ +s8N2Zh"q!Krs/Q!qu?]oqu#IQs8W,u"98Aur;Q^"dd?>Ws8VllrVlisg&>7Tb#4UlQ^*f!4]6Eh +P`V5tPa7W"P`_5rQ^3c#P`JILQB@T'PF%MrOt:j>R$X,$:>#:;q>^Eh>BPaSMLe(fs7uQK_Si<3 +J;K&H[0^E9NQ4RF)uPJrcS9arc8fsG'&+WFEDJ:BfB=? +H@'jYG'J1OF8^8iH$FUTFaSX_DIFbuEIonmEGBMoNi6Pr/;3Egrr;rqprPjFFE;Ifch[PmK!P+%]#R=%Y3GES;WQ'G7gqu-NorRq/[r;$Bl +s8N&unEKQ8oB+p/s3LZLs7kI +%K>OdU?;@Or;HWps8Dlps82fps8W)urVucqrVlfps82fqs8W&srr2p'rqPcHX/iD`r:L$Hrr<#u +rr2rtrWC8=P`u*3;3O.@FdJ>SQ^3l%QB[VrQ'I]%OdD;n94jKPR@08*P`LnUG)hiPP`\erqYpEm +r:jH:KmeZ'55,$SrSbZ3V)`sVJ:`E$KK8>lhSR7H_ns:i_uI[S_uI[S_[j]+_nWq"_o8dY_SjI1 +`52Gi!5nfSs2,G_`l#X4`l6)q^r!h(_SX4,_YqCP`#?M/`kK1(_84(+Nl]2R:bm*)DGl@f@Tt=7 +mf*5Rqu$935]La]Da2MBr;HZqoKe_0Q'@Dj/o6f9Q'%8tP`q;nQBRSqQ'di'O-c8oQ'dZ#P`_;Y +8Qg1tQ'7Gt;TSe9rr2rrg&;Q_r;ZWlrVlT:['Qj:Vm#moo)AXgs8N&us8N#q!WE#rs760gr +%e%MO=fK9U`Q$!Cb/VEAr6##[rl,nub0A>ae'6%XaMu3=`lQ6Db/hZD`lcHJb/hU%a9]P^;I*L8 +SAEAFaSEj7aT'9[aSs1_b1*IZOd;AuOHVh*FdJ>SQ^3l%QB[VrQ'I]%OdD;n94jKPR@08*P`h.Z +GE\PdQ%_3'a2Ps>d+Us%J:3#k/(`G$f#4i-TeCSCLP^ko8o(2MQoDe?.n+#l6p%%SEp%%dul1"*/m-aE9pA"@OmHX!&me#ugP`_&gM_Aq5PEqAoQBIAoOd;2rOHl2u +Q]IK$NKolpS!B/(HV.IdPEq>lMajqt`r='Z`rO3Vb2LDQ_p$9Ja2501=A_[f=)#:c`q.7\`l5p< +aMu6@bgk:pccH+)!64TN$HL-)[YdsU +s8N2\hYmBOrs/Q!qu?]oqu#IQs8W,u"98Aur;Q^"ea2M[s8VllrVlisg&FE_s.GkcI^G^"FXFa/.VEGS#b;/^GrFEr(TH$ORUEcQ5EH?ORVDK&i;+AH`u +H?FFUH?saWG'8"NGBe.RH$jmX=t(.oEHu\:ApA9=6`d+Pki2%+s82cpr;Bu2DfC#@8,3)_rV6D5 +G*A2[R#*jpOIq]0PE_W(OdD5qR[P.\OHts!Ng#ltPF@r*R>uApG>afoR?s./g&(aIs8CUL%Jp,( +s8N&un`TK6p$191s3^iFrs&DWlg +&,kLaVX=?]r;HWps8Dors82fms8W)urVlfos82cts8N#rrr2os#laGJQE.-qoDJ7\hu3WUrVlis +1]I+76'[UuR?Dhl>^2BrRZs,)PEM/qT95J#PF7`#T9,8!Ru``&Ng5o>3/3`]Q'@S#p&=t7rqEuo +L4=i+:8Rdds8(m$^r'\MH@U3jKR\\Kn(P^n_o)Jjpqni'_ns=,_nj4*`NG'"_o0O1`59C-_8F10 +`Pf[3^;7_(be]p6\&#o"_ns7*^r"",`;[_`_n8SP*DB$Lc@kaSWKJ,PFRo#Q]dT%R[0&$O.MAqR?s,)R$3kqEa*Z_QB[c& +PXsL+s8N#trRh)[rVu`mrVlZC['Hd:W2TLio)AIb!<2ur!<2oro)9!prr;iHUn"$Pi;8$~> +&+%/F>d))c`Q$!Cb/M?@b5TTeb/hZDrP]#]aNVoRb/h[%`rF-[b5]Nf`lQ6Dbf\#Hrl>AWQqppl +C9GIsqoJTQiQ,EHaNDTF`l6$AbqbBER$Wn[:gA7-Q(!r'Q]mSsQ(O2*Ng#lsPFmr#OdhDpS;rl& +AN>U:QC +Km8&`CGVEE1= +"onDYiW&fSrs/Q#r;Zfpqu#IQs8W&ss8;os#5[-BkMQ=>b5PKBkX^u'Pa[b$Nb;^aNg6#sNg?-% +OI),qQ][AnOckupQ][]!Q'n,*6TU9rQBdbYG5;%,s8)U`G):p,?_I&hs7lNJ`PK=3838OsB827o +3kW4ZG'\B3G5QL]G5ZYYH#n%@AO$Y58nr9;=H#mhF=+pJCs8VuT9Tb^,P`Ipn +J")RaS!o7UQBdf$OB$"`Q^3c$Pa.Z!P*M5oRq?;r<.0suP`eYpqu-NorRh)Yqu?Zqrr<#nk4&$< +ma_=:d/O(F#6*EDn)= +&,Y"VWV6Alqu-Nos8N#ts82fks8N#rs7$$ers//6R&[Q!MQ'[_sSYFd6J,~> +&*L?3?FIkq`Q$!Cb/M?@b5TTlb/hZD`Poa4`Q#psaSj-NaT'E_aT'BgbIW@(>?u0V_u@gYaSj-3 +aBm$1aMu3?e]9\/PEhSu6&oSbQ&_,tP`D&uR?3buQ'[VpPED#nQ'[W$P*MH)P!D$fS=,V'@TUam +^!4aT3cft&G"I2*aN_`Q^U1el_a$.45[SqhGVZ_]h=UXAoD\:YoD\:Ymsj`jl14HEk.S@fq"+(D +md0?2oC;A>mHsB3o'u>Mo[:%Pht6L/m-a94o^qbDlg!d$p[[\Ep$CtSYf6P/ilOoAF)p)4E11Ti +beq6>@de;H1*A`q.7O`r*d`_o9X +"on/Sj8\oRrs&K#rr<#rr8IYTs8N#sr;Zd$nE96'iW&r#r`B$f6Bdb)Ne0]_Cg*BqQ'@W"SW/Vs +Pa7St67\4bQB[_D309nrO-"K_4-l5%P`n_pqtpEdrI871KS*rcp](*io`*dh`l2qTZ"/bqJqeVE +`5ma[F)q)!qfZ1gG'%qA@Rpb+$V"lNGBS1MF*W(VF`VVHG'.tIDdY@1$kZ0QF`__NH$t*dG^+CP +DesB7G'%A%*"WPk>A\kC)/3\6^A1C"W)(t+s8VinqZ$-dgHBV!G&_L\63$fVqu(#VQBIc#85`BP +RZNl!BM"DRRZMJ\>@W_ZR#df#Pa@])QCNqDEg(oFR$s/%:Y#@@rr)orfDZ6Xs8N&urVuoZme$>H +e,KBqrX/])s8W)Ql1!a2s*t~> +$Mr&DY5A8!qu-Norr2rtr;Q3r;?Qms472Ks"XKA6'.A!Ne0]_Cg*BqQ'@W" +SW/VsPa7St67\4bQB[_D309nrO-"?W2j'AmP*8Strr42:qL)\'J:M3Xp&Fphp]'*i`5?GIWF(E^ +ItW5IcfMsZ^;'9W%`6-#b/;61LQ7P&`59F-rko&X^r""-`Pf[n_A:85V2C4l]?.t-_o'7(^;.S% +_oBa9ao94d_T.t+Oc%/r_m_[NBeR9q8#)hRe`d&5q#C-hp&E`,E,Tc6Da46rp\Xr!JsDIfO@E&D +PaIJsO_74KQCedQ'dW'Od)2sR?a8#@;q?U8sYm,PYfp/rr<#trRh,Krsno)s8N#b[]Zg; +WLEATrUTs`s8N#ps76-rs8N&oiMW09U!NRc~> +&*'[#@^sD!a2l?EaMl->b5TTeb/hTBpr36Prl>)^oZ.'QaSsp\".MqXaXT/+<#sl14? +][aYDBl8!,@k-B`a2c\)HB=)RN^lrGQ^No!O(CeEQCedQ'dW'Od)2tQ]mhp?ZD6X9p_3) +MF+r#`Q#p=a8O09a:ZG4a3)]L`4r0U9M/&X9s;ISo#UjNr5AZUrlG,Zrl"lWo#M0\aN)#e?;OL# +R-&o~> +"omuMkPt8Ts8;lrr8IYTs8N#sr!<<%k3_R"lMpn`rr<#Er`B!`8!T=.OB$mrK2[\oP*D2pP*)$# +P*hG5DKeI6O-u+r9TbI'R[?cd7@TF'P]_3Hp\t'_:i_8FL42kjs7uTlr;#Eq^91;4Q<*Wk6:_!j5#"NNSH[:$\F*;eOG'.qNF`qV>?n`#m"qO=DEH$#EH$k!bG^+CQ +Ecu2CG%PD%#QP5BA9NQP)Ib7hp\:e(X+kHTo)&:`s8MonrMN)0Ed;G3DY=&.p>SE%Od;>'G"71L +Sro-[>rI\2OHi=^Hr"O>R?s&#S(OHZ8ADNpSWN09Ws9$mG5rr)orfDb^J#lXf'kO&!=p +$M_W9Zi:"(qYgEmr;Z]ooDe[drVufpr;R'"pSOR_[E84Br;QZpf)G[K=8_ARP*25pL?nqW,]1XA#OQ +;Y"L"D/VZ"e\0#>`:Llb_Sa41`k$qfNfL?\^qmb%_o0F/_o'F2_o0L0b/U68N/in-`P01-a2>[, +^qmn*`5Tm3`l#F4MMm=OK#bmIYs37bUAFV`Au:/smIgJUs8W)rr;EHXF`)>8@rCr=s7bJ=OcYio +7!(kKP+7Vq,$[!bRZNe)H@/M(OI;GtPamu'PE1lt>\oRj6&LemQqGa'rVcfqqu6Qoir8rW%f?8* +rr;]&Xfee,Qg"AGnG`%ZnbrmqrVlWVWgfNP`VY/~> +$K.OdB=c"&ai_]Grl+u[b5TTcb/j@trl+oW#0=s0bf\#JrPncVrl4u\$,jGf='9'e]uJ4naSj-Y +aSj9?aT'Cgbf\#G`Q$9K1l[]hOAgapK2[\oP*D2pP*)$#P*hG5DKeI6O-u+r9TbI'R[?TZ5a[^t +O_\CYaj88Y2e.GpJ8[9od_io=aNhl<]<=f!LIU#l3`T?5e'm7Op%A:Uq"#9koC;8Bq&O`lH-Cc,moAZ"$F!92J-T_8buco>^=A$H^?.^8>@9 +:/m/5J,~> +"omiEm/QeYrrW3"s8DlSrr<#trX8Z$r;ZfSoBPH0s8W)ts8UCD4lSi"QBQ>aQ&BZbPEDH!NKfcu +P`V/l:4\U,4boPiPV#n#P`hAV;05KsPEhJ7\G,mtoSd:;KR&AB`;f]5rtPG*ikrH9PH8K>pA&H7 +4$`2JLOF7@Fo?IaFa!_+'Q\A+=qM;M!!Gf/GC=gbF`V\JG'b7rs`r,i9qZ$Qps8MgcCNFT;F#VhIs8)G/G*SJ\ +=D2JJPaI`*AO:4#Oc2JTKml^ +#ku*.]Dqp/r;HWorVuiqrr;lpr;ZTlrVuos!WE#prs8PsS"ZaeebK+@rr)lJrr)j[iBiutO`F3^ +MfMp`Oe.\pPa@i'OHko&JWitpLRaKk/QJ(#P*^>dE(H+RPEo4[qu6TfMdM3jH&+r-s8)]o'DLM& +]NgPuA&e6>C1]\$q:ra*^\5PF_Yq@d`6,s3K8u%VNj6I:^qIS$`5BL0_u@OQ__KEUW/ch"O,g]g +_8O@5_na((_8=+.`5BX4_97UlNffWg_S=%"7Rr=4r;HLqS#KK1rr5=]rVlisr:i`pDfBQ42;%[' +r:P&QPaI\9Anb))QB[hK6#;pNN';fHIS=mNP*MPqO%XY]P`T$fQAgtaNK0E*^&7U'rVtmVrr3#s +rVlg'qnK;;X/q`BrVc3aq#Ba\$NL&(rUR.^R\7@jJ,~> +#2Y\TDn*^*rlY5[rlG)]!6G/Zs2b5_s2b2Zs2>#[b5KNbb/jP$rQ,#Y%E6?0b/M"s=B9!t^W+Fp +aSj-YaT'Babf\)faT'Cfbf\#G`Q$BD0U7ofE_MaVE`eNfSro"sQ^X/#Q&nalP>XQ!S<9$fn+,u9_:@2giFd%hP`f*\Cf?OaP*fW?Cm^?D5(SE:9Qc\b +Q(3bn8T^)VN`U7fO-MV]M2t0'c,KY&rQ>/]s2P)XilM,=s3(nn`l>N%9M7rR8XI<6o#UjR!6G)X +s2G#Xm)TLQaMP,o;,'o +%fbYJoDeU`s8W)us8;cli;WcV!<2uq#lFQ"s4d>6iVW?KrVlipf`"pe=d"i41lINeHs2JpP"%Q. +OHYitOCW3jP#t;$PETNQ?'(D#=N +EHl_OG'J7SFa/(AC)[0XrW$"2@s!$C865-PqYg'.=JD9bp%eF`s8Dilr:Xr:E,p8EGs&A'oSl%& +RZiYH?@YM&P*D2H>"4I=I8# +$hh-*_uKc6rr)iprr2rrrr2rlrr<#trr;rrrql]rrVl`p$NC(uPbb4]htR'Io_njjh#@9P4MP!Z +NKl>YP+6o'N0]Vr4ACp$P+7VED39u`8U6M`A5?KmQ^*h-FDk0?R@JRlq"=R]@;LLBKnaJGs8Drr +(B==4il.HlWeb6\p&Fg`92P3:`4j11r58KM!Q2eR_[s](_T77dNfK?hZc0i"^Vdqf_u[cmrk\WP% +`YN/O-GfiOL`BL`lH*^f(sOHYlC=[n@*LiJ,~> +$ephQGIYW2cHOGN`VmmXaoKN^`rF*[b5KQaapQ50`Q63Gc-=JTaS3[b`Q$-GagtAS)\c17QaD,PEMGtA8RHl=@me%P@RHpOI)5t +7rN-=N1-2Y3T/?3cU(c`Jr#(j6/g;8`59O:fZ(@efuqjdcRCa*gZ%VioD\:Vn,;c,oCVSI +ZG"#c]tN@pnF5i7nF?/CoC;;6`4isn]))0e +g5Bq6gs4!ZVa[&=7G6#)`l>g1`6He1iV`AlV +$if;Dq#CHad +Pa.MrF'FZrOASDfP*%b36fn(KI!TsUC,ce/r;[3;9lP5q +DK9lCG&qa(Fp<).G%2Eq$2sp,#8(HaH$tI=hY-[@s8$\pWF3%0rr;rsrVu`opNp%aEd2YC7TtmW +KP4MVQ?$#ZCfHagQ#fr$GE@SJK7SD5N' +$hUs&aSu5:s8N#rrVccqrr2rlrr<#nrqufqrr2rtrX&MkOK#:bjno#Trr*$"rr2ldrW)u\rr<"$ +rqEKuOI8+aPF%;LE5;:;+,MhOZ-rZOdV;Y:k31cOd;%m2Ep^*AO2'!KS=kC +jnJQMqu?NlrSGC]TqkQDr;ZfqrV6eXOG?5VJUBV>5*VM!P<4_jG +&($5DJ@ie>c-"2M`lQ6@`r='Y`rF*[b5KQaaoof*`lQ=$bQ>r.aSNmfaMu6@bf[o0941q5V8UHt +aSs0\aND[)aT'B`bf]_%!64uYs2slQs2n]mb/hTAaNKT;NLW1fPF%;LE5;: +;+,GfO#UfYOdV;Y:46STNg,Mb/1K3%74`e8LkBe)aj\J\_T'F;f>OmVQ^9nRf$;CYbL"r'f\Pre +l0[m6mk4"rnaZ5Em^^*I^:q@ihXU+'mI9W8oCMMBn*ff=qUNh$Vbfn6-aSs0ZaSj9Oa9p&/aMPE';bg).iIC~> +&-(#2s8W)qq"t!grr;usr8IYTrri?!rqu]nrtX5Xo],uNs8W)srr)lps8Duss7lWkiVmouqu?Qn +rqcZmFaKC38WK+"P\4T[15h+53as8;ons8W)QJ9Rf=M>.&LrVufmp[l=XH$+:UH?jd\G^4R_G'81LDerGf#R(;/!!rp%CiOT? +G]e.LrcnZpG\q+L(An.I#8'aOF`qnMG]e=OCN4< +"nJLbchIA9rrW/urr2rSrXf,/s8W)rlBe9JYO2;frr;usrrW3"r;Q]tp]('crquf`raPp*s82ip +qZ$D5G`dhQNg>imB4c`NMis5bO-#Zo1maDkRoDY!QV_X,A^Hns8VllpK)$ECd)fUD+HjCJUKbEPCH5PL-CKXP]0cN6]upeJq$a6O%jkbP`InfQBZ;e +HqT`iPE]-oQ&/?5pAb0ks8VrorVZ]brr;rqru1n8rVZ]is7lQlr;HTjs8Vlnd'BmZZ)4f!r6bKM +s8Mri_P*ToU@j$~> +&&)ppOhANL`Q63Hbf7WA`q[XRb503Xb5'*Z`lS)#)TKXo9iPD/YK+o2`l,jdDj8K +rlY8^s2G;_`l?*Bbfn6"aC<'2aj.rFcdQ'9P)`4rP`h8DAqDdrP*.nfOHu4iQ]m](<'GJj9Q+-E +PEqG&G^`t4OcNmSHSm`B@!I*LI!A)-dF?RdbeD*AfY_WBQ"asVccF/Kb0SVsf%oian*B<.nc&1\ +o5s9^na#f=m(C*K_Sj@,]\rAPnaQ/?na>u8m-jE4qprj)`5oj3_Sbd9md'*%naQGMoCMJEo(Vdm +[D9Dl_S3Rmp$qA2g<8sBc,I]@a#KcW376!ic-4DVai;TQ4'?67FDkt]2h$1#4,f5J89fbKLQ@KO +CK5RHPCQ)SJ5p?G:3i1kO?AVhP\jBI99kd+PZN'mKL45-c,[cDc,n2P`l5p:b08$"aeUa1f3=>>7Ub:M[JXo#UjRj2_SMbK@f4H;dO4A(lG~> +!rpd)rr3<&p\Xmdrr<#tr8IYTrri?!rr2iprr^jCp#l;R%K?>(rVcWbs8MZis8DuTrrL?jqtTg#LO"#bH$X`7G5lgeG6`P7E,/>i$3L,*&dh6JEHQAJG'8(P +H$=CVAiUS.qu@K;&PmIlH$FOYIW0.DD09r@?kWYS#6Ff(>m)$VFa87\N7IRurVuijQ@,EKQhpaX +r;ZQjs8)cL4`l$oF(RLeJV/nu:RH`*Lk9\GS!SRtKNquQ4&\16H]sj_P`h%jOc>`sM`jOjQ^dN&rX&W(s8VNF +lgEd4J,~> +"nALdde3P:s8W&trr<#QrXJo+pu.R9XL%KtrVlirrr39%oDed]rVufqqYpEms8N&so)ARe;uHOm +r:j$DP']fhPaIS7B1&;QQ'4=jSr$ZsNKochP-,.:7%/j8:k#QPrV]$8pQPc5*D"d4HYVjRYs +&%6:iR(gGU`Q$'Jcc3rD`o4u@`lQ/]aNDcPb4E\b`l5p@c,n&ObgeY(Q@_u%P*hA5B1&;QQ'4=jSr$ZsNKochP<4)>5Bg=HOHkYc +Lk\QIMhOKKH[p'WKReZ%HrX7rd*g:g`Q6$@e&j_:QRgS.`PKO;`QZ`eeD9Wan*B<.nc&/JoBkl5 +l1=]6]Y;1u`5KO.]AW8Ona?#=naPi2lg4K@fYtS=`5]X-^VT=2m-3a#nb_hJp[@eHqtn"5a2Gp5 +_SNjrAbGZ^leg"Whp'9da3&dHQ"#!ed`K\[`5U!@d^CK8F`qk<3.HC-M/#_LI7/X5CeL"SG=R9i +@?rrP3D4[]Qp6dsNBND`R$rpr7ZWn&Q$?/iO[$k4`Q6-=aj&&P`P][7bg"<%a +!rpd)rr3<&q>:*frr<#tr8IYTs8Dp%r;ZfmfCSS!r;R3(r;?HfI$AaFrqQUEm +rquHbs7UbDEb/$+KSbD=H\#[DQo]tRHqT0XIT1fP6A.R9OckutOGlDoO[>%oQ'IDi-]S+i$Bd?6 +Q +"mi.`fCo.@s8W&trr<#QrX8c)pXGS/X1J'*rVlcq#lXRGPB6Bpq"k!ir;QWomf$;frr;rsqu-Qh +oKAJ&=E'RkQB=+WrVuWjrtXA*_o'F1_o0O6`Pf[4`50F4^5[l-rK)JjOGpE^`Q,j7_SX41 +_SO=1VN-UqP*M>sOH,=2`PBF0_Sj@+a2>g9^qYtjR>d,nMj]`eMo28H%07BH5_;.1O-#QlNf#ugO$J\kQ'DH4N@0_b +PR*F2QBk^>s8V`jrW<,urr)larr)lsrr2p4p%X_@8mCugpAb0krSXugYck"$o)$f5#lX\paJ5H" +U$I4~> +%^BhaSA)kY`l?0Kcc3rDi5c#?aNDa+ar8:3O@rSXDS+0;bJq?6`QZe:G>ul8`kf^8`r*pU`WXB* +bfn6$aC<0-`lH?GbL+GY.#sU#GF"GYOZbdmN0Tcr2O0DW7Zs1)PF@LsO_.gJ=D*__6$n?9:5,!$ +GCP3sK8PD;J:)_ie()OXcbd]:b0JdOG+;lce'6(Sbe_EFdGNI0nF>u7mJQD[mI'E0nal1_\@oZV +_?[lj\_clHn*L&BGO+Yan+ZD(]t:nh_8="&^:ie'm-Es'o(DMDmdKrCo"r)_]thh)bJh31qY9^R +jNd/JbfS&NcIb+FShAF;cHaPO_nO+>dUGseA55"5KS"u*J7<>]3JW689SSg^J_o9X>bf]Ou+j/'SaMl'7`lQHPccOUW/hoN7 +f"fDK_7Q">:e+8X>I25qaT'BgbJgo?;G9bmb('~> +!rpd&rr3<$q"t!err<#tr8IYTs8Dp7r;Zfbh"'q&s8W)us8MroqY*17IRTb+s8(XP6i-i]rr;i% +@[!$CQB7DoMCaIJPF%Dh7$*KtO-PokR?9F!##DB8o8QiFF&4XGBS+P +B/gJ4"p+Z&'*AIM:3(Q(F`MSJH?O^[Ci(6q#5S=/";tclG^"Ooeb&e:rr;rrV.?KXJGB!9s8Vrq +s7H?Q2eGlmJ:i9%Ko(M(6BsTVMMkhOQ%DDVH;8-NG`eDZQ^XC5I@Wi`Ng,fkR +"llJUh=pjGrrrE#rr2rtg\qQ[rV4L*WiNo2s8;fp$iK`]N-dp]rr;lqs82fos6fmcs&AjprVlfl +Zs\uV5Eh1pOGYTCQ]mbuMFm4_SX4. +ahjU$Mia0gQ'.;mO,^`j^Vn(.`PKF+aMYa8N.dFZOcbfkP*1c^`59@._SGmFs82fqrVE:#WIoZp +r:p +%]O5WU;"L]`Q$'Hcc3rDi5c#?aNDa+ar8:5KhtlTF2#i>ai)$1_opLTHYP0Yd`fJF`r!jU`rF-[ +b4E]2>\).!c+Ca3b/MKO_aC)d6+PRk_ofj6c-4SmeD9WlnGr%Vm4Ro"n+Q4^`Po^2`5KR0 +^:E1mnaGi5naGi5oDSF4\\>ho^q[Ru_nj%Mp$_>9nG`!%lLOK7s2;Fe`l#g9aMc'5_>O3*p#aQc +fZ;+Ua33(n=.XVMd`]SOa2,mFakb2i?;"LNI +!rpg'rr3<$q>:*frr<#tr8IYTs8W)tr;Zd4jP]Xro`+mhs8W)rr;-.ZQ'RXnme?b?r^["drVlis +rVfcVP'g;pQBdaiCmL0KPadRtO^;shQBdi#RX.q"=[%=0I$[0CK7eM6P;J5NJV8c4LkgD7F'/,2 +rql`os7uZn'kio7=.[_;qYpEms8;choYQB/F`V^'F8p@fF)c%o&-r@=q>_-87qup_Ed)\OHZF:G +4qIo)"TeT&(BXgH%SCY\FE)2>GBJ.QD/^R"!s/H&!rW+("W:lmG'81heF`_;rVlcqgKp2E;qLaB +r;Zflr;$0_OWfL5L4k>g3`nI[@[`LHQB%8t5ET,mQ][i)P`04@OdV;O +@#gC@m/?bYqYgHmrr;o\rXJi+oV>N5QB=i5q>^Egrr35^lgXH4dJs6prr;m%rVuooip6!os*t~> +"l#rNjS/TNrrrE#rVlish>[ER$2s_6TrY66qYg?irs8Ps8s5s=\s8W$]rr;uqr)8N7 +G>s`kQ'O+?QB7DsRu9Uq?>l!mQ'd`'H;d+34ap%MPsTYHK6]P@15^X4JqSf3KmSPo=S;Rhrt+u) +rVL/iW)]G6s8)]ms8W#rs('s$_o'F0_o'F2`Pf[1_T&p2KSbeSP`q5kOHGU/`Q-$:`PTI/]>_a[ +I"$p4OckfeOcbZa]#VY*`Pfa5]u%\%bD1J&PDPQmNKoTgMi5Nj_8F.*pAb0jrVuipg0^2B:Y,:= +s$char;-,J+GPN&K8>;5Ko1V)7R2-NJ9j\>K1/0f<]Oo&R$!VtN0KSjO'$RlOe%f&N+SE=R?2Gs +Nfls"rqlZkrVuiqr;Z9crr2utrVm`6s7N-cG*.bSoDS^fq>^E\Z*^d?Y++tZdf0:Hs8&Y* +U"Y"~> +%\RTNW4p3e`Q$'Hc,R`Bi5br=aSj6eaMko?<*<@N^])=e`504+bL8A-Obt@*`QH0=`l@/^s2KN+ +a3)ZPcIFdsML/KmQBRUgCmL0KPadRtO^;shQBdi#R!;Im<]b\&H^7'EKnXn:Ou&#JJ:iQ0LPC23 +E_tN>bf%K9`P9L?ges03^QB[>?Q][\tEaXob0Z_\aa26!Eb/hQ>_o9dBb4D4&CBS;MTUMGXarKJ:WH,I>3E1Jq?O%antl2 +q>^Ens8037UlA^$g@5%?qu?]mqtTg#LO"%AErgE,rcnHc"DV'O!!Dur%LGX?Df]rCF`htRAj@.7 +r;[N4!!!*'":e%@E,ol7F*)eSB5]($rVup!r;^.)!!O6NEcuPNMU_:trVuoss5URlVjV/rr:]j\ +s82iV7mVu]I>N?*Jr=o*JUgBUb*NQ&_H+QBR]%N^neh +G]N]Xs8;iqrVliplM_7jqY'_\KqFQr-hIB3qu-O"jlu7%mEtt6df0:E#lXf'ro383l2Q8~> +"P'HJm/$Y["oeK!rr<#Srr2p(r:mRnWiaPCrVZTn$2jNaOH,Ge63$WVs5j5]s8N&srr)fQ6'Ia/ +I$'YZQ]%&pPEqPpG?BndQ'IMuPaRe?,@3DOsK;MTUMG""WEIXd$$H\I*,JUp="aSku8qZ$Kn +s7s!/TSQjmg$nq>r;Zfnrr3#T_#D7L_Bm+:_oBU+HussmM3*pbP*(liOKldEa2>m6_SjI+T7;!2 +K8YhRrK)>aNk39J`l5m7]uA+,b)(@jH]4,MOH5NhP)P=<_nj:/_"Rg.rVuoss5UUnUQfu$q>UEor:RS*YcY$qmebH3s8NB'rqG*@T:D\+ +J,~> +%[q-FYJA/ra2Z9Jc,R`Bi5kr]Z.q1`oY9g`l60D +bg"PG."mj[JX2ObQ]%&pPEqPpG?BndQ'IMuPaR_;;cJ]83_t0O^;e(:daFR`SW$pl`6?BK_p$6@bgG=th=0t,qYKpWn*TT8rVuf2]#i+-85F8QO,%jIO#hGs@X1R4P*hB#P`qM:FC&XM +OI2;nSt)+1R$Nb&KofeBeB?+VbKJ&L`P]U4b0':r+i_F;`lQ6@_o'F5eN%uLR?Iutcbd`C`k/?_ +:.IlS:9D@\aT'BgbK%8Z;b9SfWIO~> +!rq!+rr3<%rVZTjrr<#tr8IYSrrE&tr;Zd$f&Z8aqu?Zprseu*r;67MHD-@]Ab,fti;RQmrVc`l +OEHYE7?j7&Q^3o#Q'[o"S8hVBBpXsGR$*_r:JZ>'NDVQf'A +"OF$Eo(r7`rVcfshu3ZTrr2p(r:[.eWj("Lrr)cp#laW[G+OVQB(l*$q>UEonc&Ofrr#[jOE6G= +6^!guQ^3o#Q'[o"S8hVBBpXsGR$!Vo:/-"uMbc-^<+p]5L3YX]Jq/K1Itic-I>hu0?U8AqqZ$Tp +p\XS]U8L_h^X3#\qZ$BjrVnP,^r+(._ns4)^VIY%^:\f;I<:'nMiX$bP*2#jYf"E!_SsF1`5%sk +G^OdcL5_8oOsZ9NN4R'Ia2Z$6_7me0L3J#lKPuR.M3!p`PDtRB`5BR3_=dj.rr2ppo'YX[NhBmc +rqufpq"=&FJ:W6)L4>#0Jqnl3ItWD"A:JT0?U&p"P`1lj7n//oR$!T&L6soC;O!K2Od_JoPE_>u +QXaTiP"YQFrr;oorVl]oo)AUfrr2os#j"RFP`(TAEqfS5$i^2$p:df;Y-",UqpPHNs8Muqpt_a; +S>FP^~> +&!L^?[)0i$a2Z9Hbf.K@b2LGA`rF3\a;Mt1BinGALVM!SaiDB<`Q?LRF/P=c/] +s2OTMs2K?-aii#ZDI.mK7[KU+Q'R]!Q'[o"S8hVBBpXsGR#dDi9MTo!N)DQh=)3>ALNP:QJ:<') +I>!9!H&-,u="d7jbKS)La3rL'RANie]"?eG_TK[8bKSAkeD9WaoD&+Qna5`6pA"O#_8sF:aN2BD +b/qT=^#8JOnM9V,o_ACahnQnC_8=76`l>p5_nNeIp@7_Fp%eFVo_uV6`5K^!_Tfs9a1T'o\b5[g +oO-b+lIR8cXI?(lc~> +!rq',rr2uprqlrsr;Zfrqr.PRrs\o(qu6WqfB2GbrVulrrseu*rVZK">E5>=P#B^*ir8uXC&@i- +rU`IAQt'p!Q'RZ!R$*o!Pad\6G!(_MQC3l)OH)=tPa%Mt6#f_RLOk)0.YiJ0KR\f2IuK)+4)\qU +@CK8*qYpEbV/`AbEPf`Fqu6Eks7uZkq"2FYH$+1NG'\ReI<]a;$NLA.!!!&t!"961F*N%UG]I\7 +4;@tq!!*-'rW!]8%o."]EcQ;JGBdRC#Qb#,!"/c,$OQe49*?&>EHQALNn!Xtr;QZns5<,+7BNOd +p%eLJQSF2EJ;Si/JV8]-K61U(7RT'p2*=<,@WFmsPEqE%MDAS(QBdf&Q]YWf7ZWmsRf8T^Q'do" +Q]aOmQ=$Nhqu6QorVlipli-q^%J][`Q]mo'>-\,'rVQEirs.cNo^hP#s8UOH!r`#prr3,\lgF-; +J,~> +#0Ng?p%n^erVm$"rVc`qhu4/brr<#tr:QtcWj::Rrr)iorsJV2=H&c3O]9g/rr)lnrr)lfrrflPE)f^ +_Sj:0`5]`fJTc3bJUDp!MN3aZP`q':a2>s:_8VGHm]qra;#KRSH.IY*-(Kn=n$F(/-<6Sgb]4[rF]F%86RP`_Ai0OBp,PEhAtO'QZEBSS +qpPHNs8Murpu&!?R\IlR~> +%uk77[_^#&a2Z9Hbf.K@b2LGA`rF3\a;W%2B3J>AMS@6UbK7cDa2lPr:Q_K=N'=DhaSj-YaSj6a +aMu3<`pq,ua2Q-Dd`s4kN*^=gQBm\uR$*o!Pad\6G!(_MQC3l&NJf\jPEV;r6?5qVL4Xr(,_CB! +K78N*HA?uj2JQi9:n0>]c-b(iN+&<,DSa-&f?D%NbJM?EdGNI0nF?&@oC;58n+?MR\\$&*`PfR/ +_8j[;`4ih>naH#9oCI,"s5:c)]#;_._SaC4_nNq$]'&\Pmd9WAq#C02[CX;p^rO7*c,m]7]!Jp< +o^VG3e*PZ*`5]a9e@s5[1nBsoe'cdcHPpjDG_CBnItE3!IVrIh5s[4b0fVHp>AH>UOHkutM(rA$ +Q'@T"QB5Eb7ZWmsRf8ThQ'do"Q]aOiLe_o9^>o#Muo_o'Rs6X_U^+9N"KU_:$C3bK7rL_4=Op6s5h+~> +!rq!4rr3<%rVZTjr;Zfrqr.PRrsA]%qu6Wqe*6;[rr;lps83?!ANZ2KSt;4=^#Wa +EI1)5MhV!$nOo[X7_cp[eboCGrr*Q1qtTg#LO"#bG'81ZG^OF6$Np>-"T\],"9Sc*!"BE8H[C9g +FE;1X(]jd@qu@Z;#6t5/!=VhGGB.qWG'[aV"onf-!!i`.!!*3$!"/i?@rH@3H]?PHrVc`p:]0M= +p5sR*Efg")2aE"HLOY&5Jq\r0H:UA"?"IVd7QlfpP`q5*2NO&gQ',30PF7VtQ^Eo"3]!1fP*qK! +Pa.E!Q][Sa9pUEEq"jmfr;HZ_rXf&.qZ$Elqu6G+Gaat[C$tourr;oqrsJ,Yn*oo#s8W)ts4.)K +rVca"r8R/6mJMJ~> +#/d4Bo)&Idr;Zfq!WN,VrW2usrr36#oV&:eY2f?SrX8c*pLBAOP`nbhq=jmg!W;uprr)lfrrsQB[YtR$Wr$J5)5YB)2<#s8;iprr<#frY,>0s8)cos8N&rBR#r2Nb\+_rVlfr%K65"aL/7U +Z('GBrr2rJrX/W(s8;cOV4O3N_gh~> +%u"M4ZG=N"a2Z3Eb/M9>b2LGA`rF3]a=>3I]4,&K>*cqHb0%rNb/hZKdS>diQ]XPFcbmuM`l#g; +b08)PaMu3<`q%2Kb/qKCbgD;[Cj>p +_nj'u\%BMr_n`mlg$n7mm-XKAfu(2-^:_.r_na.0`kK$oZ/b<;iop%+s7k'L[_g&$ai;69`5]a3 +]XG0>oBc&.ea_D9`PkutaO8/KfQCSt@WpCq+YRt^IsQZuIt3)uG==_i=CPcV6TBs^O,Sre0o_B` +Q',30PF7VtQ^Eo"3]!1fP*qK!Pa.E!Q][Sa99+$bdE';O`lcBB`P][9b43f%&$d`r=$f_6S/]7nHWPQ+k>\ajnH>a3)TG`LTmq7TPIu~> +&-(GCs8W&rr;?Hhr;Zfrqr.PRrsA]#q>UEoe*65Vrr;lps83E+RmWC*SV]o5s7ZKhs8Vu\r_rjq +s7lWhJT.&9Od)&qPa7W#QB7>tQB=-bOIDK!R?O#,/7k33QC*Rg>TNR[RurVc^ilL+35 +;P^B^7k0@FLPUbAJr##)J5/7=FEVPHDf9VXOI),qP_plKPa7Q"LamY4Q'df#QBtiBHBst_R?Nl% +P*M>sQ],fBN)0BOrVl`pmJ[k!s8Drms7uEM7@]a0QS\72rr;uqr;Q^'mcs92o%F'Crr2rJrX/W( +rr<#tipQ='rI=~> +#/Ht@o_\[er;Zfq!WN,VrW2usrr39#nt<"cYN>QXrr*W1rr2rtrgZ<:P+.8!q>^0gqu?]or;QZp +o);\irVuZmq1X"E-6#8EGoH,1/kT.K; +s8N&urqbpOq".FVVaZPa%K# +>X<\%R?O&&Pa@PuQBRYoDDd;Gr;Z`ps8Drrs8VQe&,cJ+rqufnpuFf3Q]mdpp&=sirser)q9-4P +Yd'YHq>UBnec#pSs8Mroih`6:T>5s~> +%t\81Zbji)`l?*Db/M9>b2LGA`rF3]a=>3I\m\lI>*ltIb0%rQbf\#LdX!U(Odq(df@Imd_T0m< +b08)Pb/VE>`q%2KaiDZCda)E-O>2i^PEqArQBdbtPa@\u3&ZkeQBR`#Q'Wq/Q][W&N&Op#:kKR&)M95JZgFE_\4@NRe-D0MObN5bK@lG`Pom: +]XbKEoC2A4f(7\?`5BL8f>u+YbVPNX1GThpGCYh%);bN4daN2KRa9ou0b/_Pr<(08ULO]~> +&-(JEs8W&rrquZjr;Zfrqr.PRrsA]#q>UEoe*6/Srr;io%K,ttGab"_R96cjrVZQls69M]s8Dip +q"n3@13/GCRZEStQ'.SuQBmbf5$sP9P`h>rQ#eUAQBI]$S2#SLFF&IlK8k_L3gNbaiCQ:P0Or;Q`rqu$Hn$Ld +#JHk?pAP$irr)j!r;HWphu3ZTrr2p)qXC&UXg70erVlfqrVuj(s8)Y;R?`o$!cGdYHH[:$dH?sp^GC+X^Its,KP`3`"_Sa%#oD\dh +s8W)piTU=?UhQPfD0gehIt!$)IWSsj3__JEFDGZ6F)Gi#?&k;@PESk*Q'mf#Q!HG:Q&q,oQ]m1X +BoeLBQ2[-MPQ-mZQ^3Va6fmq>rV-86kofrr +%t7o+[):#+aMub2LGA`rF3]a:$#*\R/WG>FE7Mb0'_.)pHCE`R%_@N/a3"Q-R[t_oKd; +b0%rNb/VE>`q%2KbJqHBaj`Oi/8pZ>RZ3GrQ'.SuQBmbf5$sP9P`h>rP&;h3QB[u.ShkqNDfg;U +I#*T0Ll.CSK7@DoA8?.%GBe4PDJ#aiVK8j7WHEr;Y$Q^rFI7^VIk1b0J2M`Q,s4\EN_Xk54uS^rFF9rlS9ec-FSU`l#d7 +_niq[o_%n=f_++E`5BR"iEbCX&p2Igl[LkC;2JTYX)4tT&RCO:)?F`M>6=]pWJR$3e6OHl5s +Q'GW9QBdPoQC!ej056K3PEl-6s-*JJ&snoDKfmW*eAf>Gb0%fE`Q$!AnAlfoaiVNHd+WbPNfAfH +0u_AZ`l?*Bb/:Z9<_Gt[8rLF)aN;uR!QN7\ap"hH77L4*J,~> +&-(MFs8W&rrr2fjr;Zfrqr.PRrsA]#q#(0ldd$)Qrr;fn&,Q*u4B[o9KOXiYrVulmrTX;[s8N&r +s7tnGM3=0iNLZB!QB@Q#Q]d\M/!5mYQ]dZ%PVI*GP*MGuNIR%ZO&S)#K7eu8LkgS4JTF@c8N0CX +Ec6,EF`_Y"Oel."g;D"SeboCGrr*Q1qtTg#LO"#bG'%b;7Ks)"!!*!!rVus%!W2p)$:/TIDe(j< +!s8T&!!EB*"pY5-!"9B(DKKo4?P!2C!rrE$!<3)s!"0&F@;^F:IZN"MrVc`p5QC':nbDoN-\$Q! +It`f6Kml6]O37+Q5C.0mEHl8B9j^/AQ&grmR[9;+PE^um/:a4UQC*quQUOo:QC!f$PQ$jIQN*3T +Q^)-BpA4gdr;Z0`('"11s82Zlp/$j9Dts&$rqucqs82`nrsJ;\nac8-qZ$Qos3prIrVlg"jmV^* +rI=~> +#J$P=q#: +&:%T'[DU5/a2Z-AaMYp@!oGo)$#.bKJ#Pb/_oQbKS&H_Sj@2 +_nQ!@q=Eh&oA%O-_oBpR`PB=3eN"gtGD1R%N.HFs/3%dWgW;*hBln'-@;8).3.d6POI`#3Q'[]! +MjQ&GS!K?JR$E`!79,J9Q]m`!rg!MLs-3tYQ +&-(MGs8Muqrr2fjr;Zfrqr.PRrsA]"q#(0le*H5Rrr2utrqufqrVm?#b_Is=QqcZ8s8Moqqs")/ +s8Dutp\B_ZOHGfqRZnI>Q!!!'#!WE'%!WrK+!r`0-#8UikI!1(#eFWY;rVfRL +m.()H3GF/'K8P>2L-SK&o^_kVs6DXoFE:eX8"[)a?BUeGO-#cpP*VK$Q>/=7R?`l!QBcbIN0fct +PEh>uQB[]#PEh\s8+uoYs8)Wmn,=(%rVulqrV=9+R4aHks8Vomrr<#qqu6U&p#tr;o&99Arr2rH +rWrK%s8V3Lna$+'~> +#IU;=q>UEmrVccrr;lothu3ZTrr2p(qX9fQYdj<%rVlfrs8N&ss8NT&c%[m5P=XX(s8Mrrr;Z]o +s8VWg6N-f]s7uPLAr_tXClNZ(tWfR[8tmR?`r$R$O%Q2Mmie +OHl,sH7Y#APa[f$PF%T"QBdZ!Ru0]0s8N&prVc']!WW&qrsJS;9pI2bo_ngds8N#trseo&qUr<` +ZETn;q>UBnec,UK#lXc&oVe@PS@="~> +&9M/u[)1&-a2Z-AaMYp@=;Fc,e!'aqrCI`1pueMN'L2cI0kPaM>g: +b08#L`l@Pi;Td))b/i.V>`Y/:R$`hpR[B>'QBRK#78/`0QBmc(O)?S2PaRl(S",k/OGnos;DB[f +Edi4aHtPRqhq[=F.nrl,Vlair/ieD9WaoD8Idm((!H`5fsua8X$Y +a2\(rs2P-+rr6`e[D'Q!`lH->a2c0@aN2B=^Vn.-o)/@aosqc[_SX=/`QQ?It'43dEp(beD&7oDIR$I0//9UPu*@*RZiu*Q'.H#QBib1 +2MmieOHl,sH7Y#APa[f$PF%T"QBdZ#TSPGTcH")Gb0%g)`W=0'o#N*!ccF/Haj/A24Gb,&e^Vm\ +aN2?>aND`H[t[mV8l&',]u\::e]@d1#fk*6\l_Bk:Nh6~> +&,tPKs8Diprr2fjr;Zfrqr.PRrsA]"q#(0ldHp)Rrr2utrqufqs8NW,qZ$?^k4G$YOSf"Vqu?]\ +r_rjqpA+ab9obO.QBRH'O-YusPEh;qO=#jLPEM/oQ]EhGOHu9"OI;2pQ^O&&7G7J/X\M)nF+[0[ +s7H<`nGdtoAp/066)12P2Xf\@_o^I,rVulr?2sfsoYQB/F`V_94WG(7%g<:L%LrpT#6kMB#mLJ6 +#7s72:b<4e$jd+>"pkG;#RL_>"9nr.!=BQ2Ec4_g%L<:J%LNOR$NgV>#R_.R$O-tN+C]M?F+0+u +oDSXdr_;VAr;5bCL4P/.J;K+YkO\KKs8Dujs&@]A6Z'g8r:TJISVNf&R$uQ&q87]`7a'qZ$!_s8N`-r;Z8-Jp(;lqYpNpr;Q`rqtpBm$M`fRoCCu5 +s8N#tdJj1G"QSq>lhc2~> +#IC/=qu-QnrVccrr;lothu3ZTrr2p(qX'TNYe'W-rr2oss8N&ss7m'&p[RA7P\?$Nr;Z]os82cq +s7-(hrVQ?es85ZPQC4#%Oe@\uPF.Q!P*D%TMNj*NU^9NiFrcK<-GC+dbG^=^_G^4X_GC+q!Yf+8TG^+@OG^Xm\H@'f5GlMpsGBe^mLqU^D^Vdk[ +s8W&sr_NFVo)J^R4+i'=H@CX*9]kpAs8W&to)2>669f;*p&+OO7@T%%PEhB"Pa%Q&OcqSOP*D)p +RZ`e'MNO*fQC*l&Q'.DuQ'I>m=hXk3r;Zcpm/@Ils8Vrqs6t&YF'&,2rVccrrr~> +&9(ot[DC)0a2Z-?`kfR8bf\qds2GPkaN2B?_73ZV>@OSOcH-"))p$1Gbf7QFa32TcM-+iNd*';I +_SsU=bf\)L`pq,JbfIN;dapO9R%Kh2O.2/pPF.Q!P*D%TMNj/P*2#nM2=./ +gXVBC.oT_g/^i=qf?_[u@j#-$FE0R:TM-ind'17%^Y$a/`_ORrbgG=th=0t+q!6AA^U;(o^:q7o +^;%M#_SX4*]tV;!iq_f\ZF7l,#+i]g=Oh/Ne*aiSuQ^!_)S(,?nbf\/PrlG,^o#N*!bKS&C`mW"1Cgo`a +dEg%YaMu3 +&,tPLs8;`ns8Mokr;Zfrqr.PRrsA]"q#:^AW?'e7Zrr;uns69O] +s%iHc@$6buPa@N!Q'[c%M+N\sPae#&PF=\-PF%Q$PEqT(Ng-,j;tp%dqXWNtA,,]pp](*h +s7uWAIW9=>Br6DYEq\8-bJDa,rVulr?2sfsoYQB/F`V[m0fUU8/ho+<2)I'C/hSY,0JG+1.PO2) +6p!Y#:-_366UO(%69m[s4?Ykk5=/"FG&g>M6V:$G5=&(=6VBa46q9mE8OPKu5\>+\EHmGloDSXe +rY,=pjmW59>_J#aLkUG/E;BP1s7cNm.Ja#8_s8;lor;Q`rqtpBm$N&rSoCD,7s8N#t +eGfLJ#QF]%ipZC&qg\~> +#I'r;qu-QnrVc`urVZZphu3ZTrr2p(q/s7cNm%eotom/$VUs7uZnU10ONrf\.bR$*_rS!&;cQ^X;,P`hDr +QBdetQBda7Pl6pJPQ,h/o)Jahrr)iqs8DKe,PqH?qu?]b7u]=Kr;HKiqZ$Tprr<#qqYT9ZZF$m2 +](l:(s472Jrs/Q$q59mWS@*k~> +&8kcs[):)0aMu6@`kfR8bf\qds2GPkaN2B?_6m@X_Rc,fn')90hDcd'kW`R`Ue8V&\Je'>qF +_SsO;bfn5uaAU70aNVeW:Q1[0Q][\sPEq>tQ'[c%M+N\sPae#&PF+@tP*VH&Q^F5.MN*dF6Jp/< +dEK@:6.3fu_90^=cH=\EDes?(AtaZJB'.4FaLo:?bPoLfa2uQQhpgKOnaZ:k^!+OEd*g4`bg+Vb +f\"Tue'ZFabKA-$dEL+qleUCOhV[/Fhqlu8e(*%&gYCN=naG&ahObfe/UaO8^n9oY'sQBdf(P*M,u +P(8a_R[BA)P*hAtQ'[PtQ'M?5rg!qZS +&,bDKs8;fps8Mrlr;Zfrr8IYSrsA]#q>UEocg0cNrr2utrqufqrr3K's8W#i?qQP:]_qX+r;Z![ +;Z$Lcqbr?8Pa7Z(Occ6!Q'@JtQBm_sQB@VqPa[euR?!l%Pa@PuQ'.Z"O^#Nqs8D]lqYBp]s7H?h +rVcKhqSb(*D*P,!4Dn8Igr7+JeboCGrr-4'qtTg#LO"#`Dfoo.DJ3NlBkqO#BkV'hAnc.#Deiru +<*a-PA8lI*Ec?#;E--/8DJj6(CiFE3E+sTED/40-Ec?)ADK'`9C2.U)EH-#:CM73rF)uGKN7@It +qu6R,qs3JAqOCT?JV8Z+K7uYcr;6Kn3r]'WrVuosqZ$Hmr;-6;:7RQ6R#mMsQ^3i$R#mVuOdD?" +Q'IN#P*V>tQ]mZ$Q^!`"R?F"7eGK1Cq>]s`$ig/(r;-+XHY +#I1#=qYU[ER$2NnNXKT;7r;HWnrt58/rVuTks8;Iq8<,:4qtg?krr;<`2#[:N +p&8!LP`qB!R?k['6:7 +q#:9mf)GXJ#QFYsVk9QM["&~> +%;fo^MJPp\FFRo^;;Jq"Xj_B_M5sqZ$K`p@RhB +hot<4`lZHIb/Up$ce=">GBn^mJq/8$eBPnK^V@S#bKA)Rb/DB=b0%uYZoaG5QC*btPF%T!QC*c$ +P`_;tQ^*i!R?El#Q'[]!R$X&%Q_0J"1TS^?aND`Lb/jS)rl>/\aN"%ss2lS.b/D9=bKqbN:>!_4 +b0A,N`l5s?bfn&;PZ(.G8ka3;aN2KSaSs0ba3)Q?=\).YDh%~> +"Sgp@s8W)r!<2uq!WN,Vrra_UJG]s8N!Ms82T`_MFDl88AScO.DK'W?G^+CQEcQ7#Fq/Y4CN=?1DDPgCF*2YHFT-M3G'.kK +F)cAHGB.eMCi<m.Gl~> +"L+]>q#1'hgA_'N#Q!hQXKB;4r:p9krsJ]'rql;KB05\^rr2rtrW)usrW)uqrq69oqZ#\FPl-jI +Q2d*;Q2d*IPmg1_u@Ri_ns7,_oK^7bK%B:R)d+Z_8F.._8=(g_uIRf`5oa1 +_8aO2d^Pg[`QQ0;_=dj.rVlg7qWIJIpd.9!L44`+J:9uZrqcZpq>^Bhrr2oq!<2ut%fQG%A:K`/ +Q^*i%QBRK"l'2F:OIC?=qY^?srr)`ms8Mfnqu.3+s82irr:NQmK)YWHrr)lrrr2j)rr<#rjL)4t +Z(e`&rVlcrrRh,LrrE&trrr/!St;RYJ,~> +$"R7h\]2e7aMu3MaT'6c_m`ZK<,](]bP]H\b5]Qj_oU'Hb&LH3cHF<.`rF!]`lQtfdFCM%\%C57 +`lQ6Aai`#ddbF9]na5Z0n+$8Gs7@'"o^qSFq=jpeo^MSEnac8Fo'Pc5pAXmto^D21kk4]Eqnhjn +nb)nU3V;q5nalDLqY9pWmcs60m/6"qo(M\=gs#'8aihiH`lGO'bge-rGCb7#M1g(+c-4#DahuEG +a2l@$ar8@@`Q#pHd7eVCS!T>&OctlhR$X/-Q^*i"POatSQ^X)#@9V+,cHFGTb/q]GbfIfD`Q#mq +`rF-[as5-Qa2u3>`lcOV>^"c=bf.WEaN2BBc-=>I]U2\f6qL!f]uU,n!6 +$23Ld%rVulrr0:qYnbW4`rr<#krqZHuqu$Km +qXfq`P*5d.s-DBe,91Err+8EqtTg#LO"#b +H$XXTEGoi;G'J:XG]e%IF*)VLDeEH+Ao_j1Fa!b1(O:1FF*2_QH$4CNC2[ND,$Sr.H?aLSGlE!e +Ft[u[Jp;Q[Dg"l'2g'(TFb5\)oDSO_r;Q``k5Y2B7=T`GLjt567JZu`qu?ZprVl]os8EB'qtL-K +8"5X*P*Q$4!L&ZEPlI$KQLU4JOIVDr9)&&Vqu$Elrr2uqnc&Rg&,ZD(r:NQuJbf6Dr;Zfrrr2p+ +r;6Elr9O"Jo]YW@rVlcrrR_&Jrs/Q's5rY8m.Gl~> +"gOo@p\k*grrN-!huM$(q*o$kVO9kkD)q=B^rF@ErVc`p +!<)lr!T(Wk__]0G`5Ta:`l5j4_84"+`Po^1`Q#d2`/;+C`5]g7_SO+,_o0I0_84")a2Ps>^RgM' +`5;Mi!6"iQ!5nfQ'Z7c*]ZA"+caf7&b/hH;`PM6Is8N#t(B*R_s7PS@I^Kms8N#r +rr2oq!<2ut%fZ;(i'j#oPEM2tR$a/&l'2X;S<&n,q"OX^r;HWorrN#rq>^6h%/^)(s7SlrIJX!D +rVulrs8 +%qAam]>i"7`l?!=aNVfJ`o5#=b5KBh`l#;e=&a1G`QH9CrQ>/])TKh:air#UF&jd8b/_NCaMu3= +aNDZH`lQn]"YP^e]YtTb/_WHceQt'nFQ2;lg*s*rpT^R.IZTgoD/1Tp:KY] +nF,o9o'bl-mIU&Hp@I\8m-=!7o?k/:p%J.Pnac5LmksY,p@RtFo]bo3lhf_YaoD/'l/9eNfuqR] +`Q$-6[ardL/T>ilNeN@aMu3A`QHCUAouJBaMc4!a:?A=c,df:RT2^A84m^3 +a8X-[a4JB5a2S%t"h/#98PNuN~> +$23:3hrr;lqrql`qrXo))s7Yu# +I$p=eQBdVuQBIJsrK[DKnWaWNP`h>IQi$g_rr;rqs8VrcrXSu-rVu]mpI07IpAb0is8N#srs\i& +r;Z]]o_%k>li6q_rW)oKrr2p&rr<#\lgF-4J,~> +"gOo@p\k*grrN-!huUd#s8)cn +pHk:7Qi36MQ2d*5PmQ>)]_rVuoss8N)qnG`Id*rl0 +%qAam]>i"7`l?!=aNVfJ`o5#=b5KBh`l#;e=&j:J`QH9CrQ>/]+2u:Bair&YDc\L5bK%WEa2Z*< +aNDZHaND`Nb/hZD`W!jkaNDZLaM?'If.N)HQBdYrOcu&sQg^1@Q^*j8P7*V@OZUJ3_9C!CaN4>" +s2b,\--XWe/jP2e=_MJ[+5#2[[^is!bJq]Ia2uKMgsXsHoC;;:mI0N;nHnXVo(DqM[CGGjrpU-[ +o'bo0n+6PP&G,;YmdTuBfXeQ[q"XLOlgOf>rpMW.l/1n*m/QqS`k]aoq=3e4cKa*+bK@iEb.#"- +e(7DuJTcj(M0U;sbfRcDc,\#MaN"5%$-:-*`Pg-JdogYgPQ[24Pa@U4QiE?NPOXnLR?`ek=+/cT +c,RcA`6$3Bb4Naeb/hZEa3))[f>n<>`lQ0> +[q&0(9ko1~> +$23Is-Do7#EYL"EW>k7qXOOus7/T^UQJ;jG':aoiP`dQe,91Err*9)qtTg#LO"#` +F`mA#s*-,FEH#Sd&e#RYEHZPNGBe@XH$FLREcQ;JH[9pN3t2N5>]Y19F`DMEG'J7TG5cb>HZs^W +@V$GY&Lpq#H[::*earb9qu$Hnk4/HNr'`bOL4bD>LI'qoqu6QnrVuins8N!%q#: +"gOo@p\k*grrN-!hu,.6UDfg->oA[d2_q+ebrr)orrVm#W^r+(. +o>CUF&')B'b.NXjNjljC`59=,_>_=O_uIXf_nj1&`5S^;NJbHg_SO+-ai23s_uIS,_o97&a1oiX +KTr+G`Q5d+_"Ia-rr<#ts5W_NrV8`@=,)0YJqH8Gq#: +%qAam]>i"7`l?!=aNVfJ`o5#=b5KBh`l#8c=&sCL`Q?3BrQ>/]*Q?(@b0&#Y?iX,T_8sd?aSj-YaSs?^a<8^V +dP=XgND+,$@AMN%]>1hbe]YtTb/_WHceQt'nFQ8AnItZbp\X?h[^kSlo'l,8na>f3n+$DL&G,G_ +nbDn5^:UlAq=X@Km-t#?rTuE,kj7[/s7lW6]#`Clp%Ik5cKa*+bK@iGcaL[9eCGrn8:H/MM1dP" +bfRlDaN;`J`l?+!aq;_7aMQ0RfK1X@PEqN!O-#`orKlo:%?QmAN.R_nV[A6UXL;CV@dfa8j94a9ou-aN2E2A5#QhC4H~> +$23A4RJiBMQ2d07PmE +G5cafG]s(/'6\VGH$FFC<"K-;$q>^Ha3GjD"L4X_Ns8;orr;ZfqrVuiq&cDV)s7b#J +MNX6eQ^ +"gOo@p\k*grrN-!hu(G"(Wprr;urrr2rrrW)uj +rr>3R?dc;s-N3^t/J_rr)or +rVluV^r+(h_u[cmrkSTOr50/a_83n)`km^mQA`;k`P]L,_o)Jjs24lT&AuH"`5/4-NffC>`PK=) +_SuJj1W72K_7m\)_8FN^O-GTscGIH9]tj=@s8N&urq>F>rV6Ein2Y96I"6Wg;ZHars8DutrVlcr +rVc`qrt#,/pXL +%qAam]>i"7`l?!=aNVfJ`o5#=b5KC2`l#8c=B9LM`Q?3@aN2NHaN2B?aN;ZOcUqq1`6HBCb/q`E +`lQ*?:d*9GLoZ7'P*mDl62414(CLSP3 +eCMmN]sG?$bJq]Ia2uKMgsXsHp[e4N&bGblo=MKG[HR8SnF#]7naGrFnc/1lp[\4WftG&/ZKCfN +oCVYGn,;SPm7?dBqZ$Bes22Lc][6TFnF5>ZlIjA(bfIrH\%9c*f\"Uq?@7?^JSdL$bf[rDb0%cE +`lQ`PKC-_oKmAb5KO%c-4DSaN2B@ +`Pos?aiVNLcn0i3eA]SOaNOS(%a*&?`kfBX<^T8H8Sc#[rl>)[f>ms6rl>;a\R\B*9ko1~> +$23lfJ0Hrr;fn&H)P+s8VmrL.^D&s8Doqs8VEa#Q"'g +MjK`tQi30KQ2d07Pm*:uEVTD1mf!i.BWZD]E,.l1oDIXh_oU=)rVulr&c_b'oYQB/F`VSDFa/1X +H?jc6FVAqCG]\".%L*%9$<;.nH@'m^G'&m9-rH?s[RGlE!gG5lgeG:[fP +@NkjR!sg2aDfp>ZOO`t$qYU3irUfIUrVcZlh(Er)Kn4J7mJd(arr;oos8Dp/r;Zfkq=_0qQ^j2% +R?a)$Pa)-3s-E2?&!30DP*D)SK`;#Nr;Zfqs7-(#s8N&tqYohNPX>-=s8W&trr2oss836's8D +"gOo@p\k*grrN-!huZEV]G/s7ZHks8W'1?tH]=LInb)qBai)?Q +rVc`p!<)lr"5^i2_u@RY_ns7*^qmnc_uIRb_90TMO-brk\\lA%^VRq._u@OO_[XE'_l/NLOctgA +`koR0rkeZNs24lR._ig=aiKs8PEh,tbf@Q8_8,aDs8N&urqc0Qs8;fkr8'#JIt2of54/CKrr3#s +s8MutrVc`prsnl$p9dkaRZEZ#Q'df%QMm*KPjt"DP+%`%P`U*Brr3*"s8W#orr2lprr)j,rqufq +rVu1NO$EF9s8Vuprr;p*rr<#tk-hP#Z(e`'rVlcrrR_#Ls8N#t"o#0kSY*-:~> +%qAam]>i"7`l?!=aNVfJ`o5#=b5KC0`l#8d=B9LM`Q-!aN;`Uc8To,]["Xc)F?BO3+0`mi,B^;%;1bJq]Ia2uKMgsXsHoCMVHr:BaS&G,Spo=)EM\%:ksoC),8o^`"OrpLBf +oCW(\iPN+>]X$\koC_hVoD\:Zmn!'Hs8Dlkb.kU'\B"F>o'YP`lIX5&bf\/S`4XC>cI(:Z(i4_X +Jo<6adE0JLa2Z3?`lQ +$23Lj$s8N&tpe$ZAf_b^Ir;Q`drqud$rqCeg +Q'@Q"rfmAHs-Du9s-^0fqtq,o9W+RUE*uW8s8VfR]Z@_6r;HZprY,>/q"2FYH$+1K +F*2_QH$Xd^G]s%."EJ%[;m?R$*>#mf3=^s8W&tnG`If$2sf!j[b\*m/-_[s8W)ts8W!(rr;r` +p%._8l2U_]rW)oKrX/])r;6Hmk3VR(p4*~> +"gOo@p\k*grrN-!huuL7ns7t`i +ah64'rVlcrrVca-hS@%H`5KR2_SO((_8=(,`;[Xf`5]EMNK06nOL`6F^qmn-`5BI0rk]Dd_nsEr +OcGQbOc.#p`5K^8`P]O,_#D.h_oB[3`M/HZP`:or^rXO/_SGjEs8N&urqtO=rr3E&r:lCXL4Onp +6_!rLrr3#ts7lR)qu?QnrV'?CRZro"PF%Q#QMm*KPjt"KQ^Ni&R$*>"mf3=_s8W#rs7cNks8W$, +s8Duqj@,4tmJd%`rVc`ps8 +%qAam]>i"7`l?!=aNVfJ`o5#=b5KBj`l#;e=B9LM`Q6'<`l@tu29*SVbg+V\.Y0^jbf[uIbK.]C +aNDZH`PKC.`lcNMcd0k[aMl'5`mJ71LQ@[gR$j;+Q'7F#Q2d$WOcu-"S=,@*R`rskb/jS%s2b2^ +s2b/Y+iqpP31l^/C/dCDe^;O\Yf*o\e]YtTb/_WHceQt'nFQ8No`+O_nbhkUnI5$]q!>f0]"Z+o +l1OWHmoB#MoCMM@mHsH8p&!df^r*t)^@M'knaZ,>q"t$eqXj=Jp%7\@bIkd2[_'NIqYK^Fcg'-* +bKS,QdBL:-c-FGXdWJ38LPKe+J'uH[`l?'>`l?*BrlbqraMl6?eBuT'GFOk[QBRZ#rf[JMQ^=,, +ns'rRP*:iqRZN%YbgjqP`5T[9`l?*@b5KQaaoTT'rl#;db07uMd)\�#brPrlY5]%a*&?`kfBX +<^]AJ9Q%Parl>)[f>n +$23B3i_T((&rVulr#QO\roYQB/ +FoHFoF`r"SH$O^]G]n.JEGJ\p#7(5.'*M9TH$Xa\F`2>DG'J=ZH#d^]&,lPr!sB9=D/jQ:DfKi@ +G]n4QG]d_0lV,TG']5"oDSO_r;QW^mdpJXr;QKfBP`HVK0M`mqu$Els8;osqYgs( +qY^Bhq8HO"R?j5&Q2[$HQ2d0@Pn91GNgPunR?^:_o)JUes82icrr +"gOo@p\k*grrN-!huQ'dc#Pl$aGPjFYBP`q>c=82aos8;ips8)`mrs8RPI\pjcDF!^jr!35[`kodH +rVc`p!<)lr"Q$r3_o2Plr5'Dh_SX4/`Pom7NJEa_PF%9=_Sa4,_T'I2_o'@j_%ai3X-8O(PEUl_ +_TB^5a2c9=_8!eb_D&pIbeop+Oct`fMjh`'_o0=*p&G'ks8W)olgXWJrquflqIXDnIXaIGnGWCd +s8W#lrXf,.s8Vun`E8+eQ'RPtPa7X6Q2d*>Pn97KPF7VuR?^=`o)JUes8)`ns7uZmrt#)-s8;oo +ha`f!irAlTs8Drrs8 +%qAam]>i"7`l?!=aNVfJ`o5#=b5KBj`l#;e=B9LM`lQ0=`l@tu293\[bK\AV,DSCdb07lHbfIfD +aNDZH`PK=,`Q69Jcd0k[b/VE/] +s2P)[+j/2AEi!PSAi&)jbJVTD\A5qoe]YtTb/_WHceQt'nFQ8NoE"RRqsXRTs76Wlo"MWN_8!dr +lLj`ImniWDoCMM@mHsH9rnYN-_8XC,_=mftlg4$1q"t*iqY'CFmdfSTV6R_C]X>lXo^qh=cg'-* +bKS,QcG732d)sGTc.Gm#KS4k3/C)P^`Q$+#`W=0'rQGepbf7fOb06VRMO'HmOd210PQ.!LR/iTD +Pn]:KQ'7Po33CKVai_`B`l5j7`lQ7"b5]Q_`Y$20a32]Jbg4?iL,-9``6-Slc-42D^7&(l +77p6k]uU,n!6<^4$HpT7aN:u'9LhflJ,~> +$2!6>s8W&rqu6Tnr;ZfUrr;uurr2iprr^[8lKJ3HqYgs&rqucqrUN:>PT0mO1;t^+f +s81`m_o't$rVulr$NL"uoYQB/F`V_LrcJZnG^4^[H$O@ECfD#T#5nN7$WhCmGBn=OEcuVIH$FUV +D*/L1!%e9a'j,BtFa%nJG^OORF)>u?FD=/s/LMbU%1k@7EcZ>NO4Ek#qYU3irorhIrr*K,s7^J" +KS+tCJ9Lefs8W&tp\t3jrVHhlA +"g=i;p\OjcrrN-!hu2D$`Q-*8P^n::N/R$s*5Q2d*>Plm>;QBhB6%S4S8qYp +%q/[h]>Mb4`l?!=aNVfJ`o5#=b5KBj`l#>h<)n+I`Q6'<`l@tu1<%8Sbgb"[,)&LRdE0DObfIfD +aNDZH`PoX4_8jR:aNMKLbKJ2KbrBQuO-Z3#S!f\2m$/6OP+7l*S=G^-WQiH%_TU-B`Q$!tasG*J +`6ZEIdC2'.S3gpp5hXZ/a3;K4_nWn8bJq]Ia2uKMgsXsHr:BsYs6jdknETK7nalM@\A#_p_8g;LS?_nX()\aK+Zkj.R%oD%bEo^(u6o&R*COHQ?9[_:&bo^VG6cg'-* +bKS,Qd(@$6aMu6@d*>QEI"6f-Dd(W7b/qZH`l?*BrQP;as2b5^$-UhU=H&B(QCjMDVBgda5tPb/_68`kfR7qT'5faN)]J_9gK:5_pW4`m;ZLrQ#Gjc-4/A]p_ql5tjso +^!at/b0/&LagtkS7nm`K~> +$2!6>s8W&rqu6Tnr;ZfUrr;uurr2iprr^^9lKA-GqYh!)rVucfqu9

UEls8N&u#lakoo'Pu2 +li5?2s8NB%s8Cg;m-O]NJ,~> +"SK^.Wpp#fs8N#ts8E#sir/uYrr2rrrWrQ#jI**Thtmajo_eahr;ZZfs8N&ti5W^R +ec#IGrW)oqrrLuloYU[GrPK>f`kmdkNK93`_SjF1_8=%+`5TX3rk]8bai1KHLmOWkNlT&N_oKj: +_u@OQ_>h@k_njF6Ru*,jR#dlY`5'1+_=dj.rVlfpqW@;IrVlfr!<2ut&,uV"6@4N>H\Hrp5\?$H +gAV'Lrr<#urqud#r'?L-QC!foQ2d*HPm3J=Q'7S7]`.p?rr;rss7lQms8MuprVl`p$iKu&qSKYL +\>-D+rR(TOrVulqfVG44SAG)Q~> +"l>\P=g?0Lb5]Nc`l5pf#u7X`7Z`%Od,a. +!13YP"dbL6boA73h`6#U(q"F4Hn*TE-mI1#D47i.=rqt0V]Z%e%de`k5mc;^\f?)(S`lcZA^<+O=aMu-8 +`lQ"hRfNTbl~> +%0,kYiW&rUrVlfor;Q]qiVilXrr2d&rr<#ss8UU8kk>&Vq>LBlrVlis"o\K!s7cQlq??nk?^?kA +rKQ-'%[NBGPa?cCp\Opirr)irq#2$,rk;gCO$GooF`2>?Ak)[tq#16jrVlisr@ +EH?;JG]n=WH$FINFCdBE$O6Y3#<$FFI<^1"eF`e>rr2p"kj8*Drr;rrrVR9+o6tD&MM>&,?"dLn +Q!4"]r;HWps8)^#r;ZKe6C*t%R,O>0QMm*KPRX%GOaM6Aqtp +$2_o>V!%aTs8N#ss8W&urS[\Rs8N!'s82>TX0^OUrVc]qs8Muts82d+rVucpq#C9irVunn@[E:F +rKdJKr072Gs-Di5$^R!CIph[~> +&*0Ni<2IUSbK@oG`l5s=b2LG@`XU#3b/M?C`O&K>=-:/8rQ"uYprEuc_8O79^WOaC`5TuJ;3Ht: +Pm`qHR@9P3Q^*bsOd#@$rKI8Hs-H6EQ^3\nDeRhIa3)KDaMu-8`Q$!Abfn5Mc^dk/ME3[RCM@[$ +>W(Ei`lH3BbgFhY`5g0A\A,\ge]YtTb/_WHceQt'nFQ2KmJZMPmJlWSnau[q]#DJ!_6rh*oC2;@ +oCVYEn*fZ2nalM5_7IIs]Y_>Rp[[e;m-a90nal;@n+$)NqprHqa1]=(g&1X;n`A*`f?)(S`lcZA +^<+O=aMu3<`r3sjbgY!S>Bu!V:ek2(=<`J_d`VR/"3S^(`VmgU`).[??d +S!/V?<6NG&_o0L;d)sGK`lui\dE';H`l5sAbf[D&7Qa46GeD#8d`;d;cG[JV=%l:jQ0a#~> +&-)=`k5G>[qYpEir;Q]qs5t8mUF'`n\ +r;-C#s8Domi5NXQeboCGrr*9)qtTg#LO"#bG^974%!d/EH?jdTFDtM!#m:,+&dqucGB\:UEH68K +H?OR^D/Mi_r;[W9$Q!5pH$FLTF``"QG'.tRDfB,F'FG-F!"9/kCj:ARIuVtMs8Drrrr_KOq#:3k +rVlip(B4/j>_\#fItiH/K7#mkZ2".ms8;`nr;Q]q&H;V+q=Kl9QBmf'OI2>qS!*K1"IG:/PaV?4 +rg*SLs-*ePQBIW#OA>HGnbrsqs7Z3erVuodq=3h%rr:CF$NL,)s7YUBm,e9IJ,~> +#l`JKT%s5BrVlcq!ri/si;WZSs8<6$qXgP_Y/gP?rVlZns8N&sqYgd#rr;h;H@_9Hqj%)Drg!ML +#EbF?OI)3!Pk^ODQ2m3KPR3Y?QB7DOq"t*kr;Q`r)#jI5qu$BlrV]H]W((K?>!m+DDd7AZs8Vuq +$NL,*rSYZ4`7=hbrr)orrVloT_#;1M_Z.IP^b!7:_Sj:3aME^lO-,QgPE(s8W#ns8W)ts8W&s&,Z;#oT>E)Q^*r"R$Ni'P4k.DQ]d5jRJE-I +PQ@&8rg*nXPF%Mo:A+Ydrr;rr!<;rq&c_h0rr2ros7`q,[C2UVq#CBBrX/])rqa^3T:DM)qg\~> +&*pZ/;OP8>aNVfG`Q$!Ab2LGAb5]I!b/hQ@`l#;m<`XR]`QH9C`l5s;aN2NHaN4A#r5eo\#Kb?= +<+gK=Qi<3KPlR0KR1,FIPECugR?ir$PaI^2PnB=HOcYWdQC+22R>Zi"d`oqUrlfl5`P]X6b0nJU +_oB^C1m+\)A8+t-Ecc+l;p^Uh&-bJq]Ia2uKMgsXsHoC;56n+68Jp@RkC +mI'?5p@>i2_SX4-_7fI6o^MDAoCV_Io'Gc9mJ>kb^;\+0`4rtYp$V55lg=0;p\4:Ln*Kf?f=eou +`"g2,^tAV[oC(_cm+9A"aMuBL]tVV2rlG,^s2b2Z0ZqeoFA74=M2..HM1Be/:R02F`lZqS!*K1"IG:/PaV61%?lp9OHGlpS +&-)Idm/6n`rqu]kqu6Tps5Ld%rVcTN`Pf^Fr;HZprYkh6q"2FYH$+7QG]n4PG'J:WI!KsS@q$>`"8i-3$X[t!GBe:OF*VtQ +IX5pP7Ml=-!#>_I(L_E2G]n4QH?=FKH?X+IA2Ol)$2ji4#rc[EI!L4$eF`e>rr2p"kj8*Dr;Z`p +s83Z.oLjafK8GD7J:<<. +"omSRT\'&>rr2rtrr;rSrr)j,rVZZmp8G!n^\ds.rVlfmrrE&srVZX$s8Muqq."o$PEbs0rKR2E +#Fgm+EgDiRQMHdZOcl#sR@'>,OHtus2q%[(s8W&rrr**$rqcZlr;Q^.qj_f1FB3]gNM=G.^V[h'p&G'jrr2lmk4&EM +rr2irrqud8qt3U4J:E<,I"$HuKN2b]r;Z`qq>L?nrr2rtrVlfr%/3\bP*V6$Pa.ArP*l'1#F(LA +PEJXlNqnt?PlI$KQO0%GQ'.;pO?rU?nbs'ts8W)up\a9`ZF.*2iqrc'rr +%.:u?aMkf%='0FN`QZKG`l5p:aN2NHaN2B@b0'\($-('0 +dF(O'F-DphP6.#9Qi3?PQN3L_ns:: +c-4YVbfP'=Vfc0ZB5MU6G&Ls3b/VHFbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_na5`6o`"Un +o^VJ=o'l)@]Y2+trkrZi^[q0knF?)?oC_YAo^V>Gho*=NcH*o?^V':5nEoQ/n+H8Ln+cM9p[utF +]u7e)`koIBqt9RLj3R)DaiDKBb0[i9ai_]Gb08)P`l?!;aNDa\DL$bnP)G0FK7Hd.3S;]uaMZ'B +`lcHD`Vd^cbgP$*LPh7USWoD%Q'.O1Pm +"TJG[m.C;Ws8;oos8N&uiVj#\rquZgqu$HugZ7h^s8W#prquZorr)lnrWi?!oK\:dPEta(#Eb7* +2ij&fPPLIUR$X)&PEV/mSW9,)Q2gRXrqu`os8No7s82fkrVcqlfh"8i--#rc[EH?ajteF`e>rr2p"kj8*Dr;Z`ps8;oo'Qe#A +N.6M;Ko1D6Cf>MApA"[fr;?Klr;R9%p&+APS!&quPa@])OI,d.#F(F7Q"a-IR/*$IQN*6MPlHmO +Q^*r!BhIOco)AXg$MsSurr;W[q=O%!rVt=F$N0o's6&J1lJV^BJ,~> +#lj:_Uq5`:5Xn +%.DJL=bs`-aiqoH_oVi"ilDhVbf[rFb0%`DaMtr4;cm\8_p$9ErPnlYs2tA_s2P)]s2b2Z#ft-7 +d3O'eQ(%];pm1uGrf[SLP_M,XOI27-Pu=$;PE:iePEhi'P)+;6^W4@:bg"AS`l#[9`QH6Cahu=` +R\N5jG&D#:F*MIr(!=P9bfn/IaN2E@bL4JB^Uh&-bJq]Ia2uKMgsXsHoC;;r'+9b4E[d`ko[;c-=2DO@qW! +:0+^7^W"XB$I$Z4\S"Q2=(fG>J,~> +"TAAXlK\BKs83&tr;?Qos5EtWrt#,,q"asirr<#ih"'D's8;cnrqufqrr;fn#Q=Si1i&2q#C?mr;HWprtkP3p](9ls8I\#WG?-hF*`+LG^"0s`q]B/ +$ig2(qV]?2`7=eas8N!*s82T`_M! +;g!YGJp`0)JU_u +#laOgU;Ha's8Mus!ri/siVrlUrVllrrqluscCM2Ekl(JZ!rr9!rr;cmrr36&s8MRGClahMPm^6is8DutK6sG,@W67/F_Z#>Da_YCrr;us%KHG, +s8N&si5NUPec#IGrW)oqrs.Dr_o'F2`Pqhs#fXa!_SF+2PDB."#a1=2OHGR>`Pqho4i,"T_8aO. +Z&O[,QBRGlPEh,e`l,^3`Pf[0]u.V'^r2FmOI;DrQ'd\rNMFM0_8O:.p&G'jrr2lmk4&ELrr;rs +rr)j7rr;@aFFSplH\$p&IsFMX7I:'So`+sds8W)ss8ET0qu?]qqTqWpQ^F/&Q'Rc$q3;/TOHbke +KTPtos-3PKs-E\O#Eb@1QT7pqqXXUrs8Drss8N&ue[DfmZD.$id/FCPrVuYrTUhXInGe"~> +%.Mq[>(*uuaiqoH_oVi"iQ2&As2P)]s2YYk`P74'>%+/Cbf\)L`r4!Yb5]Q_`rF3]aSs0baNMoS +)IA;hS+W-HPm^<=aBce!&VUhjag +E-68:F`M(JV9I$#bfn/IaN2E@bL4JB^Uh&-bJq]Ia2uKMgsXsHoCMtOrpTmS0(8;uoD$56_SEt( +`5BI,]C>F]m-X6/nal8Cp[7"O\A5tu^qR\%\[_;-p%._Brp:p"me65E_RI7t_S*h+]tV,.q"+%C +iQplBaiDKBb0[i9aiaV(s2tA_1WIDRaN`A\3F[&WH[1$eF`hdnRl&C=`k'1=`l5sBccsPM_njU? +c-j$_Q'[l*Od26!PkgRKSWK(u3/!CePn'.GPECukPFR`'0KH;Wb4E[d`l,g=c-"&@JOqmh9j>9E +_8apE$HgK1[TuO$=_l4LJ,~> +#QFb_kMuUBrquZqrr<#Wrr2p!rqH3brs.!Fjo,5Vr;>s]#QOPi5s1BsP4=eBP`q8^:hlA\q3;)I +Q'R`#rfRPLPre^=qu?]qrqufqs8No6s8Moqr:nr=XIM_"G&h25GALhVp\+X_rX8c)rVGHk`5L4( +rVulr$30ntoYQB/F`VU&EW:(ZFTul)D.+7g$iBu;!t*!#,G6!!X3I +Ecc;@Ecuk_FEMeE,mabP!<3*/$o_sDG]S.heF`e>rr2p"kj8*Dr;ZZn(AIh.<[fV78Prc;KSFh6 +Xc@W%p](9hq#1g(q#1!`qER*"Q&_,qPaIX0Pm +#la[qTt'pqrr2lr!ri/shu3WSrr3?(r;HKikEE'Si;ETSp\t3mrVl`p#5RpX4d2+mrKQu?#F(F8 +Jl$3LP51@DOco^0rfdSKQ8eR:qYUq_o'F2`VmeV`PfU/a2NpkP`(]gOcYWbOH%)q`l#^2^VIt)a2G', +OGf3bQ'@GnOcbXC`PKL3`P]L.]>)D,ML:DJPEM/oOd;,gUW:6g`PfUcs8W&srr)]UnGi=`s8W,u +)>X=4<@KJ47o*?4K7nJ,WJYiqqZ$TjrVuosr;cirrsnl)qu$:U3/a&^Q'RZ%P51@JO-Z,!H\I`N +pltoFQ'M<6#+1IBQ"3/[n,~> +&+\Up>]dNlaNVfG_oBd?b2:;?`W=6+rlPJ`^S4,$?^/D*aoKN]b5KE]`rF3]a9or+`Q$0FcmLK- +Rf&TRQhQaMP`q8^:hlA\qNV8OR$j>-OcTI'#;5&kb/V<"+_ +<\3"Se&]PQbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9io.'4rlg!d$m.'uK^q\%-_SX70_8*dq +md]`1lgF32p?_\Pj06D2]thFu^Abbr\FfUip@IhAlgEs(qY\4:^Vmt'`507-]t)Sbo'u,-cg99* +a2l9Cd(R08b503Z`\GQWa4&g%%i88+6;D'2F`0%4JRHmCb0%fM`Pp*LccjAG`4a11dG?cAMj9iQ_oC-G$HgH. +Y?4Iq>'AEcJ,~> +s8N;ijPU";rr2in!WN,Xrr)lsp\XsqdIHPts82`lm/@4aq+*o9R$@-+s-EnTP^tuQRJE*XR$X&$ +PEhH"M`X[7qtg?jr;ZcqrtbP4r:g-_Cmh/(Ao1't4$5bf4]qCVqYC*us8Domi5NXQeboCGrr*c7 +qtTg#LO"#`EcQ5DG'J7SFDYP/!WrE)r;[K4"U5NFEH?/FH[C'VIV):a"onc(!##J9!!a9IEcc;@ +EcuqZHuj-[$3Bu'%KZ_@2f!MYEd3Pmo`+mhrr3)am.gSXs82d3rVuKfq1jF7]8flS;K#$hV,l%E +rVcHiq>Lp%s82`d4`sOOOIDK!PE)40Pm#pQFS!<`6s-E\MrKIPNOckc)Ac)AprXAi*s8;co +s6&hDp"e^-s3glHr;Q^#h +#ljh.TWn1hrr2iq!WN&Urr;p+rr<#sr;Z]kooZ8\fDY^Kp\k0mrVl]o#5\-d6BIIrrKQu?s-EnT +P^tuQRJ<$WP`q;rQ^F.u4A8cPr;Z`os8W)ur>GY5s8Mlop1fnf9[\%fQG-rr;f5[^EQA^A%L&dJaLQrr)#WTq@pcpA]X~> +&,,(7?Ym*daNVfG_oBd?b2C>C`l5s?rlbYna1\`J=C-ftpr`QV'#r#8b/hTB`Poj@bLJ4'NguT- +rgai2KM-#61* +OIDK!PE)40Pm#pQFS!<`6s-*;Gs-3bF6qYnLb43O`aihiK^o:j75t+:l_SX72d`;d<`knKO +9i55Qg%0^~> +s8NQ'i7e52rVl`orqu]ns5EtUrrVrfrqud!g[+=ts8;fprr)lsrr;olrWiK$qK>YlR$dE/#EY@; +QCKR"OSP.PR$El$R?rqf6#1L,\b?%&rVZWn(]XI6s7u]2>HNZ]92oW`n%;fOp\+L[s7uX%s8Dom +i5NXQeboCGrr*c7qtTg#LO"#`F*2_TI=6EaCLA4b!rrrr2p"kj8*Drr;fn(]47/ +qYg3cs8MTho0RuOA#uA1o_\Ocq>("#s7lKf;He!_;+G)ZR?O)"q3;2QFARIMR?*R-Q2d0IPm3S? +Q#KTep[J1^rm,[j>s*t~> +#lje?TW.DYrr2iq!WN&TrXSl*s8W)rrVu`gT;Ag9rVccqrr;rsrr)lrrql^"rq^e4M3XA)PkUFL +Pa.>uPEq^k8s&h5s,mbUR?rqf6#:L*\G-""s8N!5s8N&ur;XQ7W.Io<;J=tU]33VXq#1*hs8N!, +s8N#trr;rT`P]XErVc`p!<)lr"Q$r3_o2Pl(W!o&_8F.-MfsPtG`e)NOcYTaOcI8s`r6\@&]=f(f7BdJaLQrVG9ET:V^qp\o[~> +&,>4N@UuRU`QZKD_oBd?b2LDU`l5p:aNVlQc,mW*<`N:I]ZA1:b5TWbb5]Q_`rF-[aqVq:`l5j7 +aj&==5_Y`"R[TY4Q^*j8PQ-pJQO0(HOI;;uS1[EqqNYKUS=,_0Q^*M^5A"FWRa94"aMu3<`lQBJ +ai)';a4R1ZUjbcj4&!Q?SN!Una3;]Q`l?6HaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[Oh+o^hJ9 +lK[d/q#8II_SEe1a8X%K`597!md]`1mI'K9p&"?e^qdV%aMtm(_83gu](Ysmo^VD;me$)Hd^I!1 +]>Vn7aMu'0]t)SdoC;A3cg99*a2l9Cd(R08b5TK\`r3t3ajSG[eBuaug!AU*,A"AcUm=Nrai2QI +aMuMHHaUUo#UjQ% +Eli8]q/Ct6UsY3`5fjEa9p,1]p;Vk;dl3QoRH~> +s8NQ-h:DW+rVlfrrqu]ns5EtUrsnerrr;lqrr;6HlK\EKrr2iqrr)j"rquZjr:p6oq8Y+=Qgg7F +S;Wc"O-+Tpplu>RQ'db_=[$\EF*:LUs7uWkrVdW3s8Milp.hK^=/.nSp\t*brql]nq#C*arX8c) +rVGHk`5L4(rVulr)?9U/oYQB/F`V\MI"-ZrH#dO1!sS`*"TSZ&!"B#??ZL71G'A%LE_d8NquHa( +.K]_P!!sC9f +rVQNks7l:leb3p>VJ*@6q>^3crX\r&r;1Y1HYmhHBNIHXQ^@K4#CeIWPaR_tRJE-JQMZpPQBdV> +DPdC5nG`=b"Q]+En'q@:!WN,Hrr +#QOVGTqpoMr;Q]prrN,tir0Pirr2ios8W&qq>^BdYbS>9r;HZprr;rsrqufrrqud$rr)]5/:NkI +rfm,A$'^^FMjTcjO`k40Pn0(@Q'db_=[$\DE-+tNrVQNmrr*f6s8Vrpp.M-S;kZ>Nq#Cs +`P]U3_SaEqH?agcrd"s0OcPTbNKK4@`PBCj_umip_3Y(H*-cmUJW#DFP)YN]Ur^Ei`5BFas8W&s +rr)]UnGiIdrVuiq0)tkKs8)corr<#op06)?CkeWoZi'b$qYpKos8MuqrqufqG=d$qEcbtr5`D%r +plu)60n,@TPED:,Q2[$JPmNa$:prr;Ke%fcP-s8))l\[A`;kPG5UdJaLQrV"^7T:Vb&pA]X~> +%Jo4`ARD1G`6?BC_o9^rb2^PC`rN0fn+Pm;dnI[$7aOdZ'2&X/?>Q^O;2Q^*l"NDs)9e]l8.a:QM< +c-+2K[#[jN6qBnJ`lc6Ia9p/1\VsH^<+Vudp4*~> +&,cJ-g>Df-s8N#ts82]ms5EtUrrVuirqucuoAK'!rr3,srqu`orVm$"r;6Bhrr2lr:]17m^/g/B +R$Er$R$3u*QC!o&QC!o#Ng#csQ'@bk="'DtR?`u%Q'IPuP_Cf%DJj`?DJ;<0qXsjfp&G'gs8Dip +rpuXtXF?!"q#C]Fn1Ec?,8:)EtGA +R$!c+P+%GL/V'@TOHQ&rPDY0ZR?j&$R?Ef%QBmf'R$NM\6LXsPnbrReqYgEtrT`eDld5Y2!WN,I +rX/Q#s6Sn3l/;R@s*t~> +#QF\SU8cW:s8N#srrN,tir0eprr2ios8W&rrr<#j^n.^;q#16gs8Mrqrquirr;ZfrsOGoBhR?a#+KNBRgOdVJuQBd`!Q'?tVA8Z4-DJNlKp\OXas7u]p +qZ$Nks8MY[CoMc9p\OpirVc`js8N!,s8N#trr;rT`P]XErVc`p!<)lr!T(Wk_ct!q^VRY"]u>,< +H$Xd^GBn^tPEM#gPE3Gq_o9O1ai1E3E.<:^I!BjaLQ7IYOcYIB`59=.`P]^2R6>C^Z +Ec,f8>Zm8RR$Nf!RZNnrCb:1-PE:rrPEUl[P*qW"PaISrQ2[!IQNib/JjAf)r:'[cqYpL%r8"un +]!.k#rVucArX&;p^n[BiU>#GCJ,~> +%JfCsBk*(6aNDZE_o9Xpb2^PC`rsR$X"tPEqW%Pad>-.$p'aQ'7N!Q^*o%K.^\PD0Ti*==2_N`llK: +b/_NJbK%]Hb^X#pCi@eGc,n/PbfI]:^VS"4`Q$-GaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[Oh+ +naTfNnaQ2Gs1H7jb/_H9^;7q;c,IQ7]C#4[oCDPRr9M/,aNViRahu!5`l5m8_RfR=o^2)9o)/@< +]u%q5bfRlD`llQF^qRY5p@n4QkgAbKaiDKBb0[i9aiaV(rPn`Us2t;]:rgf+cd'k]coRkk6.!]q +^rjpB_og'Kcd9sM0P,EAE,T]9?! +&,lP.f\lT*s8N#ts82]ms5EtUrrr5nrr;rnrr3&PmcXTL"T/5squ6Nn"8r&nr;Q]ms%Mn]7sKiM +Padu.R#dDrQ'IZ%Q'$rXQ&q/oPa7MfF@DFQPaml&R$X&$1h_5RG&2AFG?nP^?krVu`m +qb*oa9(`/[p%eX_r;$="s8Domi5NXQeboCGrr*Q1qtTg#LO"#bH$X^ZFD5P"#Qal(rr`)t$k-Zd +F`;>B@7_+9!sST&!!3'#rW!?:>]=b1Hu!b31'[d]rW)s"rW!K2!<<**0kklXH$t\%o`+mhrr3)a +m.gSZs7QBir(m=lr;-?jqt?,!VfJ:)qYg?gq>UEkrqQ;/3,sCaH?"1LD08ToQ]dZ'OHc-$OZe5] +PF%i(Pa%&XK8c%[Q'[T)PFdf$R#d2ZIV)1Lqu?3c!WDoorrr8bn+,_rr;Y4Err3,ekj%Kjrr7K~> +#64Y[USZ-/rVlfr!WN&WrW`E%rr)fqs8Dm*s81<6Y-dNns8)cprVlco!<2rsqYpNp%IjBdGD2$> +R?X,*NKKM*PWG(nO,/FROHPlnQBR&F7?iaqS<9/*Q^![jBR=W=C3+E;>?g7ir;Zfns82fos8)Zj +8Z&1OoDedbrUp3irXJo,rr;utrSYZ4`7=hbrr)orrVloT_#D7O_$@]j_7n'5G^B@9#'tQ?I"@09 +rfKU0`kfR,_oofsIs-3iGBS@YGC"anNKTHdON>8K_o]X8^R0:kIX--bGB\@]Jr5SNMN=RT`P0.% +_"Ia-rVlfpqW@;IrVlcqqYp?k:&b(js8MbQGG8uCrVlipq"k$jrr;ciEAh]\BQe69DejDfE0ZNL +R#[>qR#a=ZQ]mc,PE_;hK7f,IQ'I\sSroM#Q'[MiKm[H&r;-H`rX]&+rVlfne@;rqY,h?rqu"k@ +$NKts\YG^eUZ;:OJ,~> +&H;44D-qn,`lcHC_o9X^V@Y,bK7]<^%_0kn+H_RkeF^Hc,e)VbK%N:`5]m=_nl*@m-aK1qY8^Y +_p6HHcH!rC`5]m<`4_oBpDb07uRH#]HfJCDES +`l5d5aiVrYg0#k=HYdnDGAqA?9lZJ]Q'm\sQ^NptJ^* +/Cr%ko#MBbc,n/L_lmuG6:apZ]#i"5dDu[=^UJ/^9ibuHme_M~> +#6+Z&f\Z3!rr2rt"8hons5EtUs8VurrW2rkrr35KmHX?Ds8N&tr;?QsrquZkrr2lr:]((ir/X*F +L51SROd)B"R$O)+QBI2\JVK5OQ'7N%R#->GT9>D+P*:um;`Af6EHQ/BG\_Cg46ZP1s8)Znqu6Wq +om24eEi\j4s8)cprUKjps8Domi5NXQeboCGrr*N0qtTg#LO"#cI!p0]AR#WI!VQL'!<<*0E--,10TM9XR[TP+N'2WSR#R8sPEUuZJUrT9 +P*M?$Q^*SuP)>9VMaarOq"t*]rW2uqrVm5qmIKc)l2Ue]s8UOHrr3,^lKdZgrr7K~> +#QOeiVP:g#rVc`qrrN,tir0\mrr2lqs8W&rrqcZpl^+`[gA_'Ks8N!#rVlcprr)lnrr;mls8@sC +=+l<`R?3W%P*_DuQB[JgK7AW:QBdZ"R@&h]/t\;jR?EbqPuBS^BlA'/EHGi55W\0.o)J[gs82fp +s7LYeUMm.&s8W#ss8DrrrVuoss8W)t%KHG,s8N&si5NUPec#IGrW)oqrrLulrkf/]_o0d;_gH`T +H?jg_rHh._J;]PQOcHig`5][3[G> +N/s$eR$<_j4+*9[NKT]nPDt6HJVT5JQ'Rf'PDb]fL5^qH6a?XaqZ$*b%fcJ*rVlW7[^WTA_>O<. +d/FCPqs^b^S=ZJDrr7K~> +&HD@HF'Ndt`6-6A_o'L:bf\te+NDC>`lQ0@c-=JM`PSiY<`tNt_8FI?c-4>O`l5s;aNFJ&!65#W +HGdhReScd%GCbC5Nff`kQ'IZ%Q'$uXJ;0,NQ'7N%R#->GT9>D+P*:oi;)E9-E-?/BF(B#E-HFKK +bf%NHa3;o\cWtFYArt6_be;':a3)K@_8F79bf7ZHbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_ +nalDF$N9i"^;@q5cHOAIrP(tBaj%i@^$,=fqt^0Z\$`ohaN;cVbf[l>_8jaB`P;-Ao(_JAq:!-q +cHOMW`lQ0>_ns=3aMu'Fq=sRTl-\kLaiDKBb0[i9aia7srl4rV"2Vq!b5TFPbgeeKVCp*2aNM`P +bJMHGgauZDEH#i@E,TZ9EFLS\OH>luQ'.%fI?^+YP*qMtNJ)k6LQ.I^P`q8rP+7_gJ9GubQ/0^- +bOW^cb0A)O`PJT_5s\%=H,%A;ajJ0:bJ:5j;GC/,eF`]i~> +&,uV/gu%Gts8N#ts82Wks5EtVs8N!)s8N#or;ZfCm-F!9rr`2rr;QZp!ri,qrVl`p%J]tuo_FPE +JrY;AOI):4Prt:mMhd">I>X5RQBdYsR=T-LR>[PsR[&=rDJsZ?DKg,@HZO+I/C4=is7u]oqtp3I +KF),r8B2=e_N0Tcf5_G/YR?s5&OH+gDKS+r5 +MiNdXrf@MBKSb)'7/-NLs8Vudrr;rqrs@rXp%$]6s8MusdJaCJs8V!Am-*=*s*t~> +#64\sY+N&qrr**"rr<#trS@Gds8Muqs8W&toq&4ibPh>;s8N&uqu6Wqq>O+gq#C*\q2eC(NdZtL +QBd\uPELr_KnFu*MNa +&HDIXI9:0l`QH?B_o'I;bf\qds2P)[)oftCc-FAI_S08V=b+)s`6$6Jc-"&F`Q$!Ab5B?[`c]PC +e&fneEB88tG`.KEPEM/pPE1TUKS+]1PEhH!PEM>bCJU@VRus)%HqS6kFEDGIEH$/?BP%mYe]Q7X +aiMTLe%e28O[RgKaMQ$6`QHEI`l5s=c-42Ibfn/IaN2E@bL4JB^Uh&-bJq]Ia2uKMgsXsHrpq?% +nbN3k^V\%6b/hQ<^V@V#_8XI6_7fU;pA"[I[^X/j^;Blj29*\R^V.M'`l,Las6f@Io#J,Kaj%]C +beM$4^q[Rs^r!t#chdM3p>aQef?)(S`lcZA^<+OiaSs1W`Q#m4`6$->`PTXCR8g&+>h$a0aN)BC +ce3A-D0'Z=DK:,KEb]`4AknS[Mj0Qb5D"rVR?s5&OH+gDKS+r5MiN^PMij6]K7@ZF-.g\jeBZ&' +a:HJ9ai(rh>S!pF5ZinJ,~> +&,cJ-jl,A%s8N#ts82Wks5EqZs8Mrorr3<(r;QNls4c`'kPbD`qt^*drr2p!rqu]mrr)j\q>^?l +s7l,j=akpZL4kG@N/W[MKS+r3Kn+fEc?&AFEhkHE]WRas8)Kh +rsea3PGhd(pAb!erqcZnnbrprrVcTN`Pf^Fr;HZpr_*:gq"2FYH$+7LG]$Uj#QOu/":#/8!WW6+ +#6Fl*"UGcHF)Gqg&J#!s/<"%0m=tBm4fI +I>ubKs8Drrrr_KOq#:9mnbrOerr;rr8,)mgQ`X'6p](3ls8)cJ6$-pbI<9LTDK'QBDg61lH'4h^ +G>3sPQ^F&'R?NM`J:`H-JqAZ0K8"o6M1^>;J4f&*rr;ios7-'irVlfqrs@iXp@QW0s82irdJaCI +s8V*GmHO!:s*t~> +&-)Y+\Xokls8N#rrVuosrS[\Srt,2.rVlisqYg,nVQRi5r;Zcos8Drss8DosrVld[q#C6ks7u2l +>(2$[KnG5;MMd7EJqAW.Kn+fJ8"s]mG9NJ9uTe +G^4XaI!L!aI"I6;NP*3Ib,BH-IXQWjI=HKcIX?HgH[UO*P)mGma1TKUFEi(XH[0j]H[L6jI=6Tt +L67Oka2G^.^VTUCs8DrrrVG[Gs7cNks8N!qs8N&rrr;urrVuonqd#Dd:=f4?r;Zfos4KYYC2nQ= +DKKT1DL-/CD+Af3SrRqdLkq=`Q'Ic$MMH_6KS4r/KS>&3JVSu/I#*5Cl2U_^q>UEarXSu-r;?Q\ +]!f#SRI:(Ss3UcFr +&HDOcN*'Gl`lQ6@`P][=bf\qds2P)[*Q?%Bbfe2F`5$Io=*:p__oBpFc-"&F`Q$!Ab/h['b5]P- +`k]X8d+6OdPt5q>Jq8K.LlICQL4b#-Jq\`-Od_MsR$0[`89a!5eWK/AAp;_S5L9q>]H\]#)7u^Ve%+^rOC4_nj.'_o'+Uo).qSa03(h_8F1, +_8?2es1eTJ'thE!eGAt2n`%m]f?)(S`lcZA^<+OsaT'E]aSj-XaAU%!`l#d9aN)9=`lQb(LS$W9 +bf[iJe'H^V.rK9MJT5USDfK]BDKfthG`eVZG"daLQC*r&R?NM`J:`H-JqAZ0JU`**NJ)Y,Be$sO +dFZL_bjia`ai_`D]pVY]5>4hW^r4R?$HBlL=\qgpK]`13J,~> +&H)S.o&Sp2s8N#ts82Wks8V*X"98Arqu6U%rqZTjs8VZHlfA$E"T/&jqu6Qo!WN#qrql^-qYpBi +qt6IKL4FZ(Ljju0KnTGX"b_Y]Iu'6dQ7nAjPCdjKOd;AL:NCN#D0C#DEH?;>E--5::&";[s7uTf +]OIt!F7oS-q>^HorVZ3b$ig2(qV]?2`7=eas8N!Hs82T`_M#6G,9"p"`-$Q*8oH#=rCrX'5"U>23!!!NbB)ZrX +IuVtMs8Drrrr_KOq#:9mnbrOeq>W,Fa]bO4@fH6(s7cQG4EbUaE,9Q:F*D\IAoMj/EB]JMPW4;P +R[9;$P*:iYK7njRK+NWfK7/B,MHWaHs7Q6grr2fbrX\r+rr<#lkk+W +&HDb-a.T^Hnr:0ass8MrprS>#nZEBtqr;Q`oci+3u +US"$IaSl/ +&HDUfS69!k`lQ6@`P][;bf\qd+i_UGaMl-BbfIuE`l+$9<,SYG^rOUBbf[rE_oBd?bfIm'arSRG +ahl-@bg+Rg3I5jlIYW?)Knb53J:`FDQ)@FDu2ABl.d(=ub3[ +ccj5Jc^d^sG$W_P`P]j;b/qfNc-4E2at:]R`luZJ`Q6-@`QQ]N\\G_fe]YtTb/_WHceQt'nFQ8H +p[>K#[(sJj]t:nirk9#X^V@=g]Y1oGq"iLG[_08a^:XBS)8!Sq^qmdr[^iuZo_e^b]sG#R^:V"k +]=#6K\JVog[^ +&H)S.ro`A3s8N#ts82Wks8V*X"98;oqu6Ttr;$0N.Q\8Kn]MZ2h?U9K7oDTNgYrtP(e*ENg)MIDKBN;DffrGC3OrHEH6A.B`.c-qtp@i +V6!ASpAP$jq>^&5o*+;>(l'+tc`%MB?`$k*LN#n%:X(1Lln1)UT2#S@RT&ebff&eYch'GCub#oGF+GBn1Q +N7@M"rVlfr"6f+Hrr2rlrq$.Hq>:,4Ml13is8MroqH%BMEHZSJF`_SDF)QAHCiX_tCR%53PEh<" +Q'n&$Kn=l,KS+o1L&HZ7K8tY;HpRW,q#CBgs8)ccrW)ios8V +#64\ueY/_hrr*-"rVuosrVb^Srr3N-r;?Qns8Dlmk+&N^iVWKKs8W&urVHNmr=f21q#16kr;Zci +bs$i9KmJW,JV*fP2h?U9K7oDTNgYrtP(e*ENg)MHD/s<7DK'E:Ap&<>Df0`"BDh`.r;6CfU8glM +q#(0lqZ$Hms8;los8N!,s8N#trr;rT`P]XErVc`p!<)lr(#HaD_o0?[F*M_XH#n7UH$FU[H?j`6 +H5:dTL53:WO)fo"E-HSPGBS4YHZs[ZHN&1%H@:Ff\\=#NG^+=YIsZKeG'qt1 +_nl$Gs8DrrrVG[Gs7cNks8W)qr;lotrr+eTr;Q\:M54[^s8Dlmq,M'HE-6AEE,TQ2EG]r@C2e;l +Bp1f+OctloQ'n&$Kn=l,KS+o1L&Q`9K7\r1I]!er@^%D=(s8:7C +$2qc8SXZ2%rr;tJ~> +&HDXfWEW>e`Q6-?`P][;bf\kbs2tA\s3*@?aMl-@X\;`/R('`JbK\/M`l5j8aNVlLaNDZLb0%fM +^Ve13`Qurc].SAXJUp=p$C\am+9A"aMuBL]tVV2rlG&\s2b/Ys2Y2_rle0\aMl3EcHaVPajsOA +T3mr3`5^'U5[.o;E-62CF)>f8DL$;=EHY2oPX0PWP`_B!R@0+iJq8K+K7ei2KS4r+IZ9)5F=Z(m +aNVoHbJMNoa:H83b/Li9:dI3-HG753ai;`L$H9c-;bg+jVX4?_J,~> +!;uir!pAV/r;Qfpq>UERrWE3"q>($is830"s8;oseF)>jrr3?'q=jdcs8W)ts8W&srVmQ.s8Vrn +s7cHkmDhbNKS>#3KS5!VKK"O7L5(/3Q'RT%PF.Yo9MJi!Ciai>F`;AGDg6>;F)c>AED#S9qAeS' +HApAGs8Drrrr_KOq#:9mp\t!gs8N&us8>Ifp\O5LWMrbhr;ZUuB6&!6DK9f=F`h_DEHPu?F)H"] +9l5rXQ^O#(Oc"dCK7\i4Jq8Q-JqAZ/KnP)-:\a_^rr2iqs82Z_rW)oqrrhELo)%8BrrMuri;WcV +rr)oqpAPBulf[^&j8]/Us*t~> +s8NQ%h4gUdqu6Tnrr<#trSRVSrrW2urVca%q>U&WYd2jVq>UBqrr<#srr;rqrr2j1rqcWoqu?]m +rr;B+7tQAHJ:iH*Jc(-YJVJo.L6\'fRZj,)MbHiO?#+J)DKKf7FDGu=BQ7s1Ci)hHpAb0iRW50L +MYd>Or;Zfps8W&qrqufqrXJo,rr;utrSYZ4`7=hbrr)orrVm/[^r+(.a/le[rj;j=[^N[C[f<^+ +[C +#ljea\6i6l^;^)ms2G)\b2CA@arJLA`QH?FaN26B]2;jAM7C:?ai_]D_o9X:b08$-aSj82aMPp> +_8XR7c/-jO20OG#K8,)6Jq8K&It<0*L44lBQBI]#R$NY(9jV%ai_cMb/hTA`P]^>bfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_o_IM9 +o()DD(A74emdTiBqYKmVo_.qFmI&Tmq=sU\rr36&s8Vuiq"t'is8W'&q"!dos8;ThrrN&prr2rt +!<2fo'D'u=n+#c*cg99*a2l9Cd(R08b5TK\b5]Q]`rF*[b5TU]cH*uDbg"ARb/)?F2kQj2ccXM[ +5?;N:DJ3m-F*);:D/aT1GB.P?4A'FMQBmu'R?\*s*t~> +#5e>us5)r#rr3)uqtg0gs5X+Xrs8Q"r;Q]nqtpEc,u83aRK'Pa.Q#Q&UOtKFriiKnFl-L4t&3LOkA38bW)^rVlcqnbrRh +rr2p#jQZ71h>[ESp&>!Orr)iurquZmr;Zcqs8N!(s6&n7kM-%:r;V9~> +#ljo&m[^,_qu$El!r`,uiVrlUq#:^#p\:_dZ,lY=s8Mios8D`lrVuiq-N3VR8Uu\JIu8i1KS4`0 +Jq8N*JV&`?O-u>tPa$Pl5&tC[FE)>=rG_[S%WZB,F8Gq8p-PUN:&4Sarr)otp\t-krr*B,rr2rs +s8Clp_o1+(rVlcrrVca&hS@%H`59F0`Pqhr!6+lSrl#Aa_ns:3_T0O3aN2B@`5MYms25_m`5K[1 +aN_]I_8*t4^Vde$`l,m:`Podp_]-G3`lH-9]Yqh/b/V9:`PKC`s8W&srr)]UnGhYMrr3]0r/5g# +DjC.pdm.YkDK0Z8E,T]8rc/QhEH5r=CcYpVPE_>tP`q#Yrdk`7KS>&.KS>),L4Xc,Gt7T*s7uWo +s7?6irsnu(qWPZ*\?;=gp&Fsis5EtWrVulns8;j'qY$k\R\Q\DrVunJ~> +&HDY"eRMd)\A#r,dEK\N`l@#Zs2lA'`l#^6aNDZI`kB#s>ZZ!UaN2BDaM5I/bg"DT`q[XR`rF+. +b0AA\Uc*=KIXm?/JV&K"LP(22K7\`5OcZ$!PEhD];*8`.E,olbqXXUZoC)JCp@@hLrpp3`p@eL\*;&t!p\OUWr:os\o^DA?im6uC +aiDKBb0[i9aia.ps2t8\s2m[L`l?*AeT,B&Aq&@]Yq'.%Df'?2F`qhBC2S!.DfT`9C,fCKOd)3$ +R@'"iKnY/3JqJW&ItN8tLPUG4D(sJccH?+,"3/=!`q.:O`XTi+^R8:l4%2T@^s'g?grT<2rQ#>g +]j"-#>].^Vs8%6~> +#5e>us5W5#rr30"q>:0ks5O%WrrE&tqu?WsrVH?hrr_iCmdL/T#lOPus8W)oo_8@bnc&Rg%/dq@ +I#!K'I>`Z3Ljo;U'8(mkMOBirQ^O5(IlDUmDKK]6GPQ7iG&V\G6`KeRH\/8=W:Bocl2D(jrVcTN +`Pf^Fr;HZprWrQ$q"2FYH$+9/GQi52EcQ5DqKF(oZ,G\KKU +EdiFbHusLPF`hqRG'8.OE,orAHus'q;eU5qFaT1uo`+mhrr3)am.gSZs69Lns7lWcq+d`f9'c2^ +8:#,rq/Rj(Df9W9DfSEeK9_ghQBmbqM1^G6KS+r/K8"u/LP^V@MK_trr;HHirr)lerqud(l0@m8 +i;`iTq>L?nj8T#W!WN#rqZcutrr<#trr2p'j7DNlg]. +#ljo'o;A7cn,31brr2rtir0#WrVl]o%K?D-qY81*YIsK)s8W&orrN)rnbs'rrr;i.;0mnMG^G9s +Knk*TJeN]cKSYt\P*MB"OFB*3EG]c4DKYnsrG`?kDfoqbXSM[L9mrVlcr +s7?6irso&+r8,0!\ZVY"rr<#rrSdbUquQcqqZ$Km$N9+YT:V[Uo_ngiJ,~> +&HDY(hK)n6W4U'rf$V^\_oC]W+O&!L`P]U4`llQJaM#3B<`3A3a32TG`k9%*c-akY`Q%Ji&&cZ? +e=o-EItW)pML^G8Hi8R1Jq8W4R$X#&R$Wq_1imMJEG9?7rGhgT&8c<#J9]m+9A"aMuBL]tVV2m`>FJ +8'&iqaMu3=^X:'Q23X[ke(UHPDJ4*0Df^&EF)5T/CMe!1DfS?aJ!$%^R$sA&LkLG8K7ec*JV/Q& +KSFo3L1iU"ccO)GaSspsO%`?8uMH)c$92`4iXAMP^=FJoss7h*~> +s8;os!q5+*rr3,uq>L?niVriV!<2ups8E)uq=spg#g;]"s8N&tq>UBn!rMZbrr;Qgrr3E%rNK4T +KnbJ7JqJ]0rIbi:JqJ`6PEhDtQ^q?jUC]8S`JrS:Ps8Drrrr_KOq#:9mkl)(es8Vht +Dl&58q3supF*7;!-Za9HEcc>/7"^J`PEV?"PD=jDKS>)3KRnf/Ljt,4KR8GHnbE%^r;6Kns7-*e +rs\SdlgsQ/s8Vrpr;ZfWrr)isrr)ckrrrr7K~> +$NL,)qR<,sj88fSrr<#t!<;'X!rW#rrVmE-s8DutqtB?DYHdEhs8W#rrrE&trrN,tnbrajrr;`h +Y>Y@Q"c.SWJUrIPJeN]cJV&]?PEV/pQ%siHCNFK;C2s2krG`?cEb9AgS+to;Wh!&Zs8Dugrr2rs +rXJo,rr;utrSYZ4`7=hbrr)orrVloT_#D7N_>qLQ`;daR_Z.M#_S=41^raEKL;LmK`P]U3_ns:. +_ns=._Rdk*`5]rsPEs/-_nsj4&PEM&nQ'$ZKJ:`E*K7nf/K8=r.JUhoq +8FZHSs8Dcm!<;Tg$30u%d(?iuV69XnrrN#qiVrlUs8Musq>LHneXZW2"M4I/s8RT~> +&H2M&k([,JS@Z_de'Q@Y_T(TV+O&!L`P]U4aNM`Jb.tTi:fUSp_91$C`P0+.c-OYS`Q%Ji&&lZ: +bL_qAG^kF*JqJ`.K`-N:Jq8N+M3=*fPEqMgI5,GUEcl/nEo]5naZ5@ +naGT3mIKuJeA/ukp[mtGna6>E!:g$Z*:iIgoBlARmE2o_nFuMCl-J_JaiDKBb0[i9aia%ms2IRM +b08#L`P]I7e^9RbQ#gKpKfNX\EcH)?F`hbBCi4'+EHQ8-6%FiTOHPosP_OjDK7nl0KRnf/Ljk#/ +Ir]`jdEg%\`5p%!aof`)`Q%Ji%`ZQ,[s(V15Xo4oaN;cId`;j>aN0`E8PN +%fZD+s81X.s8W)qqY^BniVriV!<2uqrr3#qq>L=!c0a`gs8Dlkr;Q]tr:fsbs76-us8;fpr:.3k +I>`T0LOoGYre1<*s+Co8OHu9"Q^*8ZC.i\dDgH9rEY!,6DfSd%mUVK_>/L.5rqu$[$ig2(qV]?2 +`7=eas8N!As82T`_M4G1Ed2tVF)l;BG5c_%F`DSTI +#ljl&qoGG,gA1aH"TJH$rVtmV!rW#rrr<#t&HDb/s8)HaSuo3Mq>C9ls8W)ts8N-!rUKjrs7uQl +qsh-jI>WH*Kn')Srdt0&s+1c4Ng,ioQ'6iSBhEJ_D0TjpE;abeDK]l:<."%COK)Buqu6Wqo)AXg +rr*B,rr2rss8Clp_o1+(rVlcrrVc`shSB-.rke]Q!Q;nT_Z.IP_A0u*`4X18]oA&0`Pfa5_Sa=0 +_SX4.rPB5h^;e".ZB'X/bK%?2_SX71`Pf[n_ApJ1`PfO)aM=U0Mlb"9^;@\%p&G'jrr2lmk4&E= +rr2rqrXf,/s76-gpe[Z`;pTtqEcu6qE;sniE-#o9EbS0\Ko_OcP`q)\JV*lR'7tjhKSOr+KReo4 +LdUh7q>^Ens6BRoqu?Wg_RR(`S]^g-rVucph#@s*t~> +&H2D$lC2-bO1WHVd*9bS`5^fX+O&!L`Poa7aNMcJbe^p'<`N1_]Z/49`PKC3c-OVR`Q%Ji&Br#1 +e'6('3cg+/MMd(AKS9>Ws+LE)%t]k-Q^*l$KS*i,EboW=D#JAOD[pu/Cd_jc:P>E2UX.'-b4n*ff:oCMMB +p?_PEpuB&jaS>Juo(DPArUKmY*V&Odp%.eRo$XeJg%k:/mc)RZf?)(S`lcZA^<+Oda>1cS`Q63G +b/hT@bIl*QgH:Rb6+q82CNF<3F)uJFEGo]1EGoi>Cee`"NKfZmP`CKMKDpQ(K+`lmM1L;7K8P/+ +/CrIpb/DHBb5TTdb/VHia:5k`@nSmM6@ZYda32QGe&Vs?`kI7-8PNNgk4nuQJ,~> +!WW,trsIN:r;ZfpqYgHorSdbUrs8W%r;Q`rrqlNirs7NCmcjcNqYC$frrrDsq#:jM-qu>p[$ig2( +qV]?2`7=eas8N!*s82T`_MnmMM$Y=JZGm8G7F`qqQGlDjr +HZsUP8eD@;->%.:H[Bf4E)$$qD0u)!'QA89EcY,_Lk_(^RZrhfJ;/i6KnTGX%tTFcLkLP1KKSPqs8;osqW[tZ +r;Q^(kO\<6g&M*IrVc`qec,RGs8N5fkO%Wsrr3#us*t~> +&HDb/qq%L7cM7D/lJq/N/IY39)JqJ`/Jq\i3Pa7GrP(&+$6ud-`ErBtVE=d))EHcA3A[Z'HN,8Lnq"t*^rr2rs +rXJo,rr;utrSYZ4`7=hbrr)orrVloT_#D4Q_SO+g_u@OP_>V4`]tqh5O,9*Y`l,g4_8F71`5BLj +_DB0I_8ia9PEhQV`50C2^r442_o'=,_Sa@1]YMV(UPtM'YJe/k`P97^s8W&srr)]UnGhqUrr;oq +&HD\.s8;lkb>kI+=G'LfBm9Jorc'-#G&M>>:g&O+OI;K"NJ;q7K8"u2JV/T*KRSZ*Jp2c,lMCJZ +!W2o^rX\o+rU%2*\$MRhrr)lqr;GURs8Vimrr39&p:R,iStk'9rr7K~> +$N'YqmB'o$K>#@NrlYA``5^fX+O&!L`Poa7aND`LbJV*+EDK__\AZS1_o'I9bg";L`Q%Jis26A1 +_8t-KIRes?M2-qEJV8]/K7nr3K8,&7Q'[Z!PC/""7<3?fF`VVDEW0kgEH$#@AlDX- +s8N9$s8Ud.mf*4hrr)lsrSd_Us8Drrrr`5tqYpKo&Gk,Lj8]/VqY:'is8Mfgrr;Ke-3*o@qu-Ei +MI)0gKnP&2KnY24K7no1KRnZ2O-5rtLOaP7DffmlEY!A5E,eO(9q\@ZhtZsEs7tpY$ig2(qV]?2 +`7=eas8N!)s82T`_M +%fZM,rT'fI^%hX-rr)lsi;OJirr2rtrr)iprr2rrrq4m4YIaH,rVlisr;cirrrN-!o):!7s8;in +s8DqR>`!f[Jq/H*K7\Z*JqAQ*It!35OI28eIrmqmEbtYmrc&KgFDc&<9S?$/UJB_CqZ$Tjo)AXg +rr*B,rr2rss8Clp_o1+(rVlcrrVc`shSB-.s2+cQrk]Dd^qde'_Sa:-b/KF(PDkaG_o'=+_u@UW +`59@,rk]kia2PTKN0''fa2c-9^qn(1`P]R._84"+_SO:0V2L=uOK&5qs2PM`p&G'jrr2lmk4&E= +rr)lprX]&-r;ZflrGd^kAXYMnIVA\!s)J'X!H3)ZD^%)cJqArFOG\dGJqAW.Jq8N+K8+l-H@^m+ +7Gn.Fp](9es8MutrU'Rpr;ZfS\[JuMUA+Wcs8N#riVrlWp\t0l#lO1qSt2FHjSf)XJ,~> +&,Q2#n\AsAEP9TAbfRuI`Snol0a32K>`Q$'Ebf[oD`q%1t`Q#^0 +_TC*VFAR[?LkgV:KS4u0JqJ]-K7JH.Nff`pKRIu/DKBaqF8p7ZD\6u9EG/lFGX\!g3P!8Laj\>R +o>i&o`Q$-GaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[Oh+r:L$\!:fpW&bPhto!lEL\&%\+nF,u@ +nEo]Dnbr%jlM1,=^V%J!`q9'#p@IeIoDS2$n+#l;naubPe[rE,]A!#Ro((tim+9A"aMuBL]tVV2 +n&PXO`PojFdQL#0kYcEF*2PDD/F94E,oo:E]JW)Ko_O^LkL;-JV&K(It36, +MhQq9Jqnk7^!Y-@a2PX2aND`Obf]Fr&B`;@[=V%<6UsqY^W"I?bKAebs2OrWqT92^X(+t!94Gs5 +qu?PD~> +s8N9#s8Um3j8Ju[rVuinh>[BQ"9&/pqu-O#f^.Yus8;`hrr2rtq#L?^r[.[Cs8;omp&=f!ArMY" +LP:A7KnG#2KS"f3LPCVIR?2rOMD00gFSKkeGAM>:5F5ucJ<'I)s8Moql2D(jrVcTN`Pf^Fr;HZp +rXf,,q"2FYH$+7QG'.qNG'J<3H3ee>F`VP@?6TgW!!3O;FoH\0H#mtDEd2nXH?sg`B2fEB!X&WX +Ble<:F`MYGF*;hTHMr+&F'L@(!!WE16>h$iD0_)io`+mhrr3)am.gSZs69LnrVlilr;Zc[9W>$^ +4B-0?q/R^$EcH,<2M-C9OHPTXKS4u3L4k/2KnP)0J;B2;J4[9Hq>^?js69LkrVuo]mIgA=k5YJU +rr2rVrr;orrr)lsrqu]orrh?Clg*a5s8W(K~> +%fZM-r:@(bY4;Dhrr)lsh>S&err)fprVlirs8Di^SZ9*[rVZZp!r`&qr;Z?e-NEuCrr;ojs8->; +M2-P3J:W?*JUrE)J:NB.KSGPSNdcP8/ot`IqJ[$dE-,i9D*=+mX*fp's8W)qs760gs8N!,s8N#t +rr;rT`P]XErVc`p!<)lr!T(Wk_uIUR_ZRcn_SZ;f:r1#d`5Tj8Q&greQ]fD,_nj.+`l?'<_SEq% +^r"72^lOD>Q&;-Tahkj0_oTg8_ns7+_SX(*ahk'=MNj6cXM_uj^;Rk\s8W&srr)]UnGhqUrVuco +s8P(Sr;Z`Z8uJOR3)OF1E,T]7EH,r:EH,o9D)?cjM2m[UKnG#0JV&N*JqSf0It!-1Isjbop\Fje +rVulr!<)or!<;Qf$2skL]!Sf@]Cu4%rrE#Vrr<#srr;rsrqud%qr+BCSt)eKrr2qJ~> +&,H,$o@84j@^X8$bK%`Ha5P,>aoKN]`Y-A7bfn2M`PATQqh7HW,Qb%b/hZGdE;(% +,0%UAbfn/IaN2E@bL4JB^Uh&-bJq]Ia2uKMgsXsHoCMVHrq$0[!:TmVrppirrq=4>]Y25!p$qP? +oCVP>mI0T8rUUQsna='#`lc'>p%\.LoCDYTnc/&"mI0N5o_S.0]Xbnl^u5%`n*/lYm+9A"aMuBL +]tVV2n&PXO`Poj +s8N9#s8V$:hYmHVrVlcmhZ!HQ&H;V*q>^?ls4cf#pAb*er;Q]q!rMfknGXg5s8W&qs8Viglq)k] +M2$h;KSG/5KnY27KRni/JrG_IIt9RtF)u?sEXm&0E`7BSWMiG]qYg?krTO4gs8Domi5NXQeboCG +rr*H.qtTg#LO"#`F`qnMG'J<2H3eb1LdEI!Mmo`+mhrr3)am.gSZs69LnrVu`os8DroOF*[I +N$`C_q/Rj(E,p&;6u[p3KS>)3KS>)7LkUJ7L4t56KSP&5:VZf*s8Dups8)c[rX\u-s5WS?qV_;O +s8;]js8V*X"T8/or;QWo!<2uqs8N&u#3P7:l0nZNrr.E~> +%fHA+rqj1"V!7UPrr)irh#@1-krr)cnr;ZBf.0'2Es8Muss7uKX8V;JG +JV/H(KS"f.K7\c.ItN9%MN!@>Il;.`EGt_n&92Z+EH5$)6)CDKo_eaerr)Bdrr;us%KHG,s8N&s +i5NUPec#IGrW)oqrs%>q_o'F1_Z%IQ_Z%A*^r""-`lH)eNKBa5`PTR2_Z%@l_ns:/`NYJbP`C`dWkHBk`5KLbs8W&srr)]UnGhqUr;Z`p5Q1WZ +s8W&sr/Z,oG).>WDfBW6E,fl:DfK]7Ebe!ZKmnW+Jq8Q-K7ei0JqJc2JqS`1IYLV2qu$Kns8;oo +s82fqs7-(!s8;f6]<\W5h"UjKrr;rqir8oVrr2oq!<2uts8E<#c_@/*S[\Iorr7K~> +&,?&#p#Cm6>-,Q\aN)BDa5P,>aoKN^`rF*kb08)Mb/20/?!(6Z^;\"0aSj6`aMl-iE$_T0U3 +_oU6HdE=1_Fb5=(JqJc0K7no1KnFo/JUr`=M10t6E--2BF*%;"&T;Z2FD+-`4Jnc-d)sDKaN;Tq +a)0 +JV/Z0LP:D,H9A(XbfduF_T'I7b5TTeb/hTBo#M<`d))V\5r_G,PIJZU`lS/%ilM/>rQ+cV#ekmd +;c6MBjno&WJ,~> +s8NQ,s8ViHj8&`Trr;orrSd_Wr;Q]nrrE&sr;Za&s75"1lMpn\q>UBn!rVrnl2CtdrV,hQKS5/: +nUq-tL4_F%G&DL!EY!/1Fusl&UM["#s7u]nrr;6^$ig2(qV]?2`7=eas8N!.s82T`_Mrr2p"kj8*Drr;!W$N0WfX/\X6;0?o"rc.sY#]Xd/D0'neE/"+@ +s+^E(#DIb`K5tZ!r8IV[qu?TRn+ZP/rr3-#qu-Qpir0)Yqtp +$iU)(s7k*6Vq:_CrVlfsrSd_Us8N#trVlcss8Mus"o?'-ZbZ>7rr`9!rVl`poD\[frVd$$q=-t- +JV3HD#ChGZ2J[DNFSTkdDfBbXF+^*#W:Kubs8Drso)AXgrr*B,rr2rss8Clp_o1+(rVlcrrVca( +hS@%H`5BL0_ns=.rkT)^_8FC4bE\0LOctoiNlM%7/]5TKahbs:]Y2)$\sSGBP`q>hRE3@b_nj:0 +^W=.)`kT@.`PnsBP*_;iNf0n9`!s]'_=dj.rVlfpqW@;Imf*.ar;QTn)#j4tW2;n':2t5kDfBZ8 +E,KN;CiX\aDhIt>rdt`5JV&K+K7\]-JV&GkBD2<'rr2rnrr<#grX\o+jh8=8Wg`_]rr2rtrr(jU +rVllsrV[6*qu?Tns8Vi,US46R`Vf]7J,~> +&,Q2'qW4e]?CJaO`Q?3Da5P,>b5]Q_`rF-[aqi4DaMu66ISs<`\]M_+aNDZHb/hQ@`q.7``l5p: +`lQ +^Tb>c`QZ0=oCMMEnFH&5o]tr;m-X?9p"?me_SX()^Z#%_oC1edm+9A"aMuBL]tVV2n&PXO`P]^8 +rQ5,]qo1G:f/'+s5B086F`qeCCMe3:E-Z2;F?XPpKnkG;K7A?"K8"r1JUrH+KR\Dm>YEMmbfIm) +`WF6(b5TTeb/hTBo#MEcahrp-4[)J2ZG=K$`lZEHb2UMB`rF-YapuV8c,[oIb.):`:JtMam/?s7~> +s8N<%s8W#MhsgXF!WDrRrW2rrr;Qitr;?Qns8;os#Lr#&s8W&nrr2rtr9!t^qteT+LkG2M#D[hF +6$%$gD>A2_F)XI8;l?9io)Jahs8;ool2D(jrVcTN`Pf^Fr;HZprYkh6q"2FYH$+1NF`qqQG^4UX +H$44EBOiD!!rW*3!Y8pcG'8"LEH5uFD/t/IF&rr2p"kj8*Drr;!Ws83)%B;^])5]cpFs)SNfEH68;Ecu.tA:=9,s+^E(#D7_bL +I'esrSd_br;ZNWmITl0s8)cqqu$Hnj8K/YqtpBirrVuprr)j(m-EltjT#8Xr;Q_H~> +%K-5)s8:cHUWE3/rr<#UrW)utrr;rsrr<#trr +%/Kf#qsD()>Dg,5`l[)Ys2tA_s2P)[r6#&\&](2==Ce_N_SsU=aN2NF`Pojga99N%`Q64$bl>`h +a31D2H%(I$o7I="JpV)nE,]o:rH%pW&9MhMO%Z+26Hmp$aO//N_T)2g*lc1=bfn/IaN2E@bL4JB +^Uh&-bJq]Ia2uKMgsXsHrq$0[!:TmR<9`oCoCVbN_ns.!]u.e,^\70cn+6/>mcjB.o)/(SjLqt5 +_nNn,`5hK>nac,;n+5c6mI0i)_"Nng*`PqAg&&ku$8NK%.@_'FsaN2KGb2LGA`rF-YapuY8bfIrHagbbN9NG`*nbrK<~> +s8N<#rr<#RhraqGEd)_EDGqDRqZ%rK/Sf?KH$=IUGBS=ZEcZA11_9Wf +!!!-*!t.G4F*;bUNR[V#rVlfr"6f+Hrr2rWrYYS*r`>Yh;*f/AEH-&@EH-)FE--8E5"C\0LA6E+ +K7Zb4q>^0_rqlWarr2p*m-X01irB&Prr;lmrr;$X"8r&nrql]rq#1-j$K^X;k2ZLAr;?QoJ,~> +!W)fprrqkiU:0aorr2uri;Nr\rr2lprr2os'`S(0rr;rkT<,N2U""s8McmrV6BloD\ahrr*B,rr2rss8Clp_o1+( +rVlcrrVca!hS@%H`;@IP_@af&_og!@RYm2hP*;#gNf1oprPUk<`l>d4a1fX-O,B*eQ&q)jNg[u- +_o'=/_o0I2`4j48_l/ZTPa%>nNfT1"`5BL2_SPpFs8DrrrVG[Gs6]gas8)`mru:Y2 +&,?,'rU\BS?Z`]na2l?A`n&60aq2J$=&iIp[)U5/aMu6Bb/VHla:QA1`QHHOccjJL^r=Mh>^qS# +K*m0YJ6YQ]Ciji?EW'tYE=cu)1ff=&9;^.X_9C0Dahu-ia<8LA`luZJ`Q6-@`QQ]N\\G_fe]YtT +b/_WHceQt'nFQ8NnQG>Jlg*s-mIL)Gq9-Ca]t;"t_o0@anF,i;oC),9lh1&Er9V,(\%TMi_oBO5 +oC;A?mdBK1n+$#@HrQ%%BaN2B@`PopA +ha*9m8NLX.Ec>u8DKL,KDf9N-1-LDDK8##3JU`6)LP:A3It<0'IWdWDd*KGIb0'S)"j4p-`l5pf +a9or(Z~> +s8W,rs8NDehr"J6r;$3es5EqXr;QZp"8r&nr;Q^/rqZToi829O=ZSEVT;(rr;rms8;-\$ig2(qV]?2`7=eas8N!'s82T`_MpU-kr;[!%!X03LEr9tcFE;\KEbS;b"U,#-!%7pL"tOJ/Fa81TG&qtPGB.J-3=#Zk +"98E*!!!9iCNXlIIuVtMs8Drrrr_KOq#:9mir0ems7OlCUR"\]FE)8?EcH,AEccJKA5,75q1e]u +s+U\p>ke0os7cNir:9jdrsRoXo'b'-s7ZHlqtpBmir8uU!<2rs"TJAprVlcq$K^[@j6$CArVZZp +J,~> +!WE#srrr>.UoEeZrr2usi;No[rr2lprr)j,rr)fps8Mc'V68&7s8N#ss6fmcrrE&tr<`K's8Dur +p,R\Qnq-mo#(KB0E-6#9q/?mcC.VX+LMutarVlipq>^EnoD\ahrr*B,rr2rss8Clp_o1+(rVlcr +rVca!hS@%H`;@Fc_SaC0`Q-#cMiNsbPa.AjN/P]nr5:_;_Sj7-_mbYbPaISmP*M2jR`NIc_ns@1 +^rO4-_ns9gMiX-gO-,N_OcQQ^_ns=-_=dj.rVlfpqW@;ImJd(aq#:6l)#)Q]Tp&,PEc5l9EGof: +D/XH:@S8h,K7a)Rqh"`u#_[nI>PJ-qs8W)trr)iqqu?3cs8387\\#>=nGWCdrVuoTrr<#urr2j, +rr;rss8MlhgnUL5TX4:hrr2utJ,~> +&,Z>*rq>?)@UlIRaND]E`n8?4`r='Zaq2S(FAl@nZ-(20`l5s?bfIfpa:QA1`lu]RccjDH^;nII +,^On0K*m0YG=FK+EGKN5EW'tYE=d2*6r]\$JbYnaPSbm+9A"aMuBL]tVV2m`>@HrQ,#]rl?)! +`Q$?P[R$.<8m6:TD/X?3F*D\HEG\`?0Pu8ire2,?JV/`5Kn4`'JUrN-@Rntp_og!Abfp(2s3(Pe +aN4>"o#M6Y];\Li4\/)I^raaAh8oW9s2b/]&'W#5`Q#d2SlJBV>(kZ&rr2qJ~> +s8NQ,qu-Q_gu8;5qY9scs5EqXr;QZp"8hoir;HX*qu$KnfC8&)s8N#qq>'ses760hr;HWors&2o>Vs8N#srrDu]rX8c)rVGHk`5L4(rVulr$NL"uoYQB/ +F`V_Lr-/KjE-5r%+qP+`qu@c="VG?dF)uJIG'A%NF_at`"T\T,"9JZ*!!k)hDfbo%*d2jKFE)D2 +/.`!d!!*0%!!WE-5&5:dH$t\%o`+mhrr3)am.gSZs5O"cr;-6YG*&V58p#)nrGi0bEHlPH9:]:5 +q1e]u$&+$pB_VE(p&G'frqlWarr +$N0o&s8W)9U8-WArr2usi;No[rr)cnrVca+rr)cns8VuRS?KNqr;?QnrrE&trUKmes8W&urVld% +s8)cqoR:8'KCa[#K8+Y>?2oAXs8N#srrN&toD\ahrr*B,rr2rss8Clp_o1+( +rVlcrrVca#hS@%H`5BLl_@si(_nO43_NB\6Mj'EjP`Lc`NQ1t95Jt@U`59F/^q,)VOc5KcNg5fi +OI=2/`5KO2`5fR,_99]^LlRUXNg#N_P`q62`P]O0_SPpFs8DrrrVG[Gs6K[_s8)`os8W$(nop.j +@7>6WE,kkr%<63*DfJ@<=a5RNJq8LMK)L<-Jq/A1Ab>j!p\4[as7-'tqW58u^9"L2rVuoss8V!U +s8W,us8;rsrVmE+rr)N1US"6N_tj91s8W(K~> +s8S$aMYp7bg"<"a:QA4bfn>UaMu04 +aj\[P=b;4rK*m0YD`Up$Dej30EVjegFA4l`QpSU5b0%fLccsJF`q.7q`l5sAbfIcEaN)9Cd`Au6 +]"?M9`lcHEai_rbdbF9_oC;AMmoSoFn*^&LprL7i_8F+(^Vdt-_=mBen+6/>nF6)Fp[Yc/_nO+- +_8aC-^rlHEoCD89lga<3pAas7]thP$_oK^3`kK+Aq=O4Hj3R)DaiDKBb0[i9ai`tkrPnlYrlY8^ +rPff"b#j(_@S(QXCi=<5F*)GHChPqi8o&g(K8#$YK+j#oK7SN%JV/W*0iZ]Ia10.1b0'_-s2tA_ +rPnBK$,Np*8j>d3@(4)Qb1ar8b5]Nla2>j6]STW^9j+(OpAFpiJ,~> +s8NT-qu$Kig#`86q"FUas8V*X!W;rrrri>sq"Xabs8VurrrU^;k5G;^r:p'brVuHfs8;ips8N?# +s7Z-clTp*lKEm3S;8#/6Ed@J$%sUQcYBklsrVZQfqZ$Tns69Ljs8Domi5NXQeboCGrr*9)qtTg# +LO"#bG'F)uACF)c>GEc+2# +VG?rAq1Js+LIniKs82fqq>U9ho)A[h$0LjQo[Ws@s7uQkr;ZfUrW2rrrVm'#qtKsbrVlg#i8j1i +hu!EQs8E#uJ,~> +!W;rrrrrDNTqTX(rVllriVj#\rr)cnrr)j!rr)cnrr35pR]UBuq"k$jqu?]frr2rsrXJo,rr;utrSYZ4`7=hb +rr)orrVloT_#D4P_Sc8f&BD]-O*Q>:OHG]iOcGH`NlV.;rke]Q3l\tNG'o@1N/rsYP`_#iR`NIc +`59I1`PTL5_k)1%Mi`gTP`UcfPEDrc_SO1-_=dj.rVlfpqW@;IlMge_q#:6l(Zn/cU-iU3EcQ,= +EGof9DJMJnV+cPpK)C3!K)L<-Jq/JAYkJ(os7lTis7-'os2_p^[@c1JrqufRrW)utrr;osrr)j- +rVlfe\"]IcT\'&>rr<#tJ,~> +&H2Y.s82,`Ala>maihrK`5^`VrQ5/^`r3jh`lQBH`j8KE?_#']`kfL1bg";uaSsnFc\RqQ[KM`5Ka8_oKU- +_T_lMo^_G +s8NK*qu$Koi9Bb2q"+=\s5O"Yr;Q]q"TJ2jq"t$i#Q4Dqs6Jb0oD\alqtKj^rVuHfs8;ips8W,s +"TSJpCM*$g#$m#T6?$j]q/QdC8Z8FXqYL0jrr2p!rVQWZrX8c)rVGHk`5L4(rVulr$30ntoYQB/ +F`hm*GQi85F(?[1rW)ouqu@07@W6C3G^4U^GApas"TAE$"oJ?6#:aA(EcuSLF`DbIB0H_)!!!'* +qZ%$05](XgG'o;!o`+mhrr3)am.gSZs5O"pr;ZWgp5XNpHVn9nF)c8BEHc;EC.J'i6huK4KEm*b +M(u(,s8)]oqu6Kjo)A[h"Q/bDnCdg@#5nAqr;Q`rhu +!W;oqrrr;`WM$ZprVllriVj#\rr)cnrr)j,rquZkrr<#lZCeGKp\b$hrrW,qqsj[crrE&rs8Vs# +s8;P(A:]C)JdI'_?AJ)Wcai)-8_Z%A5^;%7,I!L6qO,o6YOHPcfRE3Cd`59I2 +^WXI,TR(s7I#3oGOctoiP`Vuc_nsC1_=dj.rVlfpqW@;IlMgb^q>UBn)#a8jH(B+T@W?F,EH,o; +BldrWp[LS'K7a#Ps+:3%s+1N)K7bbRp](*iqu6Bjnbrpn^UghSU\Fcdrr<#Qrr)fmrsJ`$lDgPL +S>tiOrr2otrdX~> +rr*B,qru(>;e):ar/:?`P]U4`lQBH`jfe]>(OZ@`kT:+c-OVVn]29aaN2B@`P]U1 +`R35f<*+Bso7I3rGYibN3rWjpDfP\r%s;#GTT_"Zc-+/Ib0A8S`::ni`l5sAbfIcEaN)9Cd`Au6 +]"?M9`lcHEai_rbdbF9hoD\8\oCVkO`jiFgaj%c?]tM>&`P;-9n*fl>n+-,Fo!Q!;_8OXDa2Gp6 +_S=Cnq"F@Jmd9E>q"W[U]"P\mai23<`4s!sg\(1.nDhj]f?)(S`lcZA^<+Oca9g#1aMu6=`lQCiFE:Ec?8?E*P6Zgb*euJVAmXKbB#hIsum"KnP;8+cO^g^;Iq0`r='Z +`rF$X`WF6(b4 +!WW/ur;Zd$kNh@3rUosbs5O"Yr;Q]q"T8)jq>C3k%fH5#s8Us@jo>>[r;$-crVuHfs8;iprr<#s +"T.jeK8&iK#Cf5+pLRQMF89he:3s'YVY^5fs82fnqZ$Tnl2D(jrVcTN`Pf^Fr;HZprY>J1q"2FY +H$+7SH$FLUF)l24/e/$crW)s%!!<*!%0p9XEclVPH?jI8'*&78!!33(!WE'5"Xn#$F*W"SF`VD7 +57n&!!!*'%"T/6.#=*-KG]nCmeF`e>rr2p"kj8*Drr:sV)#F7/s78saV`e+"F)Z/AEH-8B@;#0, +oS<:-j +"P;c&kO8BLs82lsJ,~> +$N9o%s8Vul[@aAmrVllriVilXrr2lorr`8ur;HWp#5QoAZ+Ki,rVllsrquB4c[E">N_X(nL.rr2rqrquWms82Bdrr;us%KHG,s8N&si5NUPec#IGrW)oq +rrLulrkecR_>_=O_c4RlNd,_pJV&K5Nf]?bP*:pJ`l5m5_8*t)\p\XOIPnC!rr;usoDejh!<2utq>LW\_6LSQYP%nns8W&ss5EtT +rVQTrqt&kIU'.!op&4gfrrE%K~> +&HD_-s8DEAJl,O\ccaJN`Q$oYr6#&\!64uV'#r#8b/q>_;HRYK`l#R-`m)iPm)TUT`P]U7ajAYn +4*>n$o7IC"EAQ&&<_mROEH1qu&TMkfH)+JqdEKYO_og'?c-+)sa<8LA`luZJ`Q6-@`QQ]N\\G_f +e]YtTb/_WHceQt'nFQ8Nnc/2^o_A=]bI4pq`5TU6`5'7.`P]=]nF,i;oC;JKos_0B^q.S,bKe2J +_nj(4qtfsWmdT];pA*IS]>;A#]Z&"3`lPm-]%ZiKnaPSbm+9A"aMuBL]tVV2m`>FNs2b2Zs2Y2_ +rlkDb)p#k7`7!-tU80\FC2e06EH#rCBMqXUgY@"%KD^K+KnFsUIgq$cNIc^n7FfT'`P][6rPniU +!QN4[b5]Nbb/hTBrQ,#Y'ZeG<\qj +s8NK)rql`ql0IO1s8;fos5^KAmd'`Krr3&trVu3_r;Quur;KcBKnB,R ++,59!JqJK/Ir/urpk)IaEHH)@E-?5@<(sEdrr2p"kj8*Drr:sV+8c*rq#:3jrs\o,s7PUJq:GZHqtKjarrW2tqr.PQs8N!!r;$9h +rs\;UlfdI%s8Dlmr;Q_H~> +!ri5trr32u_kNpcrr2osg]%0Or;I!%rquAUXgdHirr30"s8W&ss7?6hs8W'!rVlfr#5e8q<-EkE +q19oIIt`K,I>WJfC&%IV;/gGoCiaK9DfAWFVjgWXr;Z]ps8N#rrUBgcs8N!,s8N#trr;rT`P]XE +rVc`p!<)lr!T(Wk_csmn_S=(7_Sq:YG^4aeI=@!2OHPchPEa1_8=:3S9K+&GC"O]IYa)MP)trkY/J5o_oBOcs8W&srr)]UnGh>D*rH!;qYdX.V1_0R +F)H);Ec?)9<."H@_a]-.J:36%rdt'#$A*qZJ:g&Kp](6lnc&[gqu-Kn%K$2%rr2rpe@3-*Ra^m- +rr`8ur;HWpir8rUrVlfr$iKeuqSB#'SY +s8O_T)2grl,Gjbfn/G_oTmGhEbn' +I=qBM-&-o%J:i9/HsTe'e7CdYE-6)BEHuSB;+mgK4O;3m_SsO;bfn6!aF2(I`luZJ`Q6-@`QQ]N +\\G_fe]YtTb/_WHceQt'nFQ29mI0NCrl?h7 +ccF)TP#S*,6Z@$]Eboc=G%jBMdG(HXIuB2:NJ*.DK7SN%JVAl;KS4_)aj&)M`W!mV`W!mWaSs=) +`lQBH`P]d>b/;38bKS,5CHasT6&iM!`P][;dEfeJ`oG,Cb08#J`r=$h`l#a8a2Yc<<_l=iNp-E= +s*t~> +s8NT-rr)lsoAo$$s8N&ss8UOH#5nN$jQG[qr;Zfp!W2i_rr)j%q#C*?5DY#Fq1Ki@Mh?P3M1("2 +g&L]3:iUMtF),r?DK&.0Wa*mFrqZTmrr)l]rX8c)rVGHk`5L4(rVulr'*%k(oYQB/F`r4XH$jXD +?m?*aq#CBqrW!B.%VKHmH#@eD>7U]7"82^+""7o&Ed`=XFCd?@"pY,.!VcX'"?UOHH?OIjeF`e> +rr2p"kj8*Drr:sVs8O,:s8DRuT;PXsG&V;:FE2/=A:"%GrB,+MM2?b9JGY$"K*Ha^Jr4;eqtpEk +rquZqqtU'frr`8qp\t0l%K?>+r93\BmFVCC6lJ,~> +%fQG+s8N&se"<5Wr;-Hjd/FUVr:dXqWn7:MrVZWns8W)uoD\ah!<2ur$3'u#s7k/.KnP$QJf]K$ +K7JQ1I=a'$s7MgVE,]i;Bln?2Db#b_=jHjCqYpNprr;rdrr2rsrXJo,rr;utrSYZ4`7=hbrr)or +rVloT_#D5U`P9:4aMPlVIX63aH[0mbIY[HQ*W5s8nm@l]:LA6aDJsW9 +BlIO-q=j_DC3YDbIY3.LK)L<0JpN6$LM(c,s8Drro)AdgqYgBm%K6>(r;6N]^q@4aT^;UUrr`8t +r;Q]qiVrlU!ri6!rVm6'r;HN!U7\$MdJWnAJ,~> +&Gl;&s8Vu`XAhlWcH=>I_oC-G&B;]*H"^;7b&_SX4i +`@f!?bPUr!naQ&DqU`?m`l?*F`PB=,`lH'8\[U,ap@Ie3cg99*a2l9Cd(R08b2:8tb08#Gc-4C& +OJ5Z]F)5Q/G'.V<;cq;df-Y0\Mhlq@Knk;5JU`6)LOkM;Jll:0d`TPKa2e+trQ$2*aMu6Db/;-< +b0%`D_op- +!r`/trr2rt!pAY&rr3#rs3^iFrsShXlfA*GrVuooqYfUV"o\=AC41m3KH>MoM1^D4F^4eCrJFBp +DJsZDBle6*=KRX"nc/Ldp\Xsis69Ljs8Domi5NXQeboCGrr*c7qtTg#LO"#bH?jdUBkJq'#R(;4 +!<<*&qZ%oC%V9j5H#dY,$NgD9!rrB)!!*'"!<`N*"!_>oH[g6ZAMXbr"nhp+!< +!rW)srr3?)k,4i_qtU3fs8URIs8NK'r7[R?_"dp,r;QWms76-hs8;lqrs&DuFD,uTKDpK%KDpHE +H@^j&JV%rHp](5N:3LGjF*M>;DIlnJMeV\\rr;cnli-n`rr*B,rr2rss8Clp_o1+(rVlcrrVc`s +hSB*->/J1o^Vl1SG^"F\H['jbG'\^rNffKa_8+(+^V@L(EclkZG^b'dH$FXdMij0^QGp_]`k]O1 +S:,L+G^+X^I!^-cJV]>MQBnGg]=u>)_=dj.rVlfpqW@;Ih>SMnr;ZfmrQS3gk +r;ZN<6@F]BIYigYK)UE&Jd@*`IXui*oD/@arW)urrqZQqqtg9jrso&.s8MuqrntH%[&:V3qYpKs +rr)fprr:pU!<)lqrr3E+s8);`TUhdQl21M[rVqB~> +&GZ/$s8Vrc`*cGia2Hp4gALF-o&S-`f?)(S`lcZA^<+ORaT'@: +bfSG@5bX?1D/F67EHcS@@GB5Zd(22^Ljsf4N/*% +!ri5urr2rt!q>@+rr2updJj1G"o\K$eFVSsrrrE%q>('hl2Cqfo@Q9[NJ)lYKHGu&Kn=u1Kf\r" +qY$"HEH?5>EI)YC7%U5Siq`KDrVucos8V?_$ig2(qV]?2`7=eas8N!0s82T`_Mrr2p"kj8*Drr:sVs8O,:s8N&lHA/P0@rld/FE2AB>#4ejr;WBkK7eo4IJJO& +Jprr9LMK9LrVu]mr;6Wnq>C6l"oeDpq>U +&,lP,rr;uroX(ErnbE.]s3^fUs7lW`S$]EZrr2iqrr2r`rr)j&o%-!SM1^;0K)C6EJqS],J:`E. +3VDt@pQ83iEH5l6G]7IdSY8p=q>L'es8VEarr;us%KHG,s8N&si5NUPec#IGrW)oqrrLulrPMgU +`5KNJFF87VH$js`G^=X[I"m`JP)7#q]>)1dGBSCZFa&.XGBnIWG'\h"O,]IKaM>@,`0bakI=HEc +IW^'dH?jpiLl[UUWQ)`i`koRbs8W&srr)]UnGh;C*rl-;rVcD6KrC9lrVqB~> +%f-##rr;ogeok55[_g8*dE)@-%_fuj=D(Zn\]2b9aMu?@nAmf9bfn/I_o'^<\LVr[JUiH.JU`,t +JVB#>MhQe1GU1nbc-()hDK^5BE-ZMC6(!s'a48JN`6?6Bb08#L`l@SjIE'7Gbfn/IaN2E@bL4JB +^Uh&-bJq]Ia2uKMgsXsHoC;;=o_81![(X&b_8F4+^Vn15`lQ`PTI.`PoO%h#-d6n_qg\f?)(S`lcZA^<+ORa<\pIbK\Pf +@&Zrl-,#`l?0B`Pp!D +a2l3>aMY&q76*e"Qb:2X_nj@8ccsJI`o>)>b5]K[a:-,-a2u)e +"TJH"rVlfr#k[!-s8W)nq>A_@s8NT-s8VHFm.:8WrVcNds8D-["\Xi(L4P3WKHGqsJVer38C%88 +r:2RDF)Q/ADf'Q-D6A;FqZ$Hmr;>OQ$ig2(qV]?2`7=eas8N!1s82T`_Mp=B6C!;c]prqt^R!rVrnrr3`4r;6Eip](9] +kj7]umJm4bs8W#prdX~> +s8W,t%0-;)qSAl%ht[0Ks8UOH$N9l%qR`N+`q]T4rVllqmJd%`0E+P"H@g[&JqAW-KS4u0K6i!% +J;$VAs8W)i0i`40EcGr3EF`jeHAVLurVuips8;lrs760gs8N!,s8N#trr;rT`P]XErVc`p!<)lr +,i6>S_o0F/ai/XHHusRWG^=[]H$FUYH%:^3OGgfd^;74$H[Ym<3.67"G("X\H$XpmN/j:F_oKg. +Sp5[0H$jsbH@:-fH?jd`J;'5EXhhur`50:_s8W&srr)]UnGh;C+ohK?qZ$6L8$ALPDffu9DKKi9 +7aUr1q"KGIL4k87JUrFPKE$N0JVSQ.K76&[r;HHjq>^Km!r`,trr3Z1s8;cY^Uq%]SFZUXs8Doq +s8N#ss5X+Xs8Mrsrqud(rqOL0St2Urr;HQmrVqB~> +%f6)$s8W)kif%2NS%Ze[dDum=`PBO.J6Z,jZH()3a2Q9Bn]3r;bfn5L_nj79fJ7o"K78W1Kn4]# +I"-j-K85D5Gr2bXe'5oJ89/cqFDbo:B5FM\E7iaccbmZ?aND`LaMu6ja=YEN`luZJ`Q6-@`QQ]N +\\G_fe]YtTb/_WHceQt'nFQ;Ep](9(YJ7Za_SjF4rkpV7`l#[2_nNYMp%J7Q\A,qt_8=14^qe%2 +`59=(^r*t*mdU&Po\@!n^r+14_nj70`l>pq^_OW)]&35Tp$^kcm+9A"aMuBL]tVV2h8h=m`llNS +cc%Z6R724CFDu5BDdtB#bgFhhBL[#cJV])8K7SN%K7ei7H\?QW,Lk#\b5KQ`b5]N_`rc-42H`o>&Bb/hTBaSs?^`s]i)]n'6V86_PDo_SLcJ,~> +s8N0"rVlfr#l<63q>^Kkp\`M>&HDb0q#CBW`7JG=d=IZ/o4>3u7b +rV4o0E,9l=DgHJH3MNHJo(`.Yq#1-LrX8c)rVGHk`5L4(rVulr)ZT^0oYQB/F`D5:>S7DU"U,)4 +!s&K-"U##4r;]%g)f0bA;\'6 +s8NK+rVuloqTkk1anYc4s3glRr;ZfqkE3$Ukl:Y\rrDuarr)jMqtNU+L4G&/JqAW-KS+o/JU<9+ +KO"!Gr;HKC6>gO_CMe<:E]9Yf:%J,Zr;6Klqu6Wqo)AXgrr*B,rr2rss8Clp_o1+(rVlcrrVca- +hS@%H`5^'7G&r%QGC"OZH2`.aH?XU\H[^[.O2A`OWH!96F`i(XI"$BgH?OLYH$OdkMNu<'`4hFQ +H@1-aG'\@SI!Bp]G^"@TH%q0W_Sa7,`kh?Js8DrrrVG[Gs4mSoqu?]kqZ$SYD6%\^C2S03Dfoh_ +[JBk#s7oYWF+sUEs+:9's+1Q*Lk0u1J33W*rV?HhrrE&rr;ciqrso#(g:Ou+UV6O's8W#prr)lU +rr2p"rVZTlqu7#oZ)*q[UYPeHq>U?mJ,~> +s8)fqrr3<"kG;cpJ%=eu!`Pom:`Pf[3_7mIk]tX15r8Olk_Rd@s^qmt)_SX"$ +^q@1e^:h;Pp%\4+Y.VQf^V@\"\A,bo^V@In\[T2`hXg@.mHDm_f?)(S`lcZA^<+OSacHaMT +f[k1IU2XOZF*M\DFCHkgd*p:jd5)nPI=hHP%tfFaK7e]4JpDic-JQhfb5BK`b5]N_`r +s8N0"rVc]p#MeA,s8W&lqpGBOs7cHkg%"\+s8M`fp\t3Zrr;m#qYip2Ne)cVKH?&/G]-!Cp\k-f +s3NiSE,]oCBQ%"$[qDW5s8Muss5 +rr;us#Q4G\WhZrjrVliFrX&Q's8DnoVQJ5Br;Qcpmf*.a$2j`hG_pp#K7\^QK,oPuL3.6!U&"`g +qZ"o'G]%ASnI'[C]pAb-jrr;lps8VZhrr;us%KHG,s8N&si5NUPec#IGrW)oqrsdi#_o'F5 +VL*`3FFn^]rceBe!dAm7rd$/CI>*Eg`h.I&Ed`RdI`4s.(p&G'jrr2lmk4&E-rrr;6Nms76-b:na[MEHH&:Ec61mWVcPi +rr)lb:O@]mJHCFUKDgB-JVSZ.7IC$OrV6Bjs8N#trVucqrVca+r:J1E]X=3hrVZNlr;?Nms5 +s82cp$Ms,/F]i:Y_9C-Gd`;s1`6--jaT'Hqb/V94^;J4P2Kb"2IY!3,Jc:-C +JV/i8EFUYRda?4Qe#F^6EHHGMASP.gYZZb(e',kSa2Z4!ao]Z(`U_(u`l5sAbfIcEaN)9Cd`Au6 +]"?M9`lcHEai_rbdbF9_pAX!Y](kd]"5Vc\\#Mb +\$icS\+9+3\@ATP\&61u]XkP\]">Ve]=GDYZGY&bp@%;+cg99*a2l9Cd(R08b2:8_`lQ' +"TSH"rqlZo#N"P(s8W&kqpPKDr!WAss8([Lm/R+Yq=agfm/I%_#6+6\JU`?.pk0`?Lh:Dnq>1!c +s7WrjEHZ;BDfTqfWgd#^s82iprVufSrX8c)rVGHk`5L4(rVulr&c_b'oYQB/F`D+f6:+.-3^>k- +56!eG5".Ur3^,ko2)Jr\<_uRf8k;QJ8lAP\<)HCb91qlK8P;*IDe2jQ=&Vpj:Jt.m<`N:';,'b^ +>Zjm$0Ond=H\%:.o`+mhrr3)am.gSZs5Er!qu?Wnr;Q`lql+G2KiDo3E--&=:i5t*rql`frU:3ll1+?9d/X.ErVQTorqlfrs5O"Zr;$6grsel$s7uQls5`M9 +lfA*DrVlruqu2*~> +%KHG-s8;lpr;*aoV<7XRs3goGrs&>se<[2LpAY*lrW)obrql^"o07YOJqepSJfo\oKk+oiqu-No +s7j)kDKK`8D/jVbWgHcXs82iqrr;rprr2rgrr2rsrXJo,rr;utrSYZ4`7=hbrr)orrVm>`^r+(/ +_l09&VPBf]V#I4gU_fc!U84W\S\MkGZF%'GYdCgB[^*!AZa0S;0=.sgYb&AF\>HU@]"5D\[^ +!W2]krsJ_rj+^Z7T=i=ib0e<1`sTW#Q:kCsWkld!_sb\Haq)S4_8!b(e(6C)Jqo#/K8'5U+G"if +=&d`"d)j/Ga-JGoGBA"IDf.\3O[@@BaihZBai+/#"3AL%`U_)!`l5sAbfIcEaN)9Cd`Au6]"?M9 +`lcHEai_rbdbF9_o_74qgZ%/Jk2u[+s5kckinrSIhVmACc118aj6H.(n*of6o'bi5nF#c5md09) +k0N2cmbI0uo`"P-o^VJ@m-jK6n*oi:nF6"ko^MG>hp:Z@aiDKBb0[i9ai`M^,K@UCbKS/Rcc==b +>+U=GDK^#@D/2F;e'Q7S`k^'N2-PQbKDpE&K8';X$%d\TFZ7Uba2l@"b5]Q]`Z*(A`Pp!Ecd0eT +begTF5qt&^:qF]laMPp9b08V]'un>;b0A2Z_o&pD +s8Mlps5jLKrr;rmr6tZFr!`8ts8DuUo'HDQrV63fs7-(@s8MoqqY^6cp.KmiJq8]/KRno2Lk(>; +@Y"=NrVQNhs7ol8Cj'o=F_XU;V-q6prX8c)rVGHk`5L4(rVulr&-)P%oYQB/F`VPBE,]]3D>e8L +D&$r*EFs<8D/`uuE,fc2Ci464D/4$.rc/0^G%GN.AH$rVHHkrr)Y:BodjtM1L;3 +Jr+o.Knt:Eq#:L?k +s6K"@mcO9DpAFpi!ri,sJ,~> +rVuos$N9o"_PaqH]C2IkfEW^8e +oD\[f)#a5OArD+eLk(&-J;8K&JV8G8p](9mrquNis8Dut"9&/prVca0q9?RZ[%ke>rVQWprr2lp +s8W)sir8rW(&e(.rVuors8N&-U7\!MbPqP@s8;lqs*t~> +s82`o$23bX>uQ]l`QcQRa:HP6`PfX(>?P6r[`ut7`lIPh29*MQ^VRt=gcp1CK7&6"KnP>;M1'r# +9k2c$d*'MHbK`4UATr?=G%F(#QVsp4aN2B@`Q#praof`)`l7Mi-cX-Fbfn/IaN2E@bL4JB^Uh&- +bJq]Ia2uKMgsXsHoCMPDoCMYLq>C*fq%ESorr;lqqtp3^o_/(VrVcZjr;?Bos76*epAXt@p&=[_ +q"OX[qtp?jqtg*_oDAC[r;?Bgs7?0]o'bu)cg99*a2l9Cd(R08b2:8u`l5p@c-4>L`QlIkO.T6d +EGoo;DJ)Ynd`9&9`R!/k@pt7CI>33&KS>A8KS"i&/Bc&S`PojkaT'E_`>ctEccs\S`l"ci4tnuX +JAKLRb/;6?bfn/JaNEJ_s2P)[s2tAd&'N,/\8G;@:0sO^rqlQ`q#:;D~> +s8Mlp#P[-:kPtSWr6tWQr;$*es82iljmVsDrqccsrr;Qg0DtkMq>(!brqBH8MgpV>IYWK1K8"o= +IVs]1q>L!dqYp*]q/pq!EclD:?)Eg"pt>WSs8Domi5NXQeboCGrr*-%qtTg#LO&c>s)e3[rH/'^% +s*/BD0Ki&4E5I_EH?;KH2_pdGPubUEos8Mus$2aDks8V3MrqOtArs&H%s8;fps5*_Vr;6Ejs8Vrrr;Q^%l0Rd&h +uE`Lr;HWrr;M3~> +rVuos$N9o$g7k7Lo_ngie,KCI%fZM-s89U$ZI&LKs8Mupnbt6@s8Vros8;om4ItiK' +I>iMiJb]-Bq#Cr;Zfms7uX0r;HZqrVZQks8DusmC]j=[@Za`r;6Kms8W&t +s5 +!W2inrsAPo]O=TQZGk#0e&W-Dc,doC`4pn*=`q0maN)<<`q%2)`5^!9_T'L>e3Ii-Jr>5*KS#,; +M1^_,=CKS#c,7fGa2-3^B5qa/G]RCqQ[i&gc2P`_`<+'#aSs?^aT'9Na`RN#J]#)S7fB?LPH\$KsKS>)=L5L\;I6jpSb/VTI_o_br+NhpN`Pp!Dc-=JN +_6oJ'2*"&iVT6s)`P]^!m:s8)Harr7K~> +s8Mio"lA=ms8W#FrXSl#r;Zfns8UjBl2U_]rr2rgrYkh4rVuomrV. ++>.R2FTH`4rd=`lrHU#AH$"CTAnOm`1LtKJG'\I[G^4[bI!U$^I!:$eD/XN*1*0),H$4C_NR[V# +rVlfr"6f+Hrr2rNrr;aFpN)=q@Ua@kF*VXuRJHLPrqHHmqt0bEFbGL#JVSc0K7ec2MKqY[s8DZk +q>^9is8W,srVllqrr39&nFQG:jT#2Xrr<#o!ri6"hYm]Vrr2rtrr2iprs@cPlfm:+s7Q +rVuoss8<3%nu/:WkPY8+rr2p,rr)lsjdWHbqYgHns8DNfs8Nu5rr<#ps895oMM6>3J;/`*KR\<& +HrO8CrVQU*rn]eWCOL&;B0i5o9]Q-Or;Z`pqu?6drr;us%KHG,s8N&si5NUPec#IGrW)oqrrLul +pqujC%Dg$$_90WRQGgVW`5BIk^]D9erPCD-^q.M'^;m[?R)R.c^qmq,_ns4(^qmn*`4s:2^;\=5 +UQ;Ora2#R0_=dj.rVlfpqW@;Ih>[HSrr2os0)PM>EJ^Su?>sLsG\Tm=qY'shr;Zfpo_C=bJqef+ +KmnZ)JUiH.G!tm#s7lWirr;lp#Q4Q#s8MuprVlg)rntW$[\pV7rVZWjrr3*"r;Q`RrW)urrX8c* +qZ$BJV4=!JWqZMms8E,us8W(K~> +s8Dlq#Q+AOCfXZ5`6lX?>.7^W+@8`5_Di0uhAO`QQNIcdA"8L5:;:I"?m"MM?\> +G="C9bKIrJbK\>\_CfP;HZ!h<4dVZqa4ec:`W*sAame>bQbkh;5n*TK.lg*s: +miCf^kOJ02pAX^1]A3&QmHir\m+9A"aMuBL]tVV2hT5`:rlR.=_o'@5do_$l>[MJ`E-,e^L>'V` +_7\"BdaI,"A9NELIY`W4LPCM=M/=QXeBZ(]_og!=aN4A's3)J*`Pop@bfn8Q^oi&Z2`sE;_8jdE +_SjO\obfRr9PZUXO=aJirs8Voiq>UDE~> +s8Mio#3b.(r;Zcre,B^PpAY*lq>L?QjQQUC!ri6"nbt3ArVZTnq#BkLLOXu4Ljk,.N/3.BLNZkt +qu?Kfs8;ifr1HW'GB%MA@8n&%CNXfFrcoE.I!g3aG'8+UH$sjSB2B9T2J[;RH@1!_H@5^A(jpURG^4gcE,T)E%2)Zb +G]n@]NR[V#rVlfr"6f+Hrr2rNr\"6Jq<1JMW((lUCi4B<3Ka7=r;$Berr;ch9m)DKJqJl7Kn+]+ +L5BGsp%SL`s7uZns8W#qrrDoprs7r]o^L6-s7lTmrrW#kr;Q]srqtaSs8W&ss83?*s8VTKlg3`r +s8Volr;?SF~> +r;R-'rVc`o\Yu:Oqtnh@rr3B(qu?]lYGSVequ6Qns7?6is"FBLqu?Qnnj8.]Jq\r-L4+r3ItE;p +>5J3trVHQlr:Tu[7W_1j^r"") +_8X=/b/'s2M7(C>^;e..p&G'jrr2lmk4&E'rr)jNrqbeKUn^7qH>@A;EAisXs8W&tq>^Kipe>jf +Kn4f0KnFi'JUrPbM"UQCrVulss8;lqrVum1rr)fprVufl`P/^aRcsbLr;ZTlrrrE#rr2rth>[BQ% +fHA"`1WZlTtC4$s8W)urVh<~> +s8Dors8<3#l@iVKMS[<\aT'Bnc,[c?^qt%f=I?Vi`-`59O;eBlmq.XHJrMMZV0H]akD_=D/sN0FCK3\?u+B:b/M@!`otJe`l5sAbfIcEaN)9Cd`Au6]"?M9`lcHE +ai_rbdbF9_naHDCqsXLN&+&KOq")2.bkL_tmHa'&li$5MlP/aQoC;DEkHqSDs8;HWmHNftlKdd8 +m2bNVkO7p1q=)n>ZfV&SmdfJcm+9A"aMuBL]tVV2fuP5S_o'^?d)\)4T0[IAB5)C*/U>gd_naR< +cd^P$2.6E3*.j$)LkC>7LOi*1cd:7ecH+#FaN2NHbfn>U`l7ks'$%GU=@>,56D2-7bKn&EaND`N +rl3g9s2tA]&]i,:ag?Cl928lZk4eoUqtg0gs*t~> +q>UWss7k=0mJd.7rW2rnrr3?$qu?KBl086JrVuBd1&1eFs8DleoLOacL4t;=K8P/2MM4crp&"R[ +s8)]ooZ,lLGAqGC9mrqtdTrr3)uqu$Bkrr70OrqZHjrVqB~> +rVuiq#lXbOUo1d"qu,"Crr3B'rVuoqe"!V[pAXpfs7?4Gs8)clrr)fep.:$dKS"f2Iti9!L4W'g +p&4gas82cpo>f]FF)Gf3F`'@>UI4\Rs8N#tr;QNlo)AXgrr*B,rr2rss8Clp_o1+(rVlcrrVca! +hS@%H`:Uq^`5BL2_TKu^LmFUP_SX4.`5T^5_SlGms2=rV'?%f-N/WdjaMP^1_na7/_8*k$_#D4i +_S^KfJpX&-:$grr<#trr2irrr2rsrXSu)qWkVs[]lq6p](0kqY^Bnrr<#Wrr;os +rr)j)rqu`^Y+_J\T@s/ArVuos!WW.L~> +s8Dors8*$!n#']$DSa]@&BW2;`l5g2P"f/%Xhhop`Q%Mj1WI&IaOSu"fA8H7I#3]6L4"c*J;&D8 +K@.u`]ue+2e&S6(/p)#KC2n5YV3`XUeBu@W`r*pV`rF-[b4As6Vo:mHs6*mHsH7oC2=\[^soao^D>:kNqL"lg=00 +mHs6*m-soFe@)p!k4S35o\e'^f?)(S`lcZA^<+OSaT'BaaMu7!`B1lWe'2K>QYf]@D/sN89.A%J +^<=O8cH",Vf+_5'Jq/K,L4k;8It;_cg"b-*bfe)I`lQ +q>UWps8UU.ir8u+rW)orrs&E"s8Um9hu3QTr:0b@s82fon[1Q%Ljt26J:`Q2LP^k>:g*emp](9m +rVuLs9QYSpG^+7K<._2hT(i*Vs8Vooqu#^X$ig2(qV]?2`7=eas8N!'s82T`_Mrr2p"kj8*Drr:XMs7n5GnO'OZ6uHsaGAh\B3`5qNs8Vrqs7u6`EGg8XJUrE*LPLM: +N/Ct+WW3"pqu6Tp#6+Msrr<#trr3/mmIg8&rr2otrVlg%qtTs`s8W)rir8rW%K-&!r;Q`qs8V3H +lKI%%rrVrjrVcbH~> +rVufp#QO(aU8[SXrR1ZUrVufps8VuhVQ-rdr;?Tpo)A[h(]=71n?bH&Ljk&1I=Qs%Jq\o.:0ISl +qYpL.rr;Op95o&bG'7kE;Lk]^TDJK_q>U9knG`Ferr*B,rr2rss8Clp_o1+(rVlcrrVca!hS@%H +`:UtH`(S7jb*\*LQ_2=8_8=(-`l5m6`5KX6`5KX5_o7:fQAqKU_o'I0^WOL4_SEt(_o0L4`5oou +O,9'\Z,+8l`kfLas8W&srr)]UnGh5Aqu?]o/cY?,XJA*uDfKo:F)!d9s7u]pqu?]noDETFIt<-" +J:WE.JV8f4>0AUS+6To(r@_s8W(K~> +s8Dors8*'"o>YKH?F@f#a:H>6aiMN@]s1mK?^ndJa2[\k0ZM2Nc.CI;.qF$QL5:M:KRnl4KQo^I +gs*g^`l5p@_DX&XGADPLChlt%VdP&$b/3tqrPeu]b08)Po>hum`Q$-GaMl6Aa2Q6MaLT's]@G*E +b0%cHb0Skkg[P15!qc*Vqt'dY$hjMjq8^"Y^rc?BnbqqUnc/(XmJlW3o(2ABYdqW_cM$l"o'>H- +mI0N6naGr6nF?/Hp=m`lQ +q>U`us8V*:i;EWTe,K=G#lFZ$r;ZcNk4S`R!W2fcrr;gHs5B,>DM*OpKS,&8IY`T/LMa:-jqu6Kjl2D(jrVcTN`Pf^Fr;HZprWrQ$q"2FYH$+9'G5l^b +EtiV/@OM`p!rr2p"kj8*Drr:[N0E:qJrqMCaWJ+SlF)Z,?BgD=ir;-Hnqu-?jp[WE3KS>29 +KS"f/K7&Q1F[q5_qYgEkruV1:qu6Wpr;-HniUcp4df9:Gs8Drqs8;Zdq#CBnr8R_Trr`/nq>:-j +"nq3HlKIa9rrW#kqu-PF~> +s8Vuqs8N;s\"9>Hq#/Y?"8r,trr)j#c(D;fo_ndhoDUKEr;6NPOATnJJqS`+KS4W(I=QudZ1n7s +r;QHjqu$,<1gFj=E,TW1:8F4IoDeagrr2lprql`brr2rsrXJo,rr;utrSYZ4`7=hbrr)orrVloT +_#D4S_Sa7._YM+K`"U&-Q]72lP+p"4^VIY%`5T[4_nuDh$Gsg%`J]bMj'*ZZc9u!_8a=as8W&srr)]UnGh>D!r`,trr<#t$ig,(s7hF\VL_rcErKr"AjH(i +rqZTorVufqq"&Q5KSG89K7JN)JTZWrEC>QUq>UBn!<2rq!<2ut&cVh1rVl,l]"5#:q==Rcrr;ln +rr`9!s8V'W!W2fmrsSi+p:d/lTV8pnrVl`prr.E~> +r;R0'qYU*6'IpSJld`fVI +]u\:=b$H/iF+ACMAn4]8Q93RH_nsLmb5]Ng`l5p:aND`Nb4E[q`l5sAbfIcEaN)9Cd`Au6]"?M9 +`lcHEai_rbdbF9jo)nOSnalYJrUU`squ4mV`P9.2p[e"HoCM\Lo^qbHrp^Tlp@e0k^VRq+ch$_t +na>c8oDS;'oC;ABpAO[=^q7In]&rqena5Jbm+9A"aMuBL]tVV2hoGoBc-49.`W+"5bJhTLdVr9] +ITL&tF*2S5.+-MgaihW8_SaaGdp>juJVA`-JU`<(I#*2_0ketXb5TC'aND`Nc-48K`Po[2`kn3B +2`*We]u84;`5BI4b08)PaSs3;h=0/pA"Xes8DutJ,~> +q>Ud!s8ViOiTgICqu6WprW3&urqt[QrVm?%s8;iqs30rls8W&or:9h>r;ZIM7=C&DJVo)0KnY;< +L5BJarqcHis7u]kr;Z]iAl!AgDfTtmOf2ECq"Oabs82fmr9=1gs8Domi5NXQeboCGrr*<*qtTg# +LO"#bG^4Q3G5c_YG'.kGCh#%3#Qk&0+DQ+JI!U$XEH6,DH$Xd^F)4kp"pk>2#rld@F*MnLDJjB5 +F`qnKEcZ&*5nX2%!!!F"Bm4fGIZ;kLs8Drrrr_KOq#:9mg&1'i +pAb-jqu?Qmpm4j$J:rZ0Jr"u9KnYD6N'I7>qu7*&qtp +s8N0"s8W)ts8N?"d\3DLp&4pirW)usrr2rSrr;p,s82ios8;GQ\$bJsrr<#srr)lnr\4nCN"'/F\7anpiF!5\ZQ3lAhN^qde( +`kILiP*1Z`Tu=d__oB[7`l5j4_Sa=2`Pfa#OGT*]PEiMh_na++_=dj.rVlfpqW@;Ig]%0Os8Ec0 +s7u]jeO,Y!9Q5)mDf%bgqY^9kpAFq*rVlVZ;KdPBKn=l1ItiK(KmS\>r;Q]qs8N&s!W;onrsnu* +f=JT!Ut>G@qt^9lr;?Tprr<#WrW<&rrr)j,rVuMiT:DUOd/*eAqu?Zps8W(K~> +qu79*rVucSVHd,N]ZA=:`Q#p=b1XiTaiM`Ha2#R(Zr1@?U;"Rb`lQLk^V7IoBS*ccO>P^s0grPK;YI7uLM4,:Ytb/2-;_oU!Cbf\$+`o4uP`lQBH`P]U4b.;:d +7S@'^li$VPrVlrts8RT~> +s8E6&rqucqs8Drs#MJ2!s8;Qis8N#srrr5nqu6Wqhu4,_r;Zfps8V]@lMCP\qu6NnrVl]l')/_6 +J;f,4JqJo3L4b>5Lg*i.rqc`rq>(!tpionWF`V;"W/O6frqlcqqu>RQ$ig2(qV]?2`7=eas8N!A +s82T`_M +qu?]p&cVh+ntW(do`"mjrVZ]ns8Drrs4mVRs8W$&s8DQ3T=!5Irr2utrquirrr;usrVm`.YZ,t* +JUrH+M1:2-KmJAQ;LJE=qu?Kkrr<#ts8Xc/7(OHYol[DTr!_nj.]s8W&srr)]UnGh>Dqu7<. +rVQWns8V^U:8F"HDJsDdSc&EbrVm?+s7lWfXY=gMKS>&/K`6Q&K*-^Rr;HTo"TJAtq>L9l%K6;* +pVF;I[& +rr)]n(%'F^?"^LfdE');`Q?EJaMu6Bb/hT[a>V2\_o'R8\qip]L9nY6_oBsGb/M-1`QHHMb/hZH +aGiW4M1U/)K8YJ@JqeZ'906G-b/_cEaSs0oaNDiVbum_UG]mXrU4bG+e',hQb0'_-$d-Q1`l5j7 +`lQBJb4E]&`l5sAbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_naGl8oCV\Hna,Z/kj\E9a2Gs=]?^!9mHa*+nauVJqY9IHnFle:]=c%t_SEqNq=X1D +iQplBaiDKBb0[i9ai`J]rPnlV.`TWScc=,Ubq2M`P"'"tBL.F(bfIlLb/M31^rOa?e'o;4\Mrqb/h['`r=$Zb2(,Q`l,[:cH!lAa1\9M +846 +s8E6&rqlWns8N#t"mXk&s8DKes8W)trr`)lqu6Tpir8rT"9/?#rr2p%cKX6ds8N#qs8Drqr;ZX1 +s/f7PL4Y#4It`B'Mh7"&=4I*Hrr;foq>Lp'pKMB)YFa8IteF`e>rr2p"kj8*Drr:sVrVZ]pr;R3!nD#d$ +M6'oqGu]UprVuiq(]+..s8;iqo_(n*JqJf/K7o#4K854uMu*GOrr`,lq>C6l#3b[Lh!+k=dJa7H +s8MrprrqiPm-Wlqp&BO~> +qu7?/rVlfppq*3!gAV!Hr;Zfps8;lqs5*bRs8W$-rr)fWS$B9^rr<#trVc`os8N#qrt25,IY!$$ +LOY#+ItrK0@oC_Lrr3)rs8N#srtGD1rVu^tBQ%QLUnpRFk4S]Qs8Mrp!<2lqn,E=drr*B,rr2rs +s8Clp_o1+(rVlcrrVc`shSB-.s1n`Q_u@Re_o0F,_T0U7Ss,:tNf]iOc?-W`PTF+_8F:+aM,C2_o9cuNfB3`OHu,n[)9i!`507^s8W&srr)]UnGhAEqYpTqrVlg+ +q=EDr +s8)fpqYq<)i.kKAPKD(d]t_P0d)sGL`lcHF`nnd2`l#^:b/U2K>$[N,`Poj@c,df;^W"@?c-",K +bhA"EI>*<(Kn"l0Jr"i3>!B1:cc3uBc,duG`Q$!Dc-+@#?ug*JTV+@tb0A/V`lS/%$d?c7`l?!8 +`Q$!Ab4n*TN1nb);Ho'cGCo)%+S]>DD"`PB7Oq=X1B +iQplBaiDKBb0[i9ai`M^s2G)YaSs1OaNDcSbf%H3+]4,t;dF-*CXp\N`lQBJaMkp5`QZ9@eBHZ, +EI*(fL5:S>KS4r*=DQ7%^V@\-cd0hV`5':1aMY6:5r^kdFh>Q?a:ZD+^s13Jai;<7Ki(3) +s8W,u"T89!s8Dor$.Rkrs82fqs8;forr`)lqu$Hnir8uU!<2ip"lJ>(qu?Wfrr;orq\8k)1PgX= +L4=l,NJ;q=LcP/*p\OphrV?F'qt]>DDe3m_H;cMfq>Bsbg&;BZrVcTN`Pf^Fr;HZprYbb5q"2FY +H$+7QG'.kIF`r"WG'7tA@P/?!qu@?4,\hIHG^4OVF`_hMI;s(0*!cBA-Njc5BQ80?H$+7NFE`"O +EH>_T('OjB!!3-##Yo>\FE`.meF`e>rr2p"kj8*Drr:sVs8;ips8NT,rVZ]i@6efuWi/3nA+KQt +rVdW2s7Z?ipAP$bFDZVeJV8Q#L4Y/8DI*,9rX\r+s8W)qr;6Bks6T%Ao[ +qu?]q&cDY,qU_=6]`.s/rr<#rrVZZns53hUs8W&urVld$qY@P%[FYBs^L44l3 +ItW?1KR8B)2=^M9qZ$QnrVlfps8N!.rT6Od@rJ)e;_FR7rVHQoqu6Kmn,E=drr*B,rr2rss8Clp +_o1+(rVlcrrVc`shSB$+s25>`_SX:-_oTgM3Ds8W&s(&e.1rr<#n +?pAQoW2)Ua@IO6prr2lprrPeJeA&c_h0s8;osrV?,fTq%aJbk_84s*t~> +s8Dcn&bk@c?p-CKk5$[D9l+aN2C#`<"!"rQ6n:bg(q_H@(F% +ItW?4Km\N&.G3+j`lZ0>ai_cG`Poj@bf@oI2JQc>SodOJLYC.j_SuMq"Nng,`lA"s"3/F)b4o_?VD]tVG&`5'+3p[[e= +mHsH6nFQ)An+-(b]"H#&_SX7(d/NY:nL!bqnaQ2EnacJJg;(87^VRn)^q](.p$hD.cg99*a2l9C +d(R08b1OcLb/hN?aO/R33cIEdUH)7HcIg@^aSj79aMu?:`5f[;g"'A4G_L[&JpiB+K7@8ufZhFP +_8XL?ccjJJ_8XI:^Rnpr2+0O!]Z&@@&]VT)c-=GQa2,/q:IRcTV!7[Ks*t~> +s8W&ss8N)trVlrQguA;4$3'l$rVuopq>:*hs5X+Xr;6Ktr;ZZ9nEg/Ss8E#rq#230qtp0p\OpirquG*Lk:>7M1^S:LOaeBk5,)Wr;Za(qu-Qos8VrZme,`,rr:FG%K6>(qYgn*&^%s*t~> +qu?]q#lO`%qs1;UY4;Gi"9&,qrr)itrr(jUrr;rq$i^2'rn*UH]^Yt"rr)lqrr;uurr2p8qu*!a +L4+],Jq8W-JV-^lqY^Bnrr<#qrr2lrs8EQ/pAXA44K,)BDeq;Ws8W)ts8;lps6fmcs8N!,s8N#t +rr;rT`P]XErVc`p!<)lr"5^i2_u.Ff_ns7+^V\"0ad\6GNf]HeOcGQt`khVjrPSZP2oi[lLQn$a +NK9 +!<)]m&c(Y0F')q[aMc!;aNM`KaN2BWaT'9Zb"]mp_ns9V9O_\2^WOd>_o9Xb/hNSeg`_XTfHau.D"3T]>MY.r5],_`Q#p=aNDZr +a<8LA`luZJ`Q6-@`QQ]N\\G_fe]YtTb/_WHceQt'nFQ8InJ1Naq"FR/^:_4t`l,j1^cdH;nF`Lu,VJThud`KYQqoUV7bJ:s;b0A>[9lkE,KSP2:L5(%p1We:o +`l#^5aNVoRb/2$:ai_)@82i[tA@B4le&W-@_8sgCai265Qr[$W:1h<-qY1#?~> +s8W,urVuosrr3PrgZ//1s7lHfs8N&ur;6Bhrr;$Xrqu]o%0$/(s4u]%p&G'ir;6Kks8N&us8Er7 +qtpEmnm-?mMM$_:I=R'$/bJi:s8Dutqu?Kk&,cD)mX9bjBOQ+)E(Tcss4RAZs8Domi5NXQeboCG +rr+SNqtTg#LO"#_EH-#AG^4U]G'.J'-4^@c!s&B%!oF*`epo`+mhrr3)am.gSZs53hSs8W'/q>^$E5B^m_ +D*tD$8aZQUq>M3-rr<#trr<#pYuc($IXZp)HB*qkLA^lErr)`pqY^?rkjRp1e,B +!<2`m#laP8T;^Bs)3 +F,,R%LkC))JpJs&7J^;7_)`P]U/ +^WQ6=mHa0.nalACqYBj"]tM5!_SF.+^:hndrqIl7oC;26n*'ZKf"o;B_Sa=1_SNptjnJH;nDhj] +f?)(S`lcZA^<+OTaAL+(bf\)Qc-48A`l#VIF)c895cpb@cHaALaNDZHaNVoScGdW;`mW>^NB_$) +IKCY6qV`l5p:aND`PbJD-@c,ZVZ4"`cbU:SFce&W-@`Q60Fahu-2EDoS->(YQ$qtL,@~> +s8W,urVmW3qu6WqqqU3!s8VifqZ$Norr2imr;Q`UrW2rrrr3H,s8;Zjs8UIUBH;Q6!ODK9cB<-7j.r7_,Xs8Domi5NXQ +eboCGrr*c7qtTg#LO"#_DfKiAH$Xd^G&1V2"U"u2qu@<2#:+)/H$Xd^G]e%RBOqYR&GuMW!<<*, +2JR/NF`heKFa/1TCdSd9#mC;/!<<*(!";YBEc?)GN7@M"rVlfr"6f+Hrr2rTrr)lsrr2p+8Rup[ +F`1AhY).<$s7uX1s8)`pqY:!cqXmR'LkChAJ;8Dp=o&*tqu-`rqtU'arVm&tjmr''i;Wc'rXAi$ +rqu]os5EY@l/DF0s*t~> +!<2fo$2so(q:hO7^[qL)rWN9!rVlfqs8W&Wrr2rsquH`qrs/N%lBSlto_eXe!r`&qrVlcq)>jF1 +5(\$7K78N4K6'QWr;Q`rqZ$TfrVc`nrt#&-s4C,EPX9;/DKAWqqYg\h@%KHA+s8DufUS=3GU! +rVmi8qu-Qpr;H?OZsH^UYf4],bg+5Nb/hZD`lcH`aAKsr`QZTQb/(j4a3(JR@WJNhb/(g0b1"nc +aMl->b/h`NbKS?ZG'f7'I"6j"DEHk.b/q]9b0.`Lc,dlA_oB^8cI]]oT8bj>BQ&)h?H9asrl+oW +kf=gb`Q$-GaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[P150CS;olgOHDrVt'O^W"42_o'=-_7dt` +nEoQ/n+62As7QAuZd-G+_8*k'^:h>/p&=_6p@@b?mI'WBhnHYAai2*:`4j.&]B/e[o((kfm+9A" +aMuBL]tVV2hoIq&bfn5Pc-OVT`6$Ra>]k%.APQL0H!&D8aN2NHaN2TMe]YkI]t__6c-J7WKn>83 +JV\>\5hX`6b/hTBrl>Ync-F2HbfRAK4u"oV@_TRsd)Za>`m)WC`N<6?8l&ulk4\]Hs*t~> +s8W,urr3c5s82`ns8V6@kl:\Yq=jpfrr2rsqu$Hni;WcV$NBu&qtg-gs4lW"rr<#rs8)iprr)j9 +rquZjr;Z`oQLp$s7TuiWFKU7G]InL7]Z.Zr8%>[s8Domi5NXQ +eboCGrr*`6qtTg#LO"#_EH62HH?sjZC1J[s!!!)t!##D=,\qULH?jaYF`hG.%KQP0!oFF9(to`+mhrr3)am.gSZs5EtSs8W'/r:5nAF*N"% +6h=QOXAIL@q#1 +!WE#ors8T'rr)2aSZh>XrsJ`)r;Q]orr<#srSmhUs8VutrVlfr#lOAiWi3Jaqu6Qo!WDrqrVulr +ru1n:rVr3dLOO`.KRnPA2Tbptp\k-lr;Z`orqud,qZ$.rPGM]#8p5)jE^[&)qZ$Eks8VZhrr;us% +KHG,s8N&si5NUPec#IGrW)oqrtF8)_o'F3`5KR0_8=((`05RoK8okk$':1/OHQ6U_8=%d_E,HKH +?aphNKfQdOctrjO.sY4_ns7,`59R1_k_L$IXR6@OH5NaO-5U2_o9O4_SPpFs8DrrrVG[Gs5!\Or +Vuj-s7D=CDf^1p6Ln3CW(tt>qYpNn!VlTirsR^EIX6]uJ:`B09t('!qu6Qo%Jp)&rU\7I\[eHlp +\k$:rW3&urr3<(fqFn)R],?Jrq?AB~> +rVmi6qYU6ir;Z]cc>QTiUVb:&c-!uGb0%fF`lcH`a;i4=`QZTQbeq9Z#:o'cD5\@o_mbK\,J`kf@%]B/e] +o((kfm+9A"aMuBL]tVV2hT5Z>3c94e4tYVgP+=P8_u%Llb0A>T_Sa@6aj/AI,^"?f +IX[$(JiT4JbkT6ibKe,NbeKfY1b(aUSA<+]dDumCbJq`I`P%@38kN!)`:*I!p]#a~> +s8W,urr3c5s8Mljs8VWPiW&rRr:pRf^rVcTN`Pf^F +r;HZprY,>/q"2FYH$+1LFa/1XH$41@/IVLWrW*W5!!*-*,\qULH$FLTEcP\(!!E3#rW2rt%L"b* +Ecu_RGBIq@Ce#0Cq>_'-"T\T0:2Y,nGC>J#o`+mhrr3)am.gSZs5EtTs8N!.q8u$HG&1qWo(pR4 +Wg[Ajq>M-+s8Vros7uWfL0]LkKR\i8JpUGgqYC+"r;63bqu?Zqs6&qFkMZ@>d/FUSs82chs8VET +meQ23s8Voop]#a~> +!WE#krt+t*ZBO-,WhPEE5j`P]U0_"Ia-rVlfpqW@;Ig]%3Nrr*K* +b!C&gBPTj(qoMg7QXKUfrr;rr(]+13qu?]os7_4OJr,)-LP:2&;tU"es82forsef%rVPrn]"4oH +q>('jd/FIRrr;oqpqihhStNOfo`'F~> +rVm#sq"t$grr3T-ieUf9P.Socbf[uIb0%fF`r=-@a;r:>`lcQNbf.Q@a325s9j2/;_84%/bg4V[ +b/hTBrl@%?`5g'J.sHZ%K7J>u?r;9t`Pfa3_9L-Kc,dlA_o9X@b+VLtKhgBW0P>EF?6n%FaMu6= +`Q#pqao]Z(`q%3!`l5sAbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_oChhHmHa02qZ#-`^;.S% +b/VHB`5TO)a7JffmI0Z?qYp?&[)g8*a2l<@`50=0^X;`Jo^hV@n+6#Fi4Ze@_nj:6bK.]B^V.8@ +p\47NjO*>GaiDKBb0[i9ai`D[s2tAc'$AGDW%Vq+AR?n6fsj\GLdKD2rl4rY)Tp:NahPX1`QlkF +9RDYNJ;Ar,Ccg"gb/VNDrlPkp`l?*Faiq`1MF&jJ5@;4JaMuZL&B`8D`Q-!;Z?&u2:L0"@o_nL` +J,~> +s8N,trr2rsrY,&%qu?]Uk3E!ErVZKkrr2rtqtpBmir8uXs8E3"qt^'dq>UBrgu[f"rr3)urr;ln +rsSi(qu?ZqqYQ^gK7NrU.tNA"9`"\^s8W&rqu6Tms82`krVuIhX/8\SqYH"9G'ItC:Aaqbs8Vij +rSd_`s8Domi5NXQeboCGrr*T2qtTg#LO"#bH?X[\F`qS7-4p=W!##J:"9AN+$7';)H[0dREc>A( +!Wi3!rri9#%L+\(F*DqZH#[Y95S!r"qZ$Tsr;[618T&TqG(>Y'o`+mhrr3)am.gSZs5EtVs"s`Q +s8Mlb2gB=cBM\F#q###hY%t<:q>^KlrVu`oq>^Hkr;-Bc8:?5LK7AW'I6RB$s8;oorWE)qr;-Bl +$1@ +!WE#nrs8Q&s81`GTsadsrs/B"rr2lqs8W)sj8K&Yr;QZp'DhY(qmNT4jS8cRr;ZfrrVZWmrr)jT +rVu]kRpCMmK8#&2KR$2dr;$Bmrr)]lrVZ]nrVZWnn5,pT9]Z'HLI-')D/E#ErVZ]qqYpNlrr<#h +rr2rsrXJo,rr;utrSYZ4`7=hbrr)orrVloT_#D5U`kK=,^Vn"/N.H5$IslZnO,oE`Nf]Hr_nO+0 +`5':0\UJUIH[gmeZn]s8UOH%K6>,qu?TfWLfQJS^dT0s*t~> +rVm#sq"jmarVmGrZs?XF]#`4C_o^!Bb/hTBrlX9B*6,t;b08)Pb/hZ?`PfN0Pb.tj2aj/-oR[6+Uf%=aoC2dir3Ru?rcca/D +a3)QKb0%fF`q%2E`l5sAbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_oD8%Kn*KW:r5upm`lQ-8 +^rj^>`5BF+a7/Hdo(;JKrq3q3^rFU?aMZ-@_u@Rn_pS/Ln*BH3nG*%A]"5o$`Po[1aNDQ?^Uq); +rq?olj3d5FaiDKBb0[i9ai`M^3l].ZaiVQFb0A +s8W,srVuos#P\#hs8V0Ej8T&ar;ZZnrr;upr;Q`Urr('grVlrMmc=?H"9%ukrr)j3 +rqu]is8)clqK=lSKnP50LP/+@rVulos8O2>qZ$Kls8N&uQ?TKYNVi\Nqti'gEbe:Np%eIUrr;cP +rX8c)rVGHk`5L4(rVulr#64SqoYQB/rcJKlI!TpPB.+5kq#D!/"9S`1+_uLEFDc/=>T3\J!rN$6 +!X/]/!!!3YC34fOHZX.>3YDZ%!!!&t!"]56!!!3oCiFKFL6'jVs8Drrrr_KOq#:9miVioSs8)`p +0`(Q:DJsi/=TA-pqYobMWh`GhrqQNnqYpNjs8N&nqZ$5s8!/OZL5CLI;#9e^s8)Tks83E+qu6Wq +qW@GMg@bLDq>^EArWE)squ$Hn$N&fNna#B +!WE#krs&GbWM-9Squ6U$r;Q]orr<#srSIPNrtG;0s7YuT[D_h7rVlips8MuprVc`q#Q"Jss82Y7 +2u\F7L4+i06HoB-rqufr+8l!8rVlirs8J1$Vg"'rrqlTh06(oE8$DX_r:^0jqtpBms760gs8N!, +s8N#trr;rT`P]XErVc`p!<)lr!T(Wk_csdg_Sj@0`K,@iFaAI^G^Y-sNfT3[O.+,4]u@e,`jpS: +H[^0eH[C!gLQ.L^P`h]Y`PfU._8OEgIUCLr:risCNa#ds82ips62nIT1o4`q>^Kks8Vrqrr;oqs7WlhNIcV3LO_N`q"+F`qu?]o +rr2rtqu?[(kJ"XESAk*ps8W&te,KCIs8Dut$Mr>MSsl(Gli$k_pA]X~> +rVm#tq"jmarVmN&_J`R^V8:BuaMZ*Ab/hTBb0&\as2P#[s3+Qc_TBj5Y=r/?XhDj"bJM9Cc-=DN +`Q#p5bf8#Uem0eZLk1+sH\"2Zbg4/A_TpEMaNMN?c,eAaF_.7_G1G$gfA7HWBPKerbg+AIaN_TE +b08)PaMu6jaF2(I`luZJ`Q6-@`QQ]N\\G_fe]YtTb/_WHceQt'nFQ8@oC_eJo_HVA]YMP._ns7* +_9'd;^:VAXqs3nDqZ$9&YJA/rcHOJN`l5m;a2l6Io^q\?lL"3BgqgbFa2Z?B`5T^:aMu'.]]/YV +n+5_gm+9A"aMuBL]tVV2hoJ[7]?.t9ccO>W1h1?C:H[@Qa2HNQ3hi$&f?V1Rai)0@_9U-F^VS4> +Si_mbJV/o62EfsDcHj>G`lQJ`6#`J:JFP[En:*e +rV$8A~> +s8N-!r;HZqrWr;pqu?]bjPfP*rrDrprW2oorr:gR$iKeqrr<#rqu?$;gALsPpAFpgs#U/Wr;ZWm +s8Vuc3J<0:J<,/6?AA@Qs7ZKiqu6Wns8)`pp$YhUX\n`cs8VikP#HLJG +s8Moq!<2rs$NBS1T;0[0qu6WnrVliss8CaPrr3]2s8Vups1P28k4ncLs8;orrVZTlrVnDDrr2rq +ml5lNI=I<,KNj-*q#C*gqtpBmr;ZZnrq#SUTr:WRp](9hr/jnVEreGar;QcqlMge_rr*B,rr2rs +s8Clp_o1+(rVlcrrVca$hS@%H_T'4$rl,5)H$O^`I=6Khrd7:kMiWm[S]A@\aMu!+GB\1[HZjg^ +GBnL^JW,VMOe0P1^qR\(`h@g"H$OX_H?X^aI=[9:OHu0?aMbd0]YF.>s8DrrrVG[Gs5*bTrsei) +qXsdbX$plFAQJ['rr<#o,*?f@G*2P!s8Dorqu$KjrVuolr+fnrIt3B$J:9]Ts7u]pqYpNp&H)D) +p\N4N]=4-qqYL6lr;Y7Fs8NN,r;ZZe[%Wt\S&P7&o`'F~> +rVm$!qYL*erVmN(f8j0?MSR-LbeqNEb/hTBb0&M\>0>19`59I1bJnHo>aN+Ca3;9;b0A2T`l5s; +aMH*IeC)\gI"ZimK62fJCXU;K]u\17bgFGN_T:$FbrV5d4k7a!d)sp[4_K%^.Dsied)a8Gb0%rP +b/hTBo#Q7!`Q$-GaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[Oh+qXF%Oq>A@C]YVV1b/VE;^:_D) +`koL3p?_DFqtKim\%9]&`QcKE`l#R-`l>s7cLg_qlgXNAgUt#8`l6$=_o0L-^rFC2^qf(.p$VM4 +cg99*a2l9Cd(R08b2:9;`lPg?aMH$HN&kfs?TliXa25a5eq._8D0*nBb/_QF^Ve46a3)N?eQc[A +Kn5&.Ir?X^g<%LX`Q$!Abf\#H`P]U@\Y<@d/O)8!aiquO_oC0H%a*)@^r+!s@nTKq>FFjWo`'F~> +s8N0"r;Q]qs8N&o!<2ut!o;nor;ZcqrqufriVrlTrr3]3q"asirVcZis3Tils8W)uqtpCPirVulrru_(:p](9ls8RS&WbAI1s7uKjs7<0aDfT_^p\+R\oDe^e +s8V?_$ig2(qV]?2`7=eas8N!/s82T`_ML*frVccioMq]c7e-NTq#16lrr<#rrV6E`22-[8MLUX_7H4(?s8Dur +s8W&s!W;rprsIuWo&93?s8Dfls3^fIqu6TorsIcOlKR%&s8D]hrqHGC~> +s8Moq&,uV.s8W)pgmk.JqY1!hs8N#ss53hUs8Drsrs\o,qu-Qel_(c-p@e1Xrr`8ur;QZps8q>^6is8DurI=e>,VYL2fq>^KeVbLrDCdIjks82NilMge_rr*B, +rr2rss8Clp_o1+(rVlcrrVca'hS@%H_SX%$^r294H2i1eG]n7SGC=^`KT(nOR`WLgaMYZ:G(4a\ +Fa/7WI=$9aHA.@(_o9O3]>+%=s8DrrrVG[Gs5*_V +s82ZlrsAJ87<3?]4o,-TrVn/9nkl!R7.L +rVm$!qtg3hrVm6"l*t2-FLo$#aN=G(g;s95>0>19`PTF2d_2GM?ZNNe^<=F5aNVoQ`l5s;aiDTN +`m`;eG'\[gH$k!j2:U($aN)HK`R2HDbfeMiA9"/CP1A'u_p-QPM*#Nn?nC!Yd)NiFaND`Nb/hTA +o#Q7!`Q$-GaMl6Aa2Q6MaLT's]@G*Eb0%cHb0Skkg[Oh+p%%\IrQ)LZ^;Iq-_SX.'_n3Y"a25R2 +q=aX\qY%G.`4s.*aNMTGa2G[*`5]d6dJ3D(p%dq-]=Gi%`Q66=`PfX,^V[q,]=-_lp@@h5cg99* +a2l9Cd(R08b2:9:`kB+0d*U"+/o5K=0%\Cc_7dS(akK@XT.eI;`kod<`Pfj@`lH$Kdj]s*KnXc, +67fq!d*0JK_oBd?b/hZD`PfU5Z%#7u2*,`kcHaVQa3r$>b0/#G]tC%<92/](_sm^)p&BO~> +s8N3#r;?QnrrW,or;HWshr<;frrE#srrr>tr;?Tpir0#Wq>:-js7m!$rr2rlr;Z*:hYmHVqtU'd +rr2utrqnbUqu?Tns6*!CML^D8M1(%_qYU6kp&+^crql`pqV+uGTiq0gs8Duns8Vql9QYAn;#1(i +s7H6erVlisl2D(jrVcTN`Pf^Fr;HZpr_!4fq"2FYH$+7KIW]-I%Kut9!Wi?("pP26!!*3.#mqe] +HY@%q$k*FB!!3?2"98W,"9\].#QtMjAo2X8C-)q4!s/Q."9JW0"o\K5!T#QH$Fn$eF`e> +rr2p"kj8*Drr:sVs8W,p#ljNnAoD]Zc1q;<-2dcBs8/j+YEEl"r;ZfqrVulls8Vig<)&%&JVo1i +K_kHCs8)Zls8Dotr;QZps6U-Wm+VL>r;Z]ks3^iGr;Q^"o]GW0hq7r.!WMrhs*t~> +!WW/ss8W'0rVlisrVc>aTr$ZBr;?TnrVccSrr2p"rr)cnrr3B(rVu`jq8]S@h>-dBs8W#trr2pR +r;ZTmr;Q`\7n&2]KS>81J6;RBrVuThqu6Wns8D`E;59acp\k-ks8)cqqP-T"EGJAHrr3&os8VHb +rr;us%KHG,s8N&si5NUPec#IGrW)oqrrLulrkhsOb/hAXI!U3fI!U'`I!g6hH@CO)N/j=?cG7<. +Ed2nUGBS4VF``+WH?OF\MNEmi_8+"1^RKLqG]n:VH@(!aGBnL[H\%$;N3g:9`kT=)p&G'jrr2lm +k4&E-rr2p)q>:3`:h4UEorVccpq#CBiqG^.?L44l0?A/1Ms8Vrn +s8Vuqrr3K-pAW.I\@AI%o_eahqZ"tBrr3E'qoGD$U7eLZqu6WppA]X~> +!<)lr!r`#nrVm?*p[m0\?XoS7]Yhk6b1aoP`l5pEcP-a2Gsrb!a=j`lQ6@ +ai;QGb0[mP0n+@tK8Fhp6Ia<&aM#U4`Q#gAcdB);&`Q#d4`l,a5^;7e0 +`4s=]s75pVYdsbKs1oSl_7n",`4rq"`5TO8nFHDTpsld`]t_G&`;[XR_#M+b]YD;$\``YVo^1\b +m+9A"aMuBL]tVV2hoIjua2uBGf[Ml^Ana*-c-FDI^Ve1>f9B=4JQC+@c,n#HaMl$AcH+Hs7u*.Z +KmHU4f$)Rf`l?*B`l@qt&B;f.Z):Vb00W(-^rjpC`m)oPs2kej]Xr_l9Mo#@hY7'MrV$8A~> +rr3&tqu$Hns82lrrVlumiS<\srs8T's82Wirr2rWrW;ukq#16mqZ?]qrquctdH0Tkrr`)nqu$Hn +s8Ef3s7lWorr)fqppU,(Og8-1q>:0irVuQjp\.[(Ec=7oo_J@` +r;?Nms8V?_$ig2(qV]?2`7=eas8N!-s82T`_M1)bs8;orqYC$c?C%3ge+`kApAP",rVHHB8;)VIL51=GpA=Ua +rr;`mqZ$TorXf#,rVuookO@rpn,NFarr;rDrX]&'rr<#YkO@Zgn,NFcs8DZkJ,~> +qu?Zp%K6>,rVHNk_P*[:s8DusrVlftrr:sVrr2usrqufr%fQG+s8W&qnY*(up\t-hrr;oqs8Nf- +rr;urs8Vo$9n7kLIu&S?kkb>Wrr4#9s8;]koP'>h=NL@;rr)irpAap];J9rb4kB?*rVli`rr2rs +rXJo,rr;utrSYZ4`7=hbrr)orrVp9^^r+(.a2,TLFa&+UH?a[YH$ag[G]nCZI"RHOai)9-HZs[U +H@L?hH?j^[G'\FYI"@$/TZG9r\!qniG^O[UG^+CYH?OLYG]e:_M2np]_oB@,_=dj.rVlfpqW@;I +h>TA2rr;fgM,nV8:8@Uap](-js82Zkqd#DU>LWEIs7ZKls8W)srROJkJU`?*ImNl.qZ$Qpp]('d +rXo20r;Z`S]=PMOaS>f3s8W&rdJa[VqYpKcXdP`PU! +s8Dors82cp'D_:um?_*(ai_cIaNDZF`o+oW`l#d:bfn/E`5TsGb/18V=Dk7S_o9gAaMu3= +rl@=L_8spCa2u]UPs0PJLOXu&1X"7m_o^$C_9'U8dEtjGW'mW5bf[uEah#a@f0:iT`luZJ`Q6-@`QQ]N\\G_fe]YtTb/_WHceQt'nFQ8Enb0r/]Y_S*`59=,_83k$ +^;9f]7_d7HqYTQd[Ca,jbJqB6^V.Cs_ns.%]tM)'o_nd\gVUD2_7dIr^V%D!^V@S!]=bhk^utUd +oBGA_m+9A"aMuBL]tVV2hT.^saOADdF@p@a6Aj4>_8jF5`kfL:fh73d8[6FZb/2KGa2u2ZH+_;<`Q$*Gb0n?AbJVE;Y%(4$9jXaaqYpNnpA]X~> +rr3&tq>C6ls8N#t"oA9!kMk7qrrrE%s7uKghu3]So_8=a;uZ[hs8;fpr;Q`ejPg%:s8;]gqu6Wq +rr2iqqu?Hjs82Wgq2Ag=Iu&]3>*Aj_s8)ZnrVuops2/'DMJ2hbo_nges8VfmrUE$jE-42.pAad_ +r;HWps69Ljs8Domi5NXQeboCGrr-7(qtTg#LO"#_EF1%,#6=o,!s8`4#Qk&,#6k>3!!NZNA8P'X% +1PeBqs8;oqs7lTlF_?;ZJ;8_WX8;epr +;ZZos8N&urVlip#Q+Q$iU-4+h#@!<)QiJ,~> +qu?Zp&H2V-r;HZpj//TOo)JahrVc`q!ri6"ir8rW'`In*r;Q`ps8;`nq>^H.VR#%Rrr2iqrr2rt +3;NUKs8W#nr;)=ZKm\]-Jl@[*r;ZZms8N&uqu=H6WekEds7cKlqZ$Tis82:HD/OARn+m"Xs8VHb +rr;us%KHG,s8N&si5NUPec#IGrW)oqs'X^!_o'F3\qb`\H@C3fG^+L[H?a[]H@'j_K8Z,9`2n9- +H[^<`GBJ%RI=69`H$XgaGC>@8`kng:G]\4QI=6<`G^4X^H$Xd]G'A:`P+fb3`l,m5p&G'jrr2lm +k4&E,rXJo'rqUeCCN!`[q>U9hrr51Ys8W)ne5`W:>5S?rs82ios7u]nF_-,UI>*/NXSr2!rVu]n +s8Drrs8W)ts8VuqpqXSQ[ArTgs82iqs814C%KH>*rmdd3S=QnSrr2fes*t~> +s8)fprr3#tqu-QppBU`l]PLn\VRcZJs2b5_s2O$==j"b%_og3E`P'@4a3V]K^iN@VMR1.Cd*0MI +_8aR=b0S)P^;\73_912L=c.idI"+e5f?DFT_oBX7b/r;07Akf6e'GnQcG@?:^!bEX-Z!^8,Ke0V +^;e7nao]Z(`q%2X`l5sAbfIcEaN)9Cd`Au6]"?M9`lcHEai_rbdbF9_oC;"T\@of'aiVN<^qd[t +^Vn%-]Xtkja8#JgZ*M![`PTU.\@K8e]>2;#^q@%`^Vo^:kK^cP^UV.t]=YbhqnO#^]Y(hrg%b4/ +m,ZLZf?)(S`lcZA^<+OTa>h>ha3;k9:MOiQ3S)R"`lQ?LaiM]FagFU:NBYb3^sC3M`l5^ +rr3-!qu$KorVlis&c)D*jQ,4os8W)urqZ?drr<#XrW;uiq#14+rqufms8W&tpAb0>ki)O@s7c?d +qYgWtrVufmrr3,rnO/(]re2bX6gO^Nr;Zcrs7u]h:8Xp`l1b2Ss82irqu?Zks-HH*Dg"8Ao)JXc +rVlisl2Gc(rVcTN`Pf^Cq>L?mrr)lrqt.[ZH$+.G4YJH8+s\E]-n$Po-71/i-RL#_,8_G:C.13I +1bggG3&`fU2*3cY2)-sD/O!H&E+hm+5Jb5X7=h91a2HE--DbeFEM:s8W)s +k3W!Es5ukje?$mf37brrW)rr7_,Mr;HWps8W'.rVliskj.g-kNr6Hs8Vofs*t~> +qYq3-r;HZnr;Q`oq66Wif_bXHrVlfrhubV.[.4r;ZQhrr)lkks'cNLk1##<;6Cl +rVulsqYg?jrr<#urX]&*g:t;3UW!0.rVccns8C[N!<;op&HDb0s7NaoS=64frVZ]pp\smdJ,~> +rr)irs8Dor'DMA'pYC:*=GsT)aNDZHaNVfH`Snm>b/hK>b07rG`l#sC_9U3?X@ZT&S%[.kb/V96 +`lQqX`1_g"G6CjlGC[gXk36iniPOh:(3M`:W]Zg#_M]kht@XiS`\WiTB:_ioT4V +hs/kgp$M2+cg9?,a2lEId(@$8mE#7GrlG&\rl@(=b0AGbasgh?D'WN8_TU-Bbg"JV^rOC>>'uo@ +Oj(hnaNDT?bfIgVI=I**H>GXgai;0:`QcKGrl4uZs2G\oaN(H(5r(D\EkoT4_SO"4dELIgrlY&X +&&uT.c+@[e:Jk5IjRi +rr;usq>V!)s8VlMlK8-Hrr;okp\Fgfs5X([r;6Ejs82fqrrDurrs[*?q#CBmrV6?grr;oos8;j) +qY@*iLOk26IT*BAqu6U*r;QZgT5^i[MYd;Orqu`nrr2j-qk6],G[ODCrVcZfrVulps69M&s8Dom +i5NXPcLq/9rqlQls8Mc/KQqZ\F)u>>D>\5MDZ4JNC]A)WBP2'NDK]i8E+j0,DuOVODuFMcDfB`= +FE2A?DJj<.DfBZ6Df'FlD$FotE,TW3ErC+lI#H>@q>C9mq=s";rr<#tqs"(rpAb0js7uQlrUo27 +Ecu@\h=(@CrVuorrVlis)#3PlWi&efp]('hr;HZcF)$DcK8"_Lp@nRd$i^)$qu$BlrVuosrVlg& +qWdPAmFD7:rr)iur;6EOrX/T&rr;usr;6Eirr)itrqucq"Qo=Jm+Lk-J,~> +qYpQprVllsrr39%f:AbDo`"ggrVlrurVbaTrr3-#rVlcprr;rr$ig4uk*^Hn +rVulrruV.8W)84rJqSSMXnVbnrr;iprqE%&WI0R"r;ZcorVccrrVud"T1X0I?;UFrrrr5us8Moq +qYpEmrVlisrr+#>rr2rss8Clp_o:=/rVlisrr;lns5Cc2`PfX0_8=(g_u7FO_>qFN_Z.L\_Sa6Z +^W=41aMPsr_Z.OM_Z.OR_>qLP_Z%FX_Sa7,_8=(,r5/KM"N&*q_SQ5g&AZ3Us8Mios8;l\n,3+^ +rr;Qgqu?Zp(\Rh.r;ZWks8VoT4`GIZ2r*p%s8N&ur;QX8rr<#nmmj4L;"XS`r;Z`ps71/BJ:rB' +HqsG3s8Mio&cVb.rVlisro:o/\[&.+qu?ZprVliVrWE3"rr)iqrVm!!rVc`prse_[US"$GSDX2C +s82cmpA]X~> +p&G'j&c_at[TusKZ,"`lZ??`59[@`6-1"au[V` +`PojBM*QE6JU_c0PK(J]aNhiF`Qa$DSS)]dcHseVa2Z*;`lH3Fe:p&"Cf3CKe]u:RbK\2KbP]N_ +aT'71`Q#p=b08#J`luZJ`Q6-@`QQ]N\\G_fe]YtM`QQNHbhgq'lg3p(n+-,GrqQQhrqHHcqtCcs +o^_LomeH8FqY'g^q"XRVo_/"Wq#C$lo^_SBoC_kWq#L3cpAF^cp)!JroCDD?mc2a^h8mO\dEg+K +^<=U;aNF(p!64uV<6!#%bf/)VaNhW=bLbCg.:d1%,JD%:`l-$Fbg4V[b/D6r.aSj*Y +aSs0e_kg=&8Q033lMC/Go`'F~> +n,EdVjk]n8s8Mihq"t'is3goHrrV!;lMgedrql]kr;-HlrZD%;q#=eXLPgh9IT-%?r;HQnr;HF] +Vl!)\s8D]gs8Dlprr!B!9O;Xa>^c5>p](*gqu?KVrYY\6rVGHk`5Bmprr;upq#16lo=fj!EcQBq +H2MmdG5l[jDL?YHG'J(RGk-1VH1?4WGmf(\cggo4s8;]dipZmH!rVrnlMaNXq"t$err;iflT&m' +68rTLr;Zfprr;rqrr)fqs8;VRI&D"Sr;$9is8DlM8V2\KM2$MFrVuirs8Momq>:*is8;iqrqZTo +nE003f)G[Mr;Q]qs8)foir8uU#lal'rquZjr;QZp$3'o$s6T(Eo'"p,rrE#ks*t~> +nG`a_XIZ!1p\b$hrrW2trR(TKrV!Cq\Erkdrr`9!s8;lqs8Duss8O2=s82h)/qSh3J::Mos8;cj +s8Dun7]3%Rp&Fs`qZ$NmrtGD1rVZ7Z>\nXgI.[@7s8Dons7lHir;Zfr"9&6!s8N!-s8N#trr;rT +`P][Js8;iors8T"rnkN-`5BOb_uI[S`W*mV_[*ot`P'40_8aIb`;.=@`;7CO_@62=s82`ks8VBP +qu$Els7?6es8N!Es7cEhqu?]pp[("\DEp*no`"mjrVlipr;HQls8W#iO*IC:Rf3-_rt#)*gIH^D +I"d6'Q2gm]rVlWm'DhY,rqZEccF:9oU"]GCs8W)rrVliVrr +o)B:"qU]^a,Gcc4)IbehI!askEO`l5p:aNVoQ`l?6H +aMl6Aa2Q6MaLT's]@P3G_8FIAb0/Yoh!OIrnFHSMs763[#O;*Ulgj]:o^VPKo'u>Jndt!4mbc7/ +bKnY_\%^&*`lQccF2H_o9dBb/h]Ha2Z$6`P86Y/LNS>PJY;Y`lQBJ`l5sWa90H'b0'_- +( +nc''ss7kO5mJm4aq>:'err2rGrr'dW6%"'5K7?/*q>C6k +rs\LFJu!Ffo`+sfs8Mrorr2j,rq%gdDJh[dq"sjdrr;ipl2D"hrVcTN`Pf^Cr;Q^(r;-Blr9h+J +FE)ACqK2=Os)\HiGB._KG&kuQ$[dr\med%aqYU!Gn,E=gr;6EWrY>2,s8;iqq>#ItEd;cOeare> +s8Dlor;IZ6rr<#sohDHi7.BpMs82imQ;rZrMhP6$s82KgrrE&tq[`W)rr;ros8W&troWV;iT:(= +!W2lqrrW)nr8R_Ur;HWnr;Zcrs8N#trrq-@mI0'+rr3*"rVuljs*t~> +nc&gmr5bM)\bZ.&!ri/sci++#S[-<1r;Q]urVHQoq>UEo%f6+uo07JFK7n\>`;9B1rr3E!G^uT/ +X7Q>jq>^HlrVmQ1rVcZoo.4otCd*7CrqcZos7u]krqufprr<#trX]&.rr;utrSYZ4`7Fk^qYpKo +#QFW"i53=I`;.7@_Z.FV`PfO+`P]I<_@FAto`+shr;$BmlL+QIrVlifrr2rqrX\c&s8;iqqYPb% +F*_lMeF`b?!ri/sr;H]prr3o7oLl'^61=RJs82ikPu<3eL4N +o)Asnq<4/LW%QeB-.]r5KDka2uQWe/)_+?n>^7ccF;NaM?%!aSs<^aSa%'aND`L`Q$-GaMl6A +a2Q6MaLT's^"CQK_8FC>b0Ao$jn8BDnbV_GnGhq]oCD;9oC;4qn.=X+kh=2#bKJA[\%^&*`lQfi +>c$WUqY0gXs*t~> +nc&sqs8Us;huE`Uq>C6ks8ULGrr38XjQljGqt9mdrr3&srr;io*rGp9qohNfK8##'=S`!os8;ZM +=0.ukp\ascs8;lrq>LcuogqtiG]6MEr;ZKirrDfXrWrQ&rVGHk`5L4)s![mCr;Z`a\qYHPF`qqP +G'A+RG'A+RG'A+RG'J4UGBe:TG'.hKH?sc6G<'hjG'A+RG'A+RG'A+RG'J4UGBe=VGB\4SG'A+R +G'A+RG'A+RG'J4UGBe=VJ!&7Lq>^KmqtK+=rr3&tqu#aYs8N]/qu??ho/CH(E+3SOs82WhrVlfp +rrN,trr*u8Zsg4nGlIL9s7u+JMhcn;HVXD1rVufqs8Mrnqu6Qo!W;oqrrh]Wp$^!$rs8Q"rr<#t +qt^0Lrr;oorqcO!rr;utnDEEnlJqjC!ri&qp&BO~> +nG`^kk,+oNhY-mI!ri/sd/FFLpU7'-iVNQQs8Vuqs8)`pruM%;s80r+M1UG6FB85;qu6Keh,C;C +;>9tbq>^Blr;Z`p$iKZg:18<`:dG$[q>UBpp]('gs8W#rs8W)t&-)Y.s8N&si5NUPebf+:rVlg% +rVliU_Sj=1n\k@Erko&Y^r+76`5KXb`;.CB`;7F_`5D6Irr2rps8VBPqu-Kms6BU`rser)s7QEa +2JdAQ?to-1rqllts8N#rru_7=rr2lnZX0bbFoM77s7kqDLP(#*GYIr.s8Vrnr;Q]q&cV_(rr;us +s8Vi0[_BGFp@\@_rrW2trr2rWrr<#rrqcZprXAW&a/,H!Su1cKq>L?mrq?AB~> +o)B3uqX)%5=')!,`lQ0=`lS/%d`=Ae_745SqhW4D*q"4.Jr:BpY#Oq0Op@\"IoC;DIoC;DJo+:$-jjqGl +bfeDX\%^&*`lQ_p-$HbTU;&@o64ThpBE]`5]m@bK%WCaN;TIc-_bOUip5$bKJ>X +aX2CgK7Rque]H(aao9Eb`kfR8rm)A#]tD2!X&(T86oh'P`5T^8aNVfH`Q$iWr5o#\rPnlY&'Du0 +_hD;k9N,fSoC_nWrUg,?~> +nc&pps8V?UBqrqu]Arr)j$dIHB!s7lHirrN)rq>MK5s8)`op1\;qJVo.MUAXids8?Jk +V-M"3s82`mq>^KjrX]&.q.Ma2DK\Rhqu?Hcs8V?_#ljl%qV]?2`n(+gAcDK&rVuDsL4+>kF`MSE +FE2JDFE2JDFE2JDFE2MFF`MSEF`DPFEH$)BF`V\HF`V\HF`V\HF`V\HFE2JDFE2JDF`V\HF`V\H +F`V\HF`V\HFE2JDFE2JNOkBC+s8W)qpuCiBrrW,qr9=1squ?]ms7qUDF`VY1]_qU'qu6WqrVc`p +rr3r:rVc`iqd>bn:tG@=qYOfFM1:A2<5A>0qZ$NnrrW,qr;?R0rqZTop%%hMe`d&4rVQKks8W)q +qu#=Mrr3'!r;?Nj!;uir"l/>'ki)(2rr`8uqu-3fJ,~> +nG`pppUZih^\Ig.rr2rtcMe%Es6Q;b\+BRu"oeH"s8N&rrZ;+;s8Dutp1J,nIt`G>T_\B_s8-/^ +Tj#G.s8)Zlq>:3jrrL:!ds8W)ks*t~> +nc'1!n_]:&;gc6s`l5p7`QZTLdE"5`a/MR2?`1lea2Pp4c-FDMaND`LaMu*@`m32c:0;moMh3pH +f#YhQe4GUn9rZCeb0%iDaiFA"s2b5_&C8bQ9-\(YB/?F7d_NN8a2S%touJ5o`luZJ`Q6-@`QQ]N +\\G_hf$).O`Q?BHf&Y<1ki_4!mf)\SmKW.In*fT/nF5oBmd]cBmL\8"eS_c,muHaN)?@_ns@4bfe2Pa3mP8V*VZs2b2Zs2b5_%Euo0Y?t='<*tdO +qY0mXs*t~> +nc&Ufrr3/Wm,%dBr;Q]urquZkdf04F!pJ7uqu6csqu-HhrZD":qtL!dq*p-lKRo+WqYguqu$Eds*t~> +nG`dmqr+6LWUB`brr*$"rr2rErW`<"_kaKaq>LB>%:Mg];brVHQoqu-EhrVlg-r;6Hfs8W)tlG:*B +U:gErr;Zcqs8UdOqu7-)r;P!:St)OPh"UaFrUTu=~> +nc'0up[,\#>@XkO`Q#m5_p$HLd)\)b_KALLICRJ@`l5g8:=>&+Fb0%94`Poj:rQ+u\rQ$/%`Q$-GaMl6A +a2Q6MaLT's]@G*E`Q$*GaO/\[`n8hoh"on%h>Q41h$;lphVHuEi7l]:%ahl=e&fJIb0A/>^rsa: +rlXfQs2nBdc-=JT`l5R0a33,[88;sT5(1r.ccX>Na2l9@`k]=+a3DiOaN;Z+8=br;hUU4B@WHjW +HsL14aiV`Fb08)P`P975cdTqQ_S +nc&Ugrr3)cj4mZ(B=@3qV]?2`7"P^s8;]eqY^6^d_*3#rk2.B]tV1o +]tV1o]tV1o]tV1o]tV1o]tM(m^V[e$]>)(p^;%Cs^;%Cs^;%Cs^;%Cs^;%Cs^;%Cs^;%Cs^;%Cs +^;%Cs^;%Cs^;%Cs^qJ\"r;R#ujmW3Ks8;cYrY52.qtg-T4)o1_75s]8o`"acrr)forZ(k7rr;us +s7uQjFH!/3Xn\eJMMd+FE+&D5r;HEhrs8W%r;Q`rrqQ3drri#]p&*)6rr_ulqu#.H!W;rqrrrE" +q=sa^rr3/alg!cmi;NZYrqlWkrV$8A~> +nc&mos8Mi'URK'rrVlcqdf'aTrr2WbYHkUmr;Z]pr;HWpqu.W9q>^Enq#A0,IY<6!L+APcqb3]` +9^29Js8Vopq>:3jrr2p)rR*uHEG]MhfD>LBs7uZms8N!-s8N#trr;rT`P]XGrqu`ns(D9.r8l\l +gu7,Hh;6uEh;6uEh;6uEh;6uEh;6uEh;6rCh;I8NhV?uFhV[2IhV[2IhV[2IhV[2IhV[2IhV[2I +hV[2IhV[2IhV[2IhV[2IhV[2IhVQoVrr;cirr;u]mem%_s8VKc)?'R6s8Dutr;,_>D/4/W2"(D; +s8N&trVc`ps8Dp;rVliqrr$knUh-V$VCdOUItVTCp%SLcq>^Hlr;Q]qs83B+rVlisnC,"V]U\Wj +s8)Tlh>RESr;QTn%K6.mZ)!q^TY'ahr;HWcs*t~> +nc'1"rV5?#=]'OW_oB^4_p$BJd`<*BaNM?*@8g3g]>V_3`lZED`lQ7#are^J^rOLAb1N=KG)1p+ +K,/ORd5.&c6d +n,ERfs8:^A\?!WW)rrs6s;7BRf`DG,fkE +q>UEls8W#ss82Wk%fHA"s7o3!GBRsr_Yj3/kl)G!rVcTN`Pf[Ap\Xmaq"OXbrr2HSm-!m.o(2\I +rUL'\mI'Vpo)nONo(N%^#lFJ[n,E@er;>dX')DP'q419'F*:Pbo(i=^r;Q`qrr42>s8Mrqs8N#t +s7cBV9<+sgnOS:cLP^U^[J]t&r;QZls8W)trr3`0r:^-iq +n,EXhrRRaBXS;Ylrr)lFrXo2,s8N&dS[H<(rVQWprVlisqu.]9s8W#ss7lD4Bn1_eI:Rd!Quf-J +L&(cKr;Zfqs8W#qs8Dp-rVuQjpdJ_6EG\1_rVHQnqu?Nlr;Zcq%KHG,s8N&si5NUQf`1sKrs8W& +s8;osrVuo_rr)j!rqcNld/FOTrVucos82fZmem%_s8VWg!<;rqs8NT-s82S\8oSZg;-!2as8N#t +!<2ut,5hK@rVliqrr<#pr9R"QV+pDJIt*$%Hr.0Irr;rsrVQNkrr3'!rVc]p$N/Vi]=+Z_q"jsh +rVlfrrr(dSrr3*"rVlforseo$eXrA*US?? +n,Emon#9f%?a[YgaMGd:bf\AT'?S;?aMt/HOb/D?A_u7UTa:cY:_oogBfed2aG\f43dE'SR`rg1`l5p7`luZJ +`Q6-@`QQ]N\\GY`dE0JPbfn>Qa3`5gin<5GlJVX""5qtjj3ccoiSDVu`5p$?bdkU7`l7r"o#LmP +aNFM+>0+_(_T^?ZL-KNsF%ARAbg42HaN;NFb/_B=_o0^Bc-4;Q_p-7ZR$p=p0m%brLO;OZf$)=T +`Q-$Cbf7Q>`lcHGbK.N+I6/u40m:(KdF$.]b/hTA`lcNJilD8Hb0%`Drl"oXaSs?^a9obM=%>eX +?aK.nrVlg!rV66fp]#a~> +nGa$uqu?]]j5]k5s7lWoqY^9>rW3&srVluicL1N-s8VrrqXXUsr:EO4LP:J=4QK,9VG@!drUKje +rVlg/pPhslDg-5Dq>:$bs7ZKgq>]p_&-)V,qV]?2_pA)Qr;-3_r;Q^!r:p$]q=4@Pq9o-Bq=O@W +rVm0&qr[AGs8W#pn,=(%q>^Khs8W#mp+U!$EcZG1FSPk/s7-($s7cQgNdRmQEE%dHN.bncqtp?e +rr2p)r:fp^s8VK\qsDo4rs8K#r;ZfpqtpBls5O%Xs8Vusrr2p#rr;ugp\t0rk3D1&kNhsDs8M`l +J,~> +nc'1!rr;of\tPkDpAb$is8DutdJa^Rs8W&kd@dqjqYgHorr)lsqYpHnrr*K&8:Z;BJV?/E8>r:W +qY^Xs7uZorVlfrqYh--qZ$DP +HDYe&;MKXSIUmBnr;HTorr2rtrr2iq%K",U\@&:.qYU3jr;HTmrrW,qrSmhVrVlg0rr)fms8W&t +s7cAnTpMOI\b?%%rVulgs*t~> +nc&sqs8VcEM,dB.\]Xoi!QN=1a:lb;bg+;>L.GBb[DU21ai;?>aN4A's2Z"r`Q#p=aN`$bH%q*. +IP'#/S<>\\d)jB(`r3srb/hK>a3N.W89f3!AmF!;ccaMGc,%3;aN4A)s2lS+`P]U5bfn/IaN2E@ +bL4JB^UUc%bfe8TbfduEaNVuVc-=S@d14^\f#ktN`l?*D]>W"7`W"$Oa:?5/`Q5sDbJVTJb089M +<;pqIED9T`cG7H=`lQd)X,C`Q$'Eb/M9;`l?*A +aih5e;_BR_8$0YOc-FJVbfIc@`QZTLilD8Hb0%`Drl#GebL"5Jahbc/<'EoPIbXPmrVlusq"js` +s*t~> +n,EUfr;ZHIk26.;s8;uor6YEJs82cpr8-E.rr3#os7$!urN&nLKnP)-:O]?aVXXW`nbs@)r;HHk +Jm32>FE;7GV>gDms7lWoqZ$E^rX]&-rVGHk`5C!tqtpgUps/m=!ri/rrr3)uqtpBls5X+XrrW,qr;HWtr;--crr3/alLO9"q"Xjh +rq?AB~> +o)B=$rVuosps5S,Xml;hs82iqs3U`Qs8)ZnmCfL8h"C[DrVu`nqu79-s/f+IJ:E&q97*RSVXjcb +rqQNjrYPV3r;$AC=)2nrE,$btrr)lsq#CBks8)Zmr;Zcq$ig5*s8N&si5NUQf_YUPrr)fprr<#e +rpp*:rr2p+rr)fps8;'Ir;Q`qs760hrtP>0s7lKkqtL*_5=B:"FDa`OFo21:s8Drss8W&urVZX- +q>^Knr^TS"?1EbkqA +nc'.!s8Vu\W`W&/ZGXl*_TBgFa:le?ai)3AXDgd@NjH^EccX8IaN4A's2b5[!6+rW&^&IY6%"E@ +IWe8*Sm-fabf7a!`r3ssb/hZ@`5gPD:2bK%CKh7&g==Nq_T^- +n,EUgr;ZfTjOO5/!ri5sdf0:E$2X]%rr<#te*$&rrrMojqu$3f&,-#pKntJ=Gu1?+L?no`+lg2/75VI;N5F<8.BOs82?c&cD\(r;Ea/Y_c/3N.Q@[nbrFarWE)qqu6Tp% +fH5%q>1$Kk5Xu%s8;opr;QlsqtpBls5X+XrrW,qr;HWsqY0jcrrqfNmdfMprr<#rnGe"~> +o)B7"rVlisr9:2TRbn#Cs82iDrXf,/r;Zcos8D;\YIX?'s82fms8N#ort5&+7tH>EKm-:eQW*b\ +q#C?mqu?Kk*<5m8s7hh'5?_oDG%O.YoCi4aqZ$Tks8N#rrr2iqrr*E-rr2rss8Clp_o1+'r;HWo +!rr9!qu-*bnGgo8rr3?)rVc`qr9*JFs8VTf)ZTg:qYpNppAb,j2/$uMG\C01:tP^Gs8;osrVcit +rr2lrrW)utrXf,-s8T3/WeO9%LO=5HnGN7ZrrE&srsSf"mD?3AYHduqs8;lr!W2fnrrW,qrSmeW +r;HWp"TJAtrr)ir$2jA-St2OHVsO<[rr`8urVlHhJ,~> +nc&Uerr3B%ctQHYS\`=d`6$'Ja:QM=b/VB;ai:DY;IHE9bf%NraSs3Y`W*phfe.H%LPC%PVNM`P]U5bfn/IaN2E@bL4JB^Uh,2 +d*9k[`PfU1b5TTdc-488`X^)7bf7WA`l5sA]>i4;_u@gMa@!ta_nO(6bJ_iYL)X91F+8()E]:AP +aN;6:`lQ +n,Ejnqu?]ch;7Q!rr<#tqpPKDr!rT's8Dcls7Fk,qu?ZlrqlWfrX]&#JR=1\LJX&5>fZ[>s7u3a +'`\13s8;Tja[B3PEcQLg;#L+grV6BlnbrmqrVcTN`PfdIrr2os!<2`m%fZM-s8N&ts8N&ts8N&t +nbiFd0`V.Prr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;uqr;QZp"TJA^ +n,;VPs8Nf1pAb-lo07D8Ec-&AJ+<=6r;HEjnGX!ls8)Ef8X-5TI"%#dJGT6Cr;Hfrq>($hs8W!+ +p](9Pmd9Yts8W)ur;QZp"9/2prr2rXrr2p"qt^-grVlonrVlg#j6,n!h=CRF!VuW^s*t~> +o)J[f$ig5&_P*^:p%A=as3^iGrseo+s82Wls4!gIbl.A7qZ$NnqYq-"J6[_OKhdT,=i^=;s7lTm +qu?Kk'`\(/s82Hg`^*OBDJse\;#L(erV?Hms8E)urr2iqrr*B,rr2rss8Clp_o("$qu-KnrrE&s +rVud*rr;utrr;utrr;utrr;ucs"+0Lrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;utrr;ut +rr;utrr;urs8Dp$s8;'Ir;Zfdrr)itr:g3j%eDi*C2Ra*Dg^sFrqlZirr;rr!WW/ur>GV7s8N#t +p](6fr^;gE<-NVB@Xe1Prr<#tqu?Zps8NH"s8U-\\[.mrp\b!i"8_omrr2rtr8IVUr;HTo!rVrn +rr3T-q;83CStVarqY^?ms8Mrprq-5@~> +nc&UfrVm5iNa#b6[CXB!`l6BI&B`AB`PoX1cH1o:;09=__TV\prl4uW'#r,7@7u-"Lf9M>;Qn0Z +`kTU9qo8HQ5K_!dbfe8mZT(d"CM7N637uF"ahZ$=a3)WNbf[rE_o'L +n,E[lr;Q`rg#:W_rr3#srR1ZRr;6Kns8DutrVtg7mJd+crqlWhrXo20s8A-bM264RTp7q=s8)cq +nbrObrr<#t$i9GcEHc5@Eckr"qu6TspAb*]rX/](rVGHk`5^I0rqufkrXJf)r;QWnr;QWnr;QWn +meeU7r;QWnr;QWnr;QWnr;QWnr;QWnr;QWnr;QWnr;QWnr;QWnr;QWnr;QWgrWiDcmJHn^s8VWg +!WVuort+hs8o/KcFEDP3Fo24;s82icrXer%rquZU:KXTV:5*,2oDeddrW<#pqu6Trrqucq"S:L; +o[3X;"8Dclqu6Ttrqu]nrr;$Xrr3)tq>'serrDoprrr,Tm-*WarVlonq>C6mrq?AB~> +o)J[f$ig2'j/AiMf_54BrR(TSs8N&tqYU?,q>U_DPGrVuiqrVuiqrr3T)d^R!.Sal^Zs82irqu?Tlrr2rTrW2rqrVlrsqtpBm$iKk? +Tq@gLU[e-WrVlirrUg,?~> +nc&UfrVm5r^2@CaP./BO`5U0G'["bI`4Wt1d)EY<8m%Ik`66"r5elW&(&U?6%Ol7=/(j: +i7PoebONY<`6ZWNb0A>\h.(J>EG]Jh5LS$/ah>d6aND`Nb/hTA_oBpEaMl6Aa2Q6MaLT'u^Y7&Y +c-!o?`Q6BQbfnDZ:aNDZGaN2ZH6<0h>:P)VfdFQFZaN2NF`l?*@`lA#! +(rO"Z?S3lk2kn47e&]VJ]>M_6bf[rE`Q$lX( +mJdOls8V06gueY:qZ"qA!W)forsAW%s8CO?kl:\Wqu$9hs8NW*p[C.iIRp0678p;`qu?WbrY,>2 +s8N&uqu;OSE-,o?B6?61rUg*h!;l^#ab]rVd'% +rr2imr;Zfrrr2p#m/-,*g]%6QpB(6fqYgHorW)lSrr2p"qtU!brVllmrr3/ejm20bn,E=grqQ +nG`sss8W&rqS&Ys[e]k"s3U`Ir;QZorr3?&qW+B_]D):%s8Moqq>Lp#p@1+fHq'd078U&Zqu?Ta +rY,2*s8Dutrr7mVDfTT8Aofp)qt'ge!W;uqrr)lrrXSu-rr;utrSYZ4_pnV^rr2lqrs&H$rr;rr +rpp*Zrm(QCrr +nc&UfrVm2sifRPICpq7&ajJ0Db0/#J_8aR=aMX`G?=p=Q`6-4aW,>N8Y2hC8!_NB +bJ`ql)9^1Ia2l?DfPbfIcEaN)9Cd`Au6]"?P=bg";K +`5]sIccF,Kbf[95&]V`+`lcNJ`Q$3`Q63Bcb\#VGtgqdX'oa942JqV`QHELb/VF"`Z<.Ec-=))Il0)73FB&)bf7`F_7db+ +b0A2R`l#^6ilM/Bs2YhmaND`Nc,IT3W+o7*;-fIIpAP!js8) +lMh.fgZ75ks7uZmd/F4Irr<#pqYpKun_W4!s82]kqu6Km%Iu)^C1aPo?#FWQs8DufrYPV2s8Dlq +r:K\OBQn?7J8AG?qZ$EerVuEe'EA%0qV]?2`7"GUqu6WprquZkrr)lerpg$9rr;uurr2iqrWiDc +mJHh\s8VWg(]XI4r;$Ba88iTmDfB`68,)iZrqcZprUKmequ?R$oK7h_8>DnFG$ak?rr<#trr;or +s8N#trrhWXr:S>5rs&B#qtKp^rr2p"rquZjir8rW"8hlgqu-O#qu?]fj6?!ph>[EWqYU*cr;Q]t +rql]hs*t~> +nGa!trVlfpr84HNV;V@Ps8ULG&cMY,s8Vums8Vc8XJsMCs8N#ps8DrqrVum,o.FKcB!$DdCiAhC +r;ZBf)ZTg:pAb'hs8Vih7;-gZDglD'IJEj=q>UEor;QZprr*E-rr2rss8Clp_o1+)s8W)srr<#s +r;X,&r;Qcrrr36$k3`*Hs8MuerYbb7rr)]no1!S9E,'90D+=?ts8Mlps8DrrrVuiqrVuos&c_k1 +rUW%#KL_f15]U0&rr<#srr)itrr)fn$LPU;]Xaa1qu?Wlqu6ctrVZZns5O"Yqu$Em&H2P)rVlfi +c_[2'T<.GTqtU*h!W;ogs*t~> +nc&Ufrr3B(p[Q"2<`YU*aNVcRa;N%b/hTA`Q$!?r5oVqeC2MM>AIiK +DbaYDcdBbQaS!`j<_u`l#^6b08#I`m2?@d`02Gb0':r)9p:B`50mH/RWL?EH?,2 +1!7>SaMuHIaiMR%`rF+$bf[i>_oBd=`5TmJf-kci7AHP=AjOMZ`Pp!FcHO<-`?*%Ae(*!`M*2k+ +5)>b5]Np`lQ +mf*:drVm2bj5]P,r;$;>L.gs8Vrq +qXOOsqYpHdZ;ZF/?%&Sm@8Qpurr2oss8N&r!<2lq)!^_iqUGQFqu-Qpp%\CXqu$Hns8Mrnqu#LR +rr3-!q>'pequ6iQipH6hnGW@eqYpBrrr<#tr;QHjJ,~> +nc/Uf%fQG,r:mb!U:L1!r;Z`prVuiqs8UpSrr2uprr36#rqQ<#Y.1s8W)sq>U>* +AO3;i5_OYRi;EWGrYkh9qu?Qks8W#sqc%'FDJj32F?THms8W#ss8;lps8W)ts![mHrVufR`P][F +rr2rrr;?Nlrqu`ps8N#rrr)iprr)iprr)iprr)fcr%7mHrVlcprVlcprVlcprVlcprVlcprVlcp +rVlcprVlcprVlcprVlcprVlcpq>L?m#Q*ZNr;ZfrrUKk)rVu]ns7uLNCMe'/EcYehqu-Nos8)cl +rr2lrrVlcqrr2rt%/$i#J:LmOUi]s@rqu]os8N#ts8Doo$cg&o\Xr!ar;-?kqY^?qrr)fprVlls +rr;oqrVu?c!W;oprt58/rquflkc12FURT@$qt^3grVuor!<2ZkJ,~> +o)B=#qtpEnrVQBMJ6l,j]uJ+;b5KB]`n&3EbK.T?b0%]F^:%cS?(JaObfIfDrl#esb0%fHb08,R +da^us6Dp8-FE]R\e]c"Rb0'_)r6##[6H7*fcH*rD`4X491feL7FDbr&*n&*V`ko[6aND`LaMu3< +`luZH`Q$!@a3E&P\@T/ZeBlOje'?4ce(3!f_o9^AZd03-b0%uVe'ZC`d_NuQaMl6Co#M`lbL"/P +b/r-Q?YX_(EGel9ahu*>b/V]GaN4>"s2[LKaMYj5`lQ6=b0\P*6[*fXI&Cp[1=F.]`Q? +n,EIdq>U?m!nuc%rr33#s8Voiqu6Tp"8r&nrr2rPrr2ips!u4Ok5YJXqZ$NoqYg?ks8Vlhr;Zfp +p0LsPV/:+%LO2tps8N&ms8MrrrVuWk!<;ur&-$9IA9)d;F*^"Js7u]pq!n@`r=&`'i5ijZg"+^# +cHsr9chu,ucd:"bcd:"bcd:"bcgK.4cd:"bcd:"bcd:"bcd:"bcd:"bcd:"bcd:"bcd:"bcd:"b +cd:"bcd:"bcd:&7dKIq?nGi:_s7$!ts7u]ns7q1DF_l/3Ff'$GrZ_C?s8W&trVuWlqr^A&LPURI +VQW0VoD/=`s8W)tr;?Nlr;HX'o'>r@kOANMo_eagr;?Hks83-$s82ipqZ$KYrr2p%r;6Ehp\4L_ +rrqrOm-UNqr;Q +o)AdjrVlfrs8EB'hP6[BhY.!Kr;HTos8;rsrr3#urSIPLs"=?H>2B3J_]Df]i?48]'Qs8Vops8)]rs8N#r +s8W$,s7tQl_8k3]e^2Ufcd)I7!77pqqp,5f"O5$UrV-^EnpO,eVAT)$uUMTo/oDTX- +qu?Zns8N&ps8D.KKS+r.4/&c@:A4Ycrr2rsrXJo,q>1-hs4b?$[]dmKrr3#trql`nrr[PsS"HP:-hrqufqrq?AB~> +o)Adgo_A@a'(`YK:0dmHK#AScF">8>T:aNhoC`l@kr ++3)CC`l5p:aii/^_6L5Q_nN[gZEpmAZa7'GYcb47Z*Ue8Z2_-;Z*(72V9%0,bfe-!a:cY>cGduK +da2;]ARB.Q@usF0`q.8.ai2EB`5op>_pR#V0n"Y+GrVb,0/(MlbfIZ<`lucTbJh?_o9jDb4E[h`l#d>bf7WEbfRuMZZf/;9NZ)E +jS/ZR!rMimnc++~> +n,EIbp\t-k'BS05li7"\s8Voiq>UEorquZjrr2rVrr;oprWE)qrr)ir!mBj'rVn,>r;Z`ps8W)q +qu$BkrqfPeZ(F@7K85=SebT7@s8D`lqu$?]rX\r!F\5D5C6ks8W'$r;6Elrr2p(j72d&iW&rPp\XO\#QOGrrVuoos69O_rs&K#rqlB_qu6U!jl5aq +h=LIB"9/5rrq-5@~> +o)AdjrVlfrs8EB(osU<^^\@^(qu-Kns8;rsrr:gRr;Qcrrr3B)rqb`M\'4UHr;HNlrrW2urr2rs +rW`>t:.h[]6N2QFKgX5\s7u]nq>^Bkqtg +o)AdgoD&7`'):=>;GD>Fai_lNb/hTA`Q$!?rlX$;rl-b8b082P`4).-=ECab_SjF7aiDQHaMu6@ +bfn/Sgc\$(PrO)=Ll"1(bK@fMa2#^4`5TmubQ>r.aSj*m`Q#p=bg"=0/N-0j7guoMcd0YSc2GZ^ +aT'E^aT'9[`=U&2b0eVV]u%e.`l5g2_o'?j_u7RS_[4/p_n"+Db07oGo#UjR&'rD?ahlWRF=8t# +4(bf7WAb0/2BX'A%a:h,pCmJHq`rVQHi +nc++~> +n,EIdq>U?m#lNf?gAh3Ns8MupfDbgJ#6+Z&rqu]jrVluPg#W&0ruM"4rqZToqu$Kor;$Bcrb.Ck +=EfLQLP1=rr`9#p\Xsi"RkaI +nBCn3!r`#oo)8mls8)]cs8Mr[rr2p+rqlTjrVcceh<"7tg&:pOqYpHnrr2QiJ,~> +nc/Xgrr3E+rVcWEX.?*DrVHKlqu?Nl!<;$Ws8W&s(]XL6s82irZ`CUlq#1*hs8W#rrr<#rr;Q^- +o_i?\Uf_hpJq8B"1&ghAqYUL?irqZQtrqQ3_qYL0g +s8Jtqq>:Nqp&G'js8;osnbs$ss8;orp]'m\o(2VKqYfm^/cYeLs8;oqqJfVjJ:iK+Imfd);U>C@ +rVuosrr)irrVlispWL:a]q+`lrVuorrr)lprr2p'r;ZZno`+pgrquf`rr;osrr)j-p%QM&T:VdQ +lMLPZrVuosr;Zcqp]#a~> +o)AdgpA4^e%/B%kCf=K(`lZHIb/jP$s2b5_rl>)ZiQ)#Ar5]Spbfn>L^pmlQ?\b`'bK%]Oa2Ps9 +rQ#hqb/E.7KUkkVJ:ic9J0s0sb/hcPai;?Gr6#&\!QN4Y`Y$;7bgar[JS8V/aOS_\e&ohNrPnlY +rlY8^r5Sc["jbWEd+HtJd/VOnd/_Yoec45#eHjUDdEoqS_T'Uda:QM7`kom;_q!&ae'uspcHXN& +a90W,ai48!/CMqsc-=JTaN4>"r5]Pk +`Q#pC_8Nq+b/h`F`P][7bfn6!aT'BnaMl':cG[AI;bBbfDT(W-rVlrtqu-'bJ,~> +n,EIgr;QWo%e\K1kl:\^r;Zfrqt^'crr:gRs8;iq$NBtus8Vurs2=$_rr4);pA=[cs82fqs8;]l +rOZF +mJm4c%K65&o>dQ!\G,k!s8Muprs&K$rVlfrs5EtWrrE#qrX/N%s7-!XT"2Pro_ndoqu6TprqlTl +rt>7=>cEo[Kn"f.J:fk(rVZ]gq>UBoqtg9ns8N#rs8W'/s8Dcio(2PJpAb-hs7u]mrVuZlrr3<' +r;Q`orr;oorqueprr)for! +o)AdiqYU6k%K6"hes0WDCqIX.b/h['`r=$Zb5TK^`o5#"&BN#@c-=_`dalsndEp(_`R"J% +s2b,\s2b2Z$-1'.c-F\ccH=3*aJm5[ao9K^bQuS=bfIfD_8jRda:HG0ahka1`lZf^g!A*o_9DGj +*QHCK_o0X=cd/X7H$t6tLP:/&9VIM6d*0YS`l#^n`Xfu7[]"!s-TWr[^!"[CcHQ:/rl4lWs2G\j +`llE@c-ODNb/hTA`Q$!Cbf]Lts2t>^%`Z?&dD3(k<)$+iNo'0srVuorr;QcqpA]X~> +mJd1ar;R$$fAtrks8Moprr`/mp\b!irqtaSs8;iq"TJ?!qtg9k$-;*&p](*aqZ$QkrtkV3:T:'T +:O\+QKR\H-I8fq8s8Vrqr;Z +m/I+crVl^%i2WWMgA:jLr;?Qmrr`5tr;Q]qhu +nc/XfrVm6%p@ddaF')G1^W-/lrlY5]rl3s=3QfRib0%fHbfnMX`6>cuU.n6sQ,1VhcHX8C`Q$!? +`Q$-T2O^'r7sK]AN/<(9BJe)Ye^MO]`5ostaT'EWa:H>:d*'qge'6IccHjSV_TMhss2b5_!mJg0 +rlG,Zs2G#["3/F*a8O)Va8a-i`5]g;aiV`KaiDB@`kod9o#MBc^W"@.^rsj?bKS5QaMbd3o>psS +0?qPWaN;WLgbF##IZSl4Im.1;KUu)/cH+)H`P]U4`l6$,C-!Xs1PNEacdC:cb599Zb5]Q_`XTo, +aNVrLcHF5H`l?*@rQ=]P!m8a2rl>Sh_84%(I8a$?=)5_@pAOacs8)fpp]#a~> +nc/Xgs8N,trqud#jkSnWs8Vuqrr`/kp&+dgrqtaSs8;fps8E)rs8Drs$1-gJ4JW!s82Niqu$!`&-)D#s8)Wms7cQnq>^9hqsj[arrE#srs/Q%r;HTl +rViJg"onQ"s8W&drXSu(s8W&qpAb!fs8;fos7-(+s8DlqrVQWpP?EHnMLL,3Kg +mf*mus8W&qrquQ.TVAgdrr;onrr)j!rVQNlrr:mT!WE#sr=Ao-q>^3hqtS=9ZI&IJs8)`p+8u3= +s8DhWQ#!E(It`P@ +c/h3`UHJDOrr*B,rr<#rrVjaS^T,*HqYpBpqu?Zqp\t0ls8E3%q=sshq>UElrW)uhrr~> +n,ECdrr3B'q"jU@Qrm7&[)'c\aSj9]aSj-rPnlYqo\oZ +&B;i4aN2<>aiDE?`5T^6`Q"ps&B)H$_SX71`Q-*DaiV]I`Q%Ghs2khhb/_H<^od +1 +o)Apnr;Q`rr;QWo#6*N>gAh3Prr3)tp\4[cs8MrTrr;oorrW2rqtpBqqV(02rr;urs8W,r)?0Z' +1lS5(pY%WYKS=]*MLC(Fq>U?mq>^KbrX\o+s8)Wmr;?Tpr;Z]js8VTf%K$)%qu$Hms8N#ts8N"j +rs/Q'rr<#ts8DKe#l=T$rV6Bls82fq"9/?#qsjY's8N#tp\FjW4aMd?GDM<0IRqWTO`!jXr;HQm +rVuo_"Rtm)s8Mus!;#^Z#P[V(nal\Ys69O^quH`orsn>Xkj%9ds8VuqqYBsarpKf:~> +mf*@fs8W&r$NK:iTV'p8s8;forr2utrqlcqrr:mT(&e.1rVlforVulnq#C$5W4q0ds8;ckrtkY2 +PV.]`8G(UrJqSf%Jr+o,7/-WWs8)Wmr;Q]qrVd9's8Vuos8Dors8;opqYU +n,ECdrr3]0q#(![aDY$VOhAZQaN2NJbf\)Lr5Ra;"3Sj3b5KE]at:f`bJV*4Z%5\UK=AqDb0.iC +_oBd:bAS)VbfnA4bn/(<`5]jhlncHOAN^;J@@-Z4KqHART.JO?TjG#gGEdEBW1`Z<.Dah4QN.4%2FXLc6bbg=2K`l5s= +aND`Nb0%fHrl,PmbfG_[Vo5@9iYrB~> +o)Apnr;Q`rr;QZp"o\JghrO&#rri>uq>:0irrW2tr8IYTr;-Epq>:*frrUU(l2CY^r;QZqr;QX0 +o6,5Oq;X_nJqJc3IYTp_ZMX[os7l*_&,cJ's8W#srVlZnq>^Kjr:0ass82cps8N#rrr)fqs8Doq +U&G#j"TAB!rVuBd&-)M)s8)cnqu6WmrVucns7-*gs8W':r;ZAu5_k#HMLgD6K4oB&pGqX>qYU3f +r;?Qnrri/ho'FX"rrrE%r;QNio)8mi?lgZ*r;$ +mf*mus8W&qrr;rq`2'*3q>L6irr2p#rr)cnrr2rVrr<#urr;rsrW<,trVlg'r;HJnYJ'5ps8Dip +)#aC.mW*6>pu4SmK7\c/I"jRYYPJ4js7uTmrVlcqrVd?*s8)cqrVulsqZ$Bks8)]ms7Q?ms82cn +s8W)urVuotr;chqr;cimr<3&tr;HZarX\i's8)cnqu-QkrVufps8VWg!WW/urtG(85D4N:Lk()2 +JnB0$oJYt1qu-Knrr*E$e&9#5T^_jYs8Durs8N#tp&5~> +n,ECdrr3]0qYgHkm$;*ZA@B=n`lQ_rPghTo#MEccH48W`m)THc-XVV +c,7KB`q.84b0J8Q`P]s?Q7IB9LPpV0I=>@#e'SoSgXFBh`l?*Baht#e3[QI>V8LKo]u.e1`5T^8 +aNDZLbf\*+a:ZbK6N[X^e&TGIaN`&Wbf.K>o#MTdaNVlNaND8_<(^"_@?fL@s8W&rqu-El"9&)m +rV->B~> +o)Apnr;Q`rr;QZp%/^))ddQ;ks8Vuqr;HKls8:jTs8;co#6+Puqu$Bkrr4:kkj8?LrVuQequ?Zo +p\OgN=nDKF?@m`^L4b28KO0f8s8;osqoSi2s2"[Ts82cps8;e9>DIfdL4=ko:haqIqYpBgrqQ0` +s8;lr"T7ZWpWid +li-tarr)ls%.p`SLWr;ZfprVuiqrVu`no)JUdrr;`lrr8Gd!<(mUrVc-_!rr/rrr48CF'=6G +K7\K)Dbk"bq>(!cqu?Zns8W#sqYT$]]"FR&qu$Elq>^Bl&c__*s8)cqoSjk.+!lC0s8W)tr;cir +s7?4&s8Mrrs8Drmp9U]hS"Qb +n,ECdrVmQ.rVlijeSSMgNP<>!p.@[rlc,df8^;\+2`Q$!ArQH(r`llBKccpYE$kEbN`luHDc-OYW_nj@a +a;Dq9_TpBKbJh&(:e+)ZEkLc;s8VumqYU6hrr`5squ-9hJ,~> +nc/Xgs8N,trr)j$q>C9eh<3brrri2urVuosrr]nl:MbW9JRh#<[\\BDs8N&p +pA=a\qu?Qns69@RjPU"8rWN9#qtp +li7"a!W2orrY!_JT!7n^s8Dunq>LQ4O!rr2irrr2rhrX]&-s8W&tp\WI? +RA$1Ba8#Z5qu?]q!r`,toDa=~> +lMhOrq#16im&X,]D76pm`6ZQIb/h[&`o"l:`r3mV`W4*Xau.5S[nKY/XM)g#dE'MJcHFJJb0e\_ +B,*I;I"m9/JUUB4f>u+R_T'R6`l?*@b/hQ@`l?*@r6#&\oZ$jN#Kk--`Q#p=b59E_b5]PV`rF0] +bl5cbbl5cIaT'E\bl5cUa>D&abK@]=ahU%t?$^m@<@]bhK3QXM`llEEcH=,JbIY*15V"3<hcg_T0d?d_s+h=?]8M?^fpE +s8W&opA"L_r;ZcppA]X~> +mJm1brr36$q#CBSlIYk.s8MrrrrN,sh>[BQs8FVJqtp3bq"4Rcs4lo5s8W)tqZ$Hfr;6Eiq>^9] +?\qlP?"/P79hVYfr;Zfrs+10Kr\"!GrVZ]is8B_l2_e$diO*V"r;?HeqZ$E`s8;Wks8D'Fo]ap+ +s8Dims8Vulr:p7$s7cQnq>^1>)D!*T.ba[]rr +lMhIqqYpNos7*"]SC$s/rr;uorVlirrW)uWrr)lqrqZR%rr;TUV6\MGrr<#trVmQ1rVZKkqt"6R +=@$+tK6L!]XShtms82fos7?6es7uZms82fqrVc_hs7uZhs7?6`s6KXsq#C(s7lWe-PIaF)(*u0rVclsrr2osoDTd1 +rVuors8)8pU7RpMVX=?^s8N&urr;uss8Murrq$/?~> +l2MCjqu?Zlen\GkNjHR@aiqoMaN4A#hoPf:qo/TTrl?M1bf\/>Ue4L-Y/JZ6bfI`GcH!iB`R;oN +3bgo8;-83`3\,p2bKe2Jrl4uZs2tA_s2G#Xs2b5_rlk>`rlFuVq8``Z`Q#p=b5KQac2Pofb/U3q +"3/F'b5B?\`r +m/ILnr;Q`rrVQKls52ehrr3*!s8W)tr;ZctrqtRNrr;us#5nAoq=sj_rr3AZjSSuWrVZHjqY^?l +rtG5.rVQMoBnV()8A=rprr;lqr;D3GWW!M0rVHQor;QQeahkr$o)8F^pAFpmo_JFZrVm#VjR_]Z +rVuoq"onStq>UEirXSu+rr<#gBI#&D*@A,js60Fns8Mrprr;iVipu3hp&G$hrq-3lr;6Kfs*t~> +l2M=nrr2rto$X,(W94!TqYgHnrr;us!<;$Wr;Zcqq#:m's81QL[b(3Pqu?Zqr;Q]prtPD2s8;es +BS:t(8A4flrVucprVliorquffrql`krr)lnrr)fqrhBGkrq-6^rq$0Xr\=HOqZ$TorqZ<0_89II +rVQQgrr;uts8)cqr;Z`fs1u@a[\!9orVuosr;HZqrr2rtqu.**rVuosmq!Rc%i-=mqZ$Ekrr;Qg% +fcM+rquW=W1KrVT[3Q6rr<#t#Q=Z%s8N&trpp)>~> +nc/Uer;Qfoqu6U(iM9deA"pQM_op@ +b.u-Ac-"2PbK%uVdaj=MChbFRT@1m.cH",H`Q%nus2k>_r5ScXrlY/_s2tA_qo8HQrPnlYrlY8b +rQPAeaJ-]QaSj-Y`W*jT_#_Hno>h*T_nj1,_u%FQ`pUo;c,moEaMc%ag.F(-S.#*UqOOab0AD_b/VND`l?*Bbfn5NaMZ$Cd`Frd*=WDdOjh_Wb5]Zgb/hQ@`q%1d +a2Gm6ai'*>8Pr&eWp&sLs8DffpA"Ubs8Muhs*t~> +nc&Ugr;R3'rr<#qr;6Nog>UfOrr3<$s8;forr<#tr8IYTs82fprrN,srqc`mrVlfup!WI2ru:q7 +s8;fls8)Qkqu?TiqY'[`rq6$`s8VloqYu-GW;Zeprr3`.s8W&qqtU!ds82`op](!erVQTkqYgEs +hWXFma8Z,=rr +l2M7mqtpEnqt$\YTu-?qs7cHkg]%6Q"9/?"s8N#qs!RdFs8)WFTtoLVr;HWpr;6?jqYC0gs82Tg +o_AIdpA"Oas7lWks8Vrp!<;!Vr;W)^nc/4[o)J1X(Ae%1s7cQnr;6<`p\b'fqu?Nmq#10grVmE- +p\hnF_nDfAqY^ +nGiIcrVm]1qu?]ddWAo"I':9)_T^0D`l?*@bfn5haSj*\aMu<@rP^>-aND`PcHX#3MFD*?[DB\o +`lQ?GccF/Oaj85UdEU%ke]Q+\cHaAP_TBg=r5o&]`q[XQaoT`/nAtOIrlG,^r61kW!6G)XrPeZO +!64WO"3//]s2OTM(!FY4`5/6Z8OlTZGiS>gqu?Wk +q"Xabrr`/pqYg'dJ,~> +nc/XgrVuoqrr3K-r;Zfjg$.2^s8W)nqu$Hn!ri,qiVrlWs8N&rs8Mus!<2uq!rMrmrr3)ieF*;7 +rsS]'rr;fos8;oms8N#t"8;Niq>UBsrr<#os+10KrW<-!qu6U/o`+pfs8Mcmq>^3hs7lWmrqQHk +rr3,bm-a#Zrr39$s8N&ur;$6fp\k^'q>^KN.N]i\,Z"74s7lWYrWN)tqu?]qlO!(Ah>70NrqlNh +rVm!!qtp +mf3:crr3H+s8N&uqTth3UsB#=rr2ourr(OLs8Vuqrr4,?qYU-gs89m0_;+tds82iqs7lWor;ZTm +rVlispA=mfrr3-#s8Vrqo)8Xhk5P5WQ2^OXnc&OfrVlZnmf"X5qZ$Tpo`+pfs8Mcmq>^]^Y%K-8's7O+%R@p+KfDPUF +s8Muos8N#js*t~> +n,NCarVm]5rVZ]jk,DTi?B)nCaN;NE`l?*Bc-4>ia9'B&aSj6^aN"4us2HM1bf\)H`lGZ48oB]s +\\u>-bg=GVbf7rKd*9kccGITH`QcZNaN2N?chtrbaSs?\a8j6YaT'Babf\)saSNpVaIUKNaSa$X +`VmgHaSs3Xa8j6Y`W*sGa@O@iaj%o@c-")Tbf.rJc,J#M^WO[DaN;<6W0pF?0/YS\[_Tc*bKS,K +`lu]Ob/hZHb08#L`QGp8cF"#b&/Z'9dE0SIccXE/aT'ERaT'BscG.<*H;m7%9l%$&q>:'hrVHBf +rVc`uqY9j_o`'F~> +nc/XgrVm*$qu$Hns8;lr"7PO2hu'pWs*t~> +n,N@cr;R-%qu?]j\>>e!meQh]s8CUL!<<#s,5qN?s8W)ts8Vokqtm(j_;b:jqu?]os8;iqqZ$El +qYL6jrr36$s8VloqYg?`rql`arW)urrqQMErql]orVc`qs6]dhs82ipp%n[f+T2$7s7ZKls8Vop +s8)cqr;QBhcc*N*U[n +n,ELeqYL0hrtbM+pA"@9GZRsa[(su/aN2B@aNDcPb2C>@b5KNbb/jM#s2lb5cI'VM_73EA@>qD/ +aN2NEdDj,J_9U'GaiDTCa2l<@bK[fB_8O@9rlbAbrlG)_"Nng,`l7nrs2alUrQ#5`aNDZHaMu6s +`;moLaS!^SbQ,fVa9'N.bl5ikbf\#J`l?+!b43PLbf.`F^VnI=b/:m6b.c*=a2c!9b/DNPg!m@! +7k,`<5,5QpbfnD]bf7E4_oU'Hb/h`Lbf[rE\]Vt7`DI9[$l$4taMQ!9aNDTD`lQBJb4E[hb082M +^6;et6psq4j7<6Jq>^Klqu-Hm"8_`bqt0o=~> +nc&Ugr;Qlur;?BirrDrqrs7NDjm`^Hks8;lr'E%h/rVucor;$Bfs8Dut +mcX!,f`(mQrqHUEls8N#tq#1d'qu?]Ykj.p/ +hYmKSr;Q]krVlutqt^0Zs*t~> +n,N@crr2uprr3<$s8(iQTV]^)r;Q]srVY%A.f]MIs7lTns7cEdVlmi.p&Fgerr)los8Doqrr;ip +qu?Wps8Dorr;ZfpoD\Xen,<=er;QHjs8Jbmo)8Xfmf*._kl(kas8Mfns8;oprr4#9rr;utqu?]o +s7lWhqYSg]_RQB!o)Jahs7lKhrr)llrr"j>s8Dusrr;usqu?WopA]X~> +n,ELeqYU6jrsnu(qYKpal*4W%AVn.,aN)B=ai)6@bK\&P_TKd9a2c-?_oC$Bb0%rNb5TK]bR2M6aMu3=`Q#p=aS!^Sa9T`+ +b0%fH`l@nps2P)[U;dJ[b0%rNbf\/Pqof,dbf]Ou%*HfQaN4>&n]3B%c,dcH`ko[0 +_T'U5`Q6$Ba3)K@ahlBPaJiMr*@EM%[`$8.bg+SZ`kT7(`lu^,b5]Zub/hQB^r4OLd=2Z;J(2W] +^;@hfaT'6`aNVoQb/jS%r5eoXs2Ynsd)a55AkYK]8mo:"rVuiks8W&rqu6cpq"XaYs*t~> +lMpn`q>UQVj6,J$rs&E$s8DusrTX:lr;Q`nrr)lns8Mlpr;ZfqqYgQoqtpU:"s8N&ss8W)[nFQ,#rr30"q#CBnrr)lqrp]r<~> +m/I(bp\td#]q:ahg\:^IrVuoqrr2ldrr)lqrXo)-s82fos82irqu?Torr)iqq>^Bl$N'Ic[_Vb; +r;6HkrVlosr;?Qms6KXcs8N&[rql_Hrn[SRr;cinrr`5trVc`q'_VD(qu?]pq#B9l_n2q^qYgEm +s8W)s!<2utpAPU#rr2iqs7"Q_pAb0krr<#orr)isrr2iss8;iq&,uP&s7Y9CS=6+=g@kRHr;?Tp +rp0T7~> +n,NCcr;Z`o&c_L]OC2$rS\N1c_oKm=aN2ElaSj-Wa>h2\bJhWGbeh96^WOXFcHFAO`l5p:`lQ6D +bfn/Lbep>B93A1*`QHE%`5Tg;qoBu(bg"AO_nj71b07oG`Pop@b/)97RScC@ +huK=rrMrprr3#ur9=1arVlWms8;lr#5eH"rVHKkq>UEl!WN#rqu?ZuqpFHar;R'%q=jdd +rr<#trqufnJc;ABs8N<&r;?Hirr2lr!ri,srr3&ms7ZHl"Rka;m+MC +i;X;NSYVg[qtL-gs8W#rrr;NfrVuiq"o\Grs8W#rrs8Q&s8DfmrVlforr`9#s8Mus&H2=TV7FS? +s8;]ls8W)us8DlprVqHJUAb5lrVl]o)#jL3r;HZqq#CBjs82imrmf-$^9$#^rVu3_&-)Y/rVQWp +q>('brql`qrVHNls8N!!rVlfqrser+rVlifor+FTQCkGJr;Qcqk5Tr~> +ir9Mco>tWR=`(pg`l#g:`Q%AfrPnfW&]_u1ccsPYb/V6:`lZ`Q? +hu=)ThX'+ms8Mfms8W)tr9F:]rsJT%r;?Ehqu?Zqrr2rorr2p"r;$-brr3H,s3KZjs8W)qs8W)t +r;?Qsqt^-dJc;8?rqufqr;Zcq%K6>'rqcZis8V?Jp!r7)s69Lcr;Zfqr;Q^#p](9krVlclrW<#p +r;HX$rquWls8N&ur;Q^*lJ1gkpYu&Ls7uWms8D*[J,~> +iVs5`qnnqrRa:m1s8Doqs760fs8DrsrsJT%r;?EhqZ$Norr)lnrW2rqrVuos%0,k\X0oqBrVuor +r;Q]qs82orrr)kJrh9>kr;ciprr`5trVlfrs8EQ/qu?Top\s3e]#CVcq>(!RrWN0!s8Dlprs&5t +s8;iprVHNns8;lorrE#rs8Vj#]UbgaUn-$6s8N#t!<)'[J,~> +ir9Vfp#;BI=&4jlb0.`@_o9dAb4 +hZ"&MkO@+'s8;lrs8Dimr9=1jr;Z]ps82imH2%49s7?-arr2p%rqZ?ds8W&srsHs5mJm4_r;Zfr +r;?Qsqt^-eJc;>Ar;6QoqYpd!r;ZEhqtpBms6p*[jN[Z'l2D1hrVuoqr;69ds7u]pqu?Kks8;iq +"T8)mrVQTo&GuM-qV(E+lf@U9s8Mrrr;GaWJ,~> +i;X5_o=1BiUA"TdrVc`nrr;QgrVufp&,cJ*s8VurpNH6+s8V`hs82csrVQNks8N!1s8D>V\&nFF +rV?Hmrr2rqqu$Hls+10@rr)j"rVZTlrqud*qu?Tks8D0"]XkMMr:oIS%f6/(s8;flq"t*es8Vur +q#19nrVlcq&,H/'rr2rmgRk=8St!=]rr2ouqu,XVJ,~> +ir9Vhq!6Ld=^#(>bL"2C_8FLBb4I0aNDZLb0%fF`P]^Ac,7<5 +bK$_X>&0tP`koa8^q[q2aMu6Bb(7X,a:?A:c-48J_o9dEccEr8^Ac(]\AuM/bd`R$.k*8G[(= +h>[o;mbmm?s8N#trquTil2D(ds8Vojs4JhIEqK))s8)`nrs\i&qu?]pqu?]ifAlf,rrN)trVm!! +r;6DCrh08hr;Zckrs\hurV6?js8VHUnF,-1s69L_s8DorrrE&trri&qqYC0erW2rrrr3T0qtU$c +q>^Kkr;ZfQl0\',h#@ +iVsAdrVH#RUnQ!'s8W)urr2rgrr)lprX8Q%s7uKjf-DGUo(Dt]rr)orrr)usrVlZn#QFMEVmFtJ +r;Q`rrW)utquH`qs+10Brr)lsrqu]prr)j-rr;uss8)N+]!f,Qo_SUfq>U9krVlZnrVccr!<2ut +"SVllq>^9i!WW/urVZ[$q>LctjUZ).NrVuosr8ms/~> +ir9Dbqt97!?Wg?`^X:(#_Z.j\b4beq9; +aN_PY;GD54]>_k5`P0++aN_rJ_h#n$aSZ5t+Xe^$POhr;6 +h>[oPhs'(qs8VurrVcTjlM_=oq>('jr8'%N,pAKKq>^9drr)lsr;Za%rV?Kjs6\J$qu6Trp\Xph +s8N&uJc;;@"oS8qr;Q]lrri?$r;?0brsA#^oAo!4s8;lel2C\]rr2uqrr32urVlispAape!W;rr +rt58-q=jd`s8Mrrs8(R8o(;/?rVllorr2utk5Tr~> +ir9Viqu6Hi^Rh6sgA1aIs8Duss760fs8Dp2s7uKjs8:_)*?H2]q"asds8N#rrVZZprVZ[1r;ZEd +`hp5so)Jadrr;rrrr)iqs8RZLT`4rj!<2rqr;QZp%f?;+r;=@B\ZWI8s8Dujq>U9krVl]o!<)os +!;lcq#5S5ss8Vfmq#: +iVsJeqt/s0>$"q#`5op7_9U9Io#UdLrQ$nC_o'XBaJoCS((#$-a3;?=aNVoRbfn/I`Q63EaMl': +`Ql96GsbAWVo-Qma2c'9aN_rJ_o@8KS]Dhqc-OYW`l5s;aMkp/`k]a5XHu1%-R_cb^;SF?bkfEX +`r4!U`X^&2bK7`Fc-!rEaN;ZAanWsW`r=*raMu3G^ +huE`U$ifSWkN`*IqYg9jqW[tiqu?]or;ZVE,U4EZ\,H4%qYgTpq>:0jrrN&squ7)bjQ?@>s82Zj +qYU0frVqHJT`4uhs8MrrrVd6'rqufrp](9Xp$hM&r;Qcpl2D4krr<#srVucprr)`ns8Vlgrr)j7 +rquKdq#C?ns81j9lgaEBs8W)us8;ips8M0\J,~> +ir9ShrVccko"Cch[HRPgs8N&snc&LerVd?)s8W#ps8%3d*#^$.qtg6err2p%rVZZos8VuqrsS\t +\Z`Eko_e[fs8Drs"TJ>trr7QKU&P)ls8N#q!<)os!ri/trVm6#rqXFK\@/=*qYL3kqu6'a!<)os +s8<9(qu?Zoqu6Wqq"k!hs8DorrrE&trt##*rnX`KSY)Ffk5YD[s8;lr!<)'[J,~> +hu=2blHtAj;/rVTbK%NFaNF(prPnfW%`QZ8`lQEE=:c5X%$T,^rl>)^rQH/#`Q$0KaMu6=^;\%5 +_mj2PmV`llQGa32NGaN)9@b0Im#a<8LA`lcNLb/VE;b085R`kn'M91V]PLX#Pfqtp6hs8VuYs*t~> +i;X;cqZ$Tpj6>A!s8Muls8D3]%fcJ*qZ$Njqe@LNpq=sjdqu76+s7cQni6pW[s8W)m +q"OR_rVllqJc;AB!rW&srVuoss82lorqlcqrVm#dnF?(krr3'!qYB@S&-)S)rVccrrVZZprVuil +s7cKnr;QZps8!,rq>UEohr=1qk2uR?rrrB$s8N#rjo9i~> +ir9ShrVQTorSF<>R+_66s8Duqnc&LerVd?-r;HKlrVH>#)]TnAh>7*Hrr2p3rr)fprr;ipq>^Bk +os:F(h"^pLrVca!rqlWms+10Crr^ +hZ"#Zl*k8(:QrN:b/MQDn]:[KrQ$q?`lH$Eai;b.'+bNT][P3Nb/hZHb08#I`mN2T`Poa0_Rd_+ +_l[<m\`5Td;aiqlHaN;KGa2?-ta +i;X>brr2rtrS?`!s8W)ms8N&XrWi9l+<_pYpA=[b"8quhq"k"#r;$?ls6%>[o)Jaep%%kUrrW,o +r.4j?rqucurquNdrqu]o#3tXIo$RL:rr<#t!<;lo&-)J*rV-?lrr;lqr;Zcqs60F`r;6EirrVue +pAY'qiU$%,kNMdB!ri,sjo9i~> +iVrrWqYpL%p!&nqV;V:Orr;lcrr)ljrX/Vt6lI!b-1^m1rr2rsrr)lor;cirrs/Dpae68koD/@b +#6+T!rVlcqJc;>Arr)iq!WW/urt>>0r;6Hh_n +hZ"#]p"Z0C;HTU0bf\&In]:[Kq8iQX)U[@t$4@1Oe^Mje`l5s=b0%`FcdBtV_8!h(rl#Pg_7G1i + +_90m@b/MQDaMu6?rPnlYs2soR(WOA3b0A8V`l6! +iW&rW%fcJ's81X8mGIsBqu?Wpir02XkU%As)IiI:rWN9!p\4U`rr`2rqu$Em#L)E,s8VH[qYgEq +rV6;Arh9>hrs&K#qtg-_q>C7!n+#u +iW&rW%KHG-rnOHDV69gmrVu`arr)ljrX/Vsj<5E_'OCA/rr)lrrr)lqr;ciqrt>8,q!b#ich7>3 +s8W)qr;Zfrs+10Crr2lrrr;uurr2p+rVuljs6%A8]=ag/qu6TtrVQQlrVlcq!rDrorr3<#rVl`p +s8N&rr;HZ`rqud-rVZNiqu?Wpq;eHDT9u+AjSf)8s*t~> +hZ*WO$LtfQ=]oIQ_9:0Bn]:[Kq8iQX1!e:i$O74G8(H)4`P]U5b0%fHbfn5L_84.4b/hQ@bfIAg +5ZW<:a2-*I_nX.6dE]mcaJ-cTarAF@`Q$'Hd*9MGb1+;.Fupum.kR-n_T0d=`lJ)$s2b/Y&&HH+ +b0J5Mai_]JbK.fC_u7UTaT'ERa;i4=`QHHMbfIc?ahPp,ULI(o78R^@pAP$krVQQQs*t~> +ir9)Zr;QWo"7tR7i;W`XrVuoWrWiK"Zm7+D,_l0prr3H)q"Xads8Mojq#: +i;X;ds8N&up!T_0T$m<3q#Bm`rVuQi$30e*+!_aHK)GWHrr`9!r;HTos8Dusrr2utrr3/ul^593 +nGE7crW)tLrh9>irVulrrso&.s8Dlor92/7[(;n-qu-NprVl]prVlfnrri2us8)QirrW#nq"t*Y +rr)j1rquWis8DuqqR`>lR\HA!qu-Qmrr1mVJ,~> +hu=,`q>0gHZYroCMS%*KnAtRJq8iQX1!J(nOpMg2$Y@l4`PKC0b08)N`P]^:`l?6KdET\Mc-4&3 +Tgi.,XN8;ua2l9@d+$9jaJ-cUas"jG`Poj +ir9)Zr;$6i"6\V-l2:S@rWi>sr/DpH,)Z6rrVm?)q"aphqtTp\s8Voiq>UBq`p*9trs&H%rqlNh +r.4jArql]urqlQeqY^@%jmh[!ec5[Ks8Mojr;HZlrX\u,s7lWorql`iq#C9lrVYjXs82lrrVmB+ +s8VN?m.BT&kPtSYr;Q]q"9/2proO01~> +i;WiUrVca%qn&MpWo!OKrUKmcs7Q?tqt^)F*ZlDWr;QZp"9/8rr;HWsrr)iqs8W)srseM`S%[>E +s8Dlqs8MrrJc;ABrr)iqqu7$&s7bira1JdZo_JCa!<2urrr2lrs8EK-q#CBmqZ$9`s8;oqrVcc^ +rr +hu<`Tq#:*rl&K.N?(\mL`5_AhrPnZSrQ6h7ajb,6$jULqb/M35`QHELb/(g0`lcNOdF6F_aNVlG +^pTt$>_&lf^;J"1`R!&XJ]OS,s2k>]rl#YmaNMWC_nELTI3omR0Li%R`Q#p?aiaV-s2tA_rPfAe +aNMNIeBQ.``lHQLbf@[#`rF-[b3m@LaplG3^:V"2=]A6l>)qS:rr3&sq"s%MJ,~> +ir9)Zr;6Kn#Q+Ats3pE%h#793rr +huE`U$N9i$s5KZHU8RV]nG`Cdo`"mj#4ZLW\+'@qrVm'#rVcZmrr2rtrr2rtrVlg,qtg3JV8(CK +q>U?ks8W"JrgNicrt,2+rr2'!^VI"VqYU*grr)fps8W&rrr)j-r;Q`ms7cQlp](9js8)corVu9a +s8Dlp')h\+p@Y>[S!g%LmJ6b\r;Zcqi;\<~> +hu=2`qY'X^oYbTP^W"IFci)*%bfIfJ +_SEjQ;-Ik7\A,boajA;TJ]OS,"Nng)`Q%nu)p-(7\[.uO2\?lZ9s21Hc,R`CajADU`lQ +ir9)ZrVlcq#5S/rmc!NfrVtjU#5%rpptu#IqYgQoqu6Tp!;uils8*'!s8W#pq>^9irrUd6li-nd +qZ$ToJc;8?s8W,u!rW&qrVm#lkOmTjrr3?%s8N&urqZBhrr;io&-)Y-s8DcnZhsRqrr2rrs69O] +rr`2rq"t'j#4CX@mI&X*rVm-$r;ZfrqtpBRs*t~> +hu=/brVlisr;":#SXIjus7-*es7Q?ts7H?ip>,TArVlfrrr*'#rqu`oqZ$Tos8NW+s8;oli2X?, +li7"]s8VtIrh'/is8DrsrtbS5s7kWu]>Ub^p%n^bs8W)srr<#tr;HWmrseu+s8;ZlZMF:lrVccp +r;Z0`rquirr;R?(o=UonS"ZA(rVlirrqucpqu6ZqkPp&~> +iVsJgs82ZirVuTQS6]#cL:>1Bo#UdLq8iQX1!%AKd*^1Je'ZF_`l5s=b08,S`PKC0bg4PXaN2TJ +`l5d<`Q#Z[8Q'N#]YD2&ccXC]aJ-a#b/hQ@`lQ +iVroUrVm9)r;HZqhWt!mrVuoVrW`Dur;Q]os8)]rr:p*drr`8rq>:0krr)ruqY^?pdF@[brrDur +s+10Drr;orrY>J4rqu`os8W&algX-0s8W)qs8)Zmrr3*!qYL-drX\o+s8MupZS>Y`qZ$KlrVu-] +rVm<(q"4=Zs7+t0o'5Jlrr3#sqYpKsr;$0fj8XW~> +iVsGes8Mrqs8W)nq4aIZT&TV:rr)lirrC6jr;Zcq!<<#ss8N3"qtg6hs8N#trt,20qZ$Qm +qqnBPbjbQ-qu$DDrh9>gs8W'5r;6Nii5WC@ZGZ)0qYpNos8MrnrVlfrrr2lr%f?;+rVZPt03J2K +s82cnr;Z0`"9&/rrr)j-r:n*tR@]hDXS);es82coqu6`ss8M3]J,~> +ir9Vhq"jsfs8W&kl.g/[<_K(#`q%4L`qd^Taqr.=c,IiLc-4PWaN2BBb08)Pb08#J`Q%nu'ZIu/ +`l?*E`6HBB]9Q8dCmq]F`Q*PNTZI/U+i_F;`QHHN`k%dW2]3\o?(/F>`Q5m7aNr8X`P&t)b/h[& +`Xg&4c-=P[L^#T`c.:(]aijY&s2b5_o#M]kc-42H`Q69I`4^_$8k;-JHeRc`s8VrjrVccqqr[p/~> +iVroWrVlorqu-NsjQGjZqZ$Kms8N0"r;?*a#QOSus8;iqqYL0nr;$0drVm#tq>C9mrr*'#rVuok +rVlrRg?AJ7#lac$rqu]kr;Q]q!<2uqJcUBqqt^-Ks*t~> +hu=2crVufos8MiITpV[Up\asgs8W)t!r`,tqu??g#QOW!s8;iqqYL3jrri?!qYU9kru(h7s8W)s +qu?]ls8M]Q['7C-r;HNmrr;usrVufprr7QK_>aH4q>LHorr2`n%K?>&s8(Hb^U^;Gq>0scrri?! +r;6Hls8N#qrso#'s8&rF*?nPYqu6Qlrr)llrr)lqrr;uurr2irrr)j*q"pSSTU_dNo_JLbs8Muo +rrE&[s*t~> +ir9Vhq>1$hs8;`ipuo,#92Js%_u@aU`rF-[b5KE[`qd^Tap?)2^rXd?a3DX&aSj6aaNDcPb5TE\ +a;;h5_o9^>b0S;Kb/Cl^=%m.e\%fc#b0'\(rlP;``l +f)GmChr=.gqYpWqr;?Nns8)foir8uU!<2ut"oeGtrr<#prW<#pqu6TseDB]os8Vm"qYp?jp%eOb +rr2utrqc]nJc +huE`UrVmW3q=qn&S#W^hrVZTjrr;uts8Dlorr2rWrr;uurr2j!rr<#trVZZpr;cirrtYM0p8=k# +f_kdIrVliqs8N&urVZTlr;V?I_u9r?r;6Ejrr2lqrquorrVlTl%fH2'beh0*VW[gRrVlirrr<#t +!WE#os8Dp-s8)ciY9G&)+"+YtrVuoqqu?]qrr)lrpAYa's8;cos8)WbV4sNMUn?B=rr)lsrnd[*~> +irB#Vs8O&:qu-Qppun8Y92o<2`l5p7`Q?'>b08)PaMu6WaS[b/M9 +iVroWqu?]qrr3,aj6>_'rVm#us8DlnrVuop!;t1B"8quiq#:9qk1oG&rVuop"T8/mp&=pi"8quj +r.4jarq-3rr;6Bip\4R^rr2p#jmDQsf)G^7rX8c$pqS-q*@<&)o_e^e!<;oprVlotr;HNkr;ZWt +r;Z`qs8)`p#3Y7 +huE]Trr<#r'D2%,URS"1r;Zcrqu6Tprr)cmrr2rWrr<#irr;osrr)j%rV#fhVS:[Urr3#srr2ou +qu6Tn!<2rsJcR$s8Vrqrqa:-R\-.>[J'RNs*t~> +h>dNP!<)os%di,)>XhGP_8s[>_SsI7rlbDa`o"l;`rF-[b5BK_as"jKc-=>Lb082S\>WV"?[o,n +a3_`Caj/2TbfIc@`Q$'CJ]P^L!6Y;b"3Sj3b5TBraND`Nb0&#L`5fj7_Qo_&.3T]`OKlXna9'B# +`W!mVa:HJ7c^kLQ',Lapaj82SaijS$s2b5_!6kDd!mJg.rPfJk`l>j8b/V`J^N`sF4[iD2iV(n' +J,~> +gAh3P!<)os"5W&"iVriZpAOphrr2oss8::DrVlutqtpBlrt",.jRW?NpAb0jr;Zfpqu$Hn!r;Wh +Jc,pOUhp&G'irr)fkrr2otrqu]k +rXSl'q>:-jrr;ZMk3qKtime!Y~> +hZ!TTrVmE-qu$;^MVsXB\fDg@~> +huiQ)2B`Q#p=aSa3[a8jB]aT'E_bR_e1_m4G] +C3ukiZHC>5bK0\&s2b5[!m8a0J]PaM#K=Hm`Q63C`r +gAh0Mrr39#g#M#Ls8Vohrr3-#r;Q`rd/NtC!<2uq#QO`%s7jFmoD\airVca%rqlNhs8W#or.4jb +rWW5pq"ajequ?Qm!<)iq"Q].Kk1oq8l2D4ij!>lk*[6F4rqHHks8)]err2iqrql]trquZlrVm&[ +l1F/qhUDLT~> +iVruYs8N#t%fZM.rVlWfc_ID0XS)Jirr3#trr)lTrqufhrr)cqrr)j,q>^0GTYAbIp](*hrVl`n +s8W)ts+10erql`qrr;rsrr2rtr;liprVm/f]tD"]Z2aIrmJd(a&H;La+s%X?*/!e[pAb*kqYgBm +q>U;dLVr@IKrn%1#~> +hu!l`1!pW+H!aMYp:b08#L`lQ$@^77u+ +DP4)J`QufL_SaC9b/h['b(7XOa90Dq^;9ce)90b;`P]U5c-abYaht]kHorf,0M/[`c-=E%a;<(C +aMu3<`lcK9!sJl5$uO;;aO/2U`5hhrp;m9Rrl+oW'$/5Bc,IK:_5(a<9hJ5m[-7>afDg@~> +g]%EUr:g*frr3Gge*6&ls8Dror;Q]nr6Gs8V<^&-#ue.N:!no`+jes8W)os7uZkquH`ls8W'.p&+jhs6AtB +l0%*\s8VuIs*t~> +iVroWq#CBn%Jfb3TV/(0qY^Blr;Q]os51*jrStr2[@kb=pAb*hnc&Re!<2rs&,uT6-RKTXJFW[:qu?]qq>C9k +rqcZmrr2j.rr;lqs7Z)gStVREWjqs)p\reEJ,~> +hu*leR_4;,E7d`mW&Qbf\#H`PpcVs2G,Z`lA#!r5ScX+Nh^?_8sjCaMl-Ac-k%W +X$'!\VR=Ie_oB[7`lQ`Q$!@`k%UN1F+@rEO!+#b/s4q(s:+J +b/VE>`lupm$4QtKB@>GUbK\;S_p&)!s2Y8aaN4>"qSa,faND`XbJqE/[;Ar?6q_$Jiq2rqs*t~> +g]%EUqt^$arVmG[i:#J#s8Vlkrr;uqqu$Hndf07G$2j\trr<#orpT^_rrUd"g%kXMr:os[rr7QK +_uBW7!ri,prV6Qmr;?QkrrhNEo((B1rrVoes69Lnq>XG=.=_6mq>^KorVHQmqYgQoqtpBj!<2cn% +fZ:uqZ$T]lLF?1in+50eGk%~> +iVroWp\ta&r;6#aS"ut^9is8;lp +rrN)rJc +hus2G)Y`r3sY`r3jq`lQ5bc-42HJ]P^L+NhsQ`PK:'`QHTWdEKVJ_847*[$4B7*$?Y\Xieu/]uKWa +(s:+Jb/VE>aNVrc1B@bef@7sfccXAJc,KY$s2b5_!6G/Zs2FuTs2>YkaNDZMccsAEZ[,VC7SQp' +f^\ggs*t~> +iVroWqu7*&q=s[_rVuooio&nTrr39"rr<#tq>($idf07G"8V`fr;HWrq=ade"7^Bg +q>C3kJc:-grVm#Zlgj&_rr3,us8W)ul2Ckdq"RsJqYpL!rVQWnqZ$ +i;WfVq>Uj%s7uTjfr1C4V<@CIs8W)trrN-!j8T#WrVl]os8N&s!<2rss8;rprVm<'p[ZY#^!lKN +rqHBjrr3#urIOsarWN2rq>1$ds8W)srsSN"lG^TUY+t:Qs8Dlqmf*7d&cVb/p@VF?q#C?nrVQWn +qu?His8N#ms8Dp.rVlcprVuomi0pI.S=Ze=rR:ds~> +hu'm'^V';-Tp+cHX>G`Q6h9jVk1]Z8(:bg"DT`l#^6J]PaM+j/'UccsPM`Q$0Me'H1U_nN=VFZ(6[*%R8ZbKIuK +_8sXfa;E(Dbf\#H`lcQUcdFRYdb3'raiDQE_Tfjo`rF-Zaof`)`l7qps2>&ZaNFM+%*Qu<\X6&i +7S6U"\an5LJ,~> +iW&rWr;R9+qY9m`s8Vurn_rcqnGiLes8N9%q>($is3glMs8;Zdq>C3k!r)Nfr;Qi:hWXt="9/2n +r;?SGrkna5rrN,srqccprr2iq"o[KGp>Y04rrr;ts8Dinl2D4lrr;ojr;6KmrVlisr;6NjrWN/r +qu$Hls8W)sr;Za,s8Dusi:641n_s +eGfjSo)$J)Tq/^jp&>!krr)lUrr<#qrqufqrW)oprri;ur;ZZnrt55-o^&-T`:Wd'rr2rsrVc`q +Jc +huC]ZS..`luiV`l#gUaT'6\aNFM+!Q`7Z_^*4Bb08#Nbf\#H_o'I7 +aN_lJ_SE^Y5YYd][*$V=dETbO_84-BaMZ(BbgFneccX8H`QHHQccX5@Z(>ed+!;@dQatDcbf7K7 +`l@De'$AGCcI(+eb0S;Vb/_TFa2Gm;rPnlYrQ5Gf`l5j5`Poj,Z:/YQ#kkb>Z +rmq+"~> +ir9)Zr;?Hl"8r&nr;?QtjPoOlrVca#qZ$Kfs8DuWrWE2qs8;lr%fHA)rVufqrVcZkq"Xacr;Qls +qtpBkrs[B2k5YJ\qtg?ls8Vuqs8W'"s8MnHrlP->rVHNqqu?TlrrqrQo',&_rr2utrr3*"r;6E@ +rWN/rqu$Hmrs/Q%q=sjaqYgBm#2eS2o]b91rVuosf)L7~> +huE]Tq#:s*r;=-rS"dt#r;Zfms8W&trSd_es7lWkrr<#rs8DrsrVuiprqud!rVZTlrr2rtr>5D1 +oWG4&hu!^?js82fqs8N#trqh9Gao3(OqY^ +h>[TSqYL*frtPG/qsiKu<_?;=]>;D)_pI#[ahc!Ua;)S9bL"bdb0%W=ahu3AbK\;Ub/hTArkfbq +`lcNMb.tZk>t\(LXi/W3d_s#?]uJ4;aN2NF`IZ+Qah6X`PojUbl,]`bQ,`Z`r4!Yb5]ZdaN"1t(!4P?cHOJTai:j!A5Plj8m7eC +pA4[9s*t~> +ir9,[r;?Qls8Drorrh9SkNMpDs8Viqqt^9NrY5;1p](3cqZ$Qpp%SL_s8Dijq>:0grrrE!q>'pc +rr3)fcg0oqrsSi+q#C9jrVZTms8RZLb5MYDrVZWns8W)trrE#rrsIcJkO$s^s8Vrnrr2p"r;6Bh +df0:E!<2rs#Q4Jtq=XOZr;Q`rk6gYIn*fQAs8)cqqpk^s~> +huE`Up\tm*rV5ZQX.#m6rVcWnr;Q`ls8V*X%K6>#rql?_s8N&lq#C6gs8W)srVZ[,rql]irP4u= +bjtf4qYU +h>[TUqY9pdrtYM/qZ$EWb%b +ir9,[r;?Qars[`BlJqpErr;rls8N&WrX&N"qSlInq>UBkrr3/os8)Qer;HWqrqlWnqtpBpakcIb +rrW2trVc`urr)irJc +huE]Trr2utr;RB.rVlTGUR@jThXgF?s8DusrSd_^r;6<.:uD!ErVZZp!qlTlrr;ur!<2ors8Mus +$iBkojdW?jn+lhYrVQTsrr)irJc +h#@HQq"k!i'`7\%s8VuYY[gI)>ai7Qb0&\a'ZS2:SLqS+f$DF\bfIHAaNVlNb/jM#(!+PA +bg"AR_nj*oSOH=eR'Fh'S_84.6rlkbl`PK=(_oBd?aSNpRa<8XLc-=JR`l5s=bL"JUcH*c7]7NpM91Ms"e+EG/ +o_/76s*t~> +ir9,[r;?Qdrt#&-s75.4jludEs8Durs8:jTs8NM^-79qnrqQHlo)A[hrqlZo"oeDoq"t!grWE)t +s7Q?j"6.bqnbrIhrVulrrrN,tJcs8Drpe,Op~> +huE]Ts8W)trVuos&,Z@naeY])Yh]*Rrr;utqr.PSrs@@',95J8pAFs^rr3*"s8W)tquH`ps8Dp, +s8N&js8;][ZCo"as7lNkrrE&trrN,tJc1$grrW/qrn%1#~> +h#@ZYqYU!!6Y;bs2t>^ +'YMW/^SY:"?%',g^W4IcH4,H^U9eg?8aAb/Q\pjaP+eU_84%.`lQ_nN[=>uF*d=)G28rqH-Yp=0+m~> +iW&oVo`"pjrr3B&g>CoRs8VurrV6EOrWrP_/gDJ_0\64%rrrE!r;QWnrVm'!q=jXZqu-Nsqu?]j +rVlunb2VL]s8W)uqZ?`rs+10irW`E%s8;`hqu-NumGmQjdd[58"oA9!qt^0hrrW)nr6kTEquH`p +rrr>tq#CBmrr3/Zk2tjgf)>UNrq?9heGk%~> +hZ*KPqu76,s8W&lcCUK!]Cl'os82QjiVj/`i%,rh*@oS7rVlisr!*0#s8Dlmr;6Nnr>,D0s8Vil +s7Z*0S@6<6r;QNjqtp?ls+10jrr)j1rr;uss8Vure\]/!S'1I(qY]pZrVlrurVlfro)A[hr;QQm +s8N&um/Ht`(&mk%r90oLTqe0Ff_>%;s8;osqY^?Es*t~> +iVroVq>UTrqtg0drr3N-o%]jFla:HM#"p+r8(qJ>Lc-ODI`lS/!rQ,#]rlc8& +aMu6=bgF>NbIt0-5#YjfZbsZ#`Pom>aaqOSa;Dn2^WF^A`lH*>WJa%_,UYNsZH159`5g.$`rF$X +_Z7^IaT'9[aT'BaaMu3u_Ze$!aN2B@oZ/,sbfn/J`Pop@bfnGT]=tnO>#S?r92r@cpAb$\pA4d= +s*t~> +eGoOI$2aZ!s8Ua;hqn#(rrW&qr8IVcpKT0i,:"V`rV?KirVufpr;Qruq=j[[r;?QurqucorVQTo +"3]-Mo)8Rkrqu`ps+10krr2p!rqZHirrr>WhW*&PrVllprr3)rqt^0hrrN&pdf'@HqtpBkrrW,q +q>C6skNqKsjP\hlrr`2rr;P4GJ,~> +hZ*WTs8Dusp\t^%q5C?aW6G,9CpAam[qu?Zjs8W)sr;HWpmf*(_ +r;Q`ro`"ghrVlis&,lP*q>]`hUR@dLTW.bZqY^BnrRV"!~> +irB#VqZ$Ql!<)iq%fZ(UH>ZbmL:=t4a32lQj2`1^bfVgQ#n[^YYgph;_Ssd<`l5s;aNDZLb0%g' +`YQhAb08,TaN(EN6qM'IY.DToaMu9BaaqOTaIb08)P +`kfL2o#UgQ!6G#Vr5eoXo>psS!65#W(WOVAbK\#?^SG^G7o3/fFQDuis8DilrRCjt~> +f)PdLrqm*"p\Xsis6Sb'h#.0Qp&*hK&-)J%IOZ?\,UTeoqu?]jrql]ur;6Bhrqud$rr;orq=t!d +rr3)YbM_mgrri?!s8W%KrlY6>rrW,prVlg#kk+N(de<\?"SVlqq#:9m!<2uq!<2ute,BIIqtpBk +rr`8ur;HWp#4'e,puUN'rVm)mp\b!grqb4GJ,~> +h>dHPq#:m's8;QU\"f[qg%b:@s8;oVrX]&(pN\#")'1!)qtpEnq#C6i!<2ors8N&s(]++-s82`o +qu-Qg_5"EXq=t!irqufrrIOsirW2lorVmQ*k/"jGVl&&As8Vins7lTns8N#qrUBgdrVulqs8)]p +s760errN-!rr*]2qYU3V_jd6jQ_M4`pAP$crVulrs81CIJ,~> +irB&Ws8)fpr;Zfo!<)lr&H2M+s6J!`?rpKn\%Bl3ai`Yb&'E5BemfO,%hK&*c,\#M^])5!`Q$!A +c-4>L_8!h*b08#PbL4PTcGIK:X`$j5@%OdJbK.]FaiAtRb/baG^r+78be]lp2Cp@*4+FKH_Rn"< +`5os:`QHTYe'5kJ`q.7Yb0A8VaMl'7`Q64$bQ>r.`r4!Sb596[`W!ah`lcNJa2YopI83@*6s>St +kP4rGq9f4m~> +fDkjLqtpHnrr3G]hW3Mgs8Vllr;Q`rrr2g!rr<#tr;?!^%K-8$JgDWb+Y1"urVu]ks8W)ur;Zck +rrMlnrqlfnq#:9qbhh7Rrr3*"s8W&qrW)lqrW)ukrr;nIrqucos6BU\rrr8`n*Sd%rr36%r;6?d +s7uZnrr`2rqu6Tpe,BIIqtpBlrrW2tqu-O"map^nkj[@"rr39#r;QTkrqlTlfDg@~> +h>[KSrr)Qj%K65$k,>#NV9er4qZ$Torr2rrrr<#drXSi)oR.f%)]U95qYgHjs8Muorqufrr<)rp +s7cHk%f-+tgnD'djn/TOr;Zfqr;H]rqu6Qoqu6WqJc>ZJs8W&s!<;Whrr;rr%f?;+rr2]M`4i[R +`Td-prr36%r;Z]ps8N#rrVuforr)lmrr;rsrr)lrrW)obrr)lqrY>J4s8;f_^RqEsPc(;)qtpBi +s8W#oe,Op~> +iVs#Yqtg9hs8VuorrE#srtkY&_fK!^=GON*aO//O`l?*@b0%fFaN4A'nAl-ac.L]a'+kTV$&csJ +bJD=!`Y$A;c-=>K^V7J#b08&Ncc+2SrlYee_6Stf9j3da]=u,%b/aG$rQ>,\rPjE0p;m*MrlG)] +prNHSs2ZM/aMGd3]="2E3$TIg@\UQQ`59F1`R2T@_SaIBe^`!e`Q63CaSj-YaSj6laNDcRbfIc@ +`Pop@bg"ASrQ+oZ"3AX+b5B?\`r3mVa:l\%k;1q"sd`s8LIHJ,~> +eGoRJ!WW/urtGA2rVbF6kiVpFq>L*ds8Vrlr;6Kn"TJ;qrr;Ke%fQ/%nqJJ8)(@$1r;Q`prr;cm +!rr9!rVm*$r;6 +g]%9Qq#;'+rr)`ns7GBHUn+@=rV6EkrVulorr<#t"o\H#rr2lcrXJi"s6kO_*>KkIp\Xsiqu6Wo +s8Moq!<2ur!<2rss8<9%rVl9+Tteb9p\t0mrVca#rr;uqrVc`ms8Drqs+:7Ms8W&us7QBdrri?! +s8W#rrt###k.J:?ZD6=WpAP!gs8W)trr3#us8DrsrVufqs8W$(s82fqq>L3is82corVu]ms8Vck +*rZ* +i;`iUqu?]pr;Zfqs82ir)=,:W=\;VY^qe=;`5KR1aj82N`Q$'FccjQ$a<8UGgX'R@#65#3cHFAP +`Q#p=b08,Tbf[rC_8F10`lQ6uapc>/_S^Kl!<(OLJ,~> +c2SLTq>C9lj6Z*is8V`ks8Dutr:0U^rr3&tqu#s_rr3E*r:cp1/L@e(rVuoro)AUf#QFYuqt^6i +rVlg"r:8(jir&fYrVQNkrr2lr!<2rprVlcnJc>]Is8Mlps8N#qs8N)urqufq#6"T$rVcThrVm6$ +iqi#nhZ*WNr;HWpo)8^jrq??k#lal%qqe+Dqt0CWs8;ipq#:EpqtpBm%Jff!s82irg?\S&mFM47 +rrN,sr;Qluq=ss@s*t~> +df1![r;HQkrr<#me"`P/W:Ku\s8Vuqrs/B"s8Muqrr;Hdrr3K+qXg@$.3Ytpr;Zfrs8W)ts8Drr +r;Qp!rVc`pqu73)qYg +dJs7F!W)Wkru(+$APZ!(X2VftahYj>bJqcG`Poj@c-=JTo#M`kb0nSad=DE1"HM'Yc,mrE`lQ^0^T`e`7TYG>Y//#o`Q$$Bbg+PYb/hZDrPefVs2b2^J]Ir7`l?!r +_Z[ruaND[)bl#Q]ar&.=`5BR4`ko$SP[Gmo+s0FN^VIt6aMl7"b5]O"`l5p:aN2NHbg"Y^^rF=0 +`Q?r.aSX!Wa;2q>`PfjDcc#@mV;HTdUp\FgkrVQKjfDg@~> +c2RhCrr2p.p#kQ!i;`iSr;-r,II@Is8;osnc&Of!WN#rqZ?]p +rql^)f[8aEs8W&pqu?]pq>:$g!ri,prqQZnrr<"MrW`;tq>:'er;?Qor;ZWor;Q`qrr2p$qu-Qp +qu$Hn%HQpMjkT\3s7Q0eq"t!Zrr;j)s7ZEkq>:$+,pT\ks8V9]s8W&s"9&/rrr2otrr2p%gu%,\ +mb-t*rrW#nrqufrqZ-WIs*t~> +dJs7G&c_k/rr;rhaJPZ(XlKHVr;6BhrrE&tr;cirs76-us82ipqu?,k+L1b@s8;iqq#:9mqu6Km% +K62%rr2ffZD=tMo)8OcrrrDuqu?ZprVZ`qqu?ZoK)YWHs8N#r!<2rsrr)iqs8<$!p\Ogf&,bV)^ +:gYLf(&e8rr;ors82fos82fqq[NT"s8VokpV.gmY5&%sli-k_qu6Wq'`J%2s8MuprS=?GSXuLF^ +@D'rrVZZp!ri/te,Op~> +ci5'br;6Eho@ojI;bp_oaMGm5`QHBIccF)C_o9^Ac-#Uu%`ZB0c-P4iOoUNkdEfnSrl+u[b5KNc +b/h['`rF-[`rF-Yao]Z(`;[Ro_RZXO7oj,bWjT^bbK@f?`Q?->b08,SaMu-8`Q$("blGn +d/O1Hr;QTn"PDc#hqJ&/#6+Grs82]krVlrsqu$$a&,ZD+rVlWgs6TIZr;Q]ns7-*gs8W)squQWl +q>Ucoe'ZkArVuopqu6Ttqu$BkrVlotqu6Blr;Q]qKDklKrV?Kjqu$Hj!;u]n%fZA*s8N#ts7>aF +m-E?]rr36!r;?9`qYL-\rX]&*s82imq>ZF*)CHcfs8(pXs8W&s&HD\*p\b'krr<#Vk2bpkj4aJ3 +"TJ8or;QZps8LULJ,~> +c2S1Nr;6Hkq50m\T!%Y_rs&E$s8N&urr2itrr<#irX]&,s8Muqq"OgRo`+gfrr)irn,E:c'E%h/ +s8Dfjqtp!5XK&_`li6qZqYpL#r;ZfrrVZWmrqucurVZTlKDt`Iqu6Qo!<)los8<]3qZ$Tnq>^?R +e%rf3WNtsis8)cqrr)lprr2rorX]&+s8;onp\osq'I"XUrqbs[rVucos8N`1r;?Tpq"s!JTqJ6M +T<%DTo)8Ics8LLIJ,~> +c2Re>rq.,shK<.'9P:ZMaNi#MaNMWHaMl'5`QZQKo>h`f_T0a@ccjbk`6HfVbfI]E`l?*@b0%s) +ap$#3aMu&b/_B=aNVoTc-48J_o9Xa>jrWW>uqu$ +bPr1Rs8VuVV4ONW\FKOsrVuopr;HWsrr)fcrr)j*rVuosp%\Lcqu?Klr;Q`irWE,urr;lp!<<&t +&HD\+rr;cnqU_RD]AiG^s8Moqs8N#r!<2ut"9/8srIY%Fs8N#orrN,trqlcqrr3`4q>L +dJk9drr<#no_/(Wn&00G;cIeC_og0Ga2#U8bf[rA_8c#drPf8dc-anYbg4YXbJ;08rl4rYr6##_ +"jP94`lQ7"ar/FEaN)<;_SjO3^p8Va7TY23\\c>*`5B[?rQP\nb/VE>`lcNOc,tXZrlkAdrlbJe +aMu7!`?3+@b08#L`l?'Ftrd"IRHQ +lcB%Es2b/]'@"VBcGdZB`N3BI:/k%pHc54@qYpNoq>gE?s*t~> +dJj=JqtKmarrDinrt"&MkMkJ#s7QElrVuciq"t!ho)8gkqYgHlrVca"qZ$HmqZ#gZ"98B!rr2p) +rqZTkqZ$TRh;Io'rs/Q%q=sd_r;QHjJc>QErr*-"rqucnrr2iq"TJ;oq"t'j"n1jIlIY>"rsA]) +s8;osrV-3eo)A[f%KH8(i$T`o*@ObBo_ngLrr +ao;kKrqtcPTUqsloDeF^s7uTms8E#snbramrql]pr;HTo"T&/rs82ZmqYpNns8E#uqu.?1rqu`p +s8N&rs8M`hm&d+cbO#*%qtpBrrr)cnrVlcurVlcoJc>WJr;H`srql]urr)fprql^.jN"g?[]@RG +q>UEms7u?bs8W&qs7ZF's8N#tq#&ki*#o_<9AT1;s6K[_s8;itrVl]mrso"l\YkdcR@L20qtL'f +qYC-nrr)fpfDg@~> +dJj4Frr3u7p@e@]qWbe1=A`.B[*$2.b.Pa:c-48H_8F73o>hH^`50F5`lZQQc-=8P_ofgl`r=$Z +b5TWbbll83`lQ7"asbKV`lH->`Q#sGa18^R<(9GpQ)qC*]u%e1b08,Tccs\T`Poj_FR`r4!Yb5BbhL)M +&ek`e28%&SbNm7J`rF-Yaqi1AbK\/O_l@WU78?HVFh@&2rVufqr;QNmrR(Xq~> +d/O7Hq=jabrr2utrr3)RmHEC&rri>uq"ajds76."qZ$Tns8Vuos8W&ms8;lrnc&Lbs8N&u!<)ip +"T%lgs7lNls4m_6oD\amrVQEgrr)lrrql_IrqQKrrr;utrr2p$rquTeq>C3k"n([@kLnYhrrDll +rri5us8DugrX]&*qtd]K-QsKZD"RT(qZ$*bs8W&sq"tX$s8W&koDejUk4eK +c2SIVs8MrrrVcWTTqe0Sh>I*Hs8;lns6optqu?]ps8Vuos8W&ns8Dutrr2iqq>U?ms8N&s!W2fo +rY#80r;Zfks8Vril*ROqaQ`['r;HX!rVZQirVlfr!ri,rJc5lQrVlfrrr2lps8M`l)#a?rcG6rj +U:'Lfs8W&ts8)]krqQBjqu6Tpq#:6l%f?+sYTY,-(F3_cq>^ +dJj4Frr3i6qYBseqtKBiBNRl*PeY/Yb/2*:b08#Jrke`Uo#M?YbK7]Dai29BbK%E@`5]puaT'6_ +`Q#p=aSs?^bQQ)0`lQ7"asY9Pb/hZD`59O=_9L0A];/n48RRCS\@fSk_8a^He^`'k`PK=*`Q!JM +29`aMu*6`5KmEcc*oK_SsF3`lQ7!b5]Q_ +`Xp,+_9CK$(E*tq&5(-he&KN"aSEjQaT'BobK.`Dbg3D39LqH@UBqr;ZNjq>gKAs*t~> +dJjCIs8;ckr;HX+rr<#^kiV!^pAb0is8N&trqccps8VWg%fcJ(rr<#srqcWorVufonG`Cas8N&u +(&e14rqlWlr;6 +dJj4Dqu79,rr2rtqn](rU8?98qY:*frqufrrW)uhrW<,uqu6U$rr;lqs8N&srVc`ns7uZms8W)u +r<3#ts8N#rrsnu,q>^Hns7XU2UqP@Eq>UC%rr)cmrVc`ps8N#rJc5ZKrr)cos8<&trVc`kru1k6 +k0UiT[]-t+qt:!brVuoprVccpr;?Nnrr2rnrql^(q7@jd)]U&ko)JXbs6fmYrrW3"qYpL-oZs)! +R@B_Cd.[D:s8N#tqu?Wmrr`9!rVkFKJ,~> +dJj4Dr;R]6qYg?lqW4#Q7nZd?_8jO<`5]g`koa9`Q?'=aNDZH`lA"s +s2b2^rlG,Zs2b/].*0WWb/_WHai;X`is_X5[/W*Xfo(B_91*QdEThQ_nj1,`Q!JM!QN+X +_(WdIbg"JYb/M33_o'=*^V$tNGu-%?/2CV)\@]r(bK@l@_o9jFc-42K`P][7aN4;%'?J25`P]R5 +c(5X\'bV"(`m2TCb4*LJ`r!ghb/hZ@`lZ93Le^N.6VV3ljSJfS"Sqriqu+nAJ,~> +cMn"GqtpBls8Vuqrs7HKjPT\2s8Mrprri5pqY^9LrX&W!s8Vuqs8;Zjrr;uqs8Moqs8E]0qtpUNps8;fo"8r&jrVca"p[@k;f@BWq!ri/s +rVm3&qYpHns8Mios7uX)rVuZfDB(/LaR]B.s8Vrqnc&RgrVlip'`It,qu6WprVuoms8Uj5m.'Z5 +iUQpI!rVlnr;Qp!r;6Eke,Op~> +dJs4FrVlrurVZZp$iAA@U7J40q#10js8;lqs6fm^s82d%s7lWor;Zfpq#13l!r`0!rr*-%rr2lp +rr2lrs8Dips83B*d@[5HanPT.s8)Zns8N#t"T/2urVqKK!r`&qrVm!!s8W)srVZ[(q"j="]"P,; +WTX0f)o_@Ir;Zfns6os_s8N!1s8Mros7u]j +\u20kS=cY(qu$ +b5VqJqYC0kpu7oE9LW-E_#DR`ai)*9a2lBGn&POPaSEjUaT'E_bR_t5aiM?O`l5j1]XW_n:L%LsTa_T0^: +bjidO`rF*raiMNCaN;NA_T'C4\oh.M7n69\U>tnDrVulqc2W:~> +c2RkCqu6Tp&,Z.us8VlVmG?b#s8;oqrr2rtq>pTnir0,]rVc`qrVca&r;Z?cr;Z]mrr2fps8Ec2 +qtp +dJs7Fs8Mus!WN&rrs\54U8"-VoC_nYqYC$cs6]g_s8;j"s8Doqs8Mus"T8;jrVc`qqu6Wos8Mus +s8;]m&,5bj_O7RBdH^T-s8W&trVl`ns+1.Xrqucorr<#qs8W&prqud0qrG`,\Zr*:i:HsBrr2lq +rVZWmrr3H(s8)Kds82fnqu6Wqq>LNkSVs7u]pqu?-aqu6ZqrVuor&H;_,s7Y'L +S"6"BTZd3/r;HTo!<2ur!<1=EJ,~> +b5VPAqY^?m%e7T"=&2Fq[(j`2`PKC2rlkJib4kk_nj:2aNDcMK#e;Ac-=AL_o0F1_T;`"/'cMa +]sYDPKN0i]/2C+i[DTJic-=5D`Q$-Eb/D->ai23B_SsO6aNr)Lb5TK]`Y$2,`6m2b'L'RXcc +aSuAAqt^!crrhiRk31\"rrrDtq>^Hei;O5dqu?]os8;`jrVlisrVHKlrVuiq!;uin#Q4T$s8;fl +r;-F)hq-fInc/XfrquWhr;Z`nqgnbGr;ZTsq"jm_qu$9i"mk^NleL4nrri<#rVZZnrrrE"qtL-c +rVm&qs8;oqq>UEirXSu+r;HQIp&+jir;?Tpr:'^as8W)uquZlqrVQU$rVucQm-sH/hsrr1FIJ,~> +dJs4E!<2or(B4@6rVuoe_5Ep$VY0W\s8W&mr;Zfli;O8equ?]ps8;]hr;HZqrql`hrqufqrr)j+ +rVQQmo(hmbSu9$DnG`7`!W;hGrr2onrrE&trsnr$qYK3i^qd7PWS@7KpAP!nrr)fprr3&ts7uWn +"oeQ"s8Dcms8Muts8N#trser)rVP:?qu?]or;ZfplMgb^(&n74rVccroDIFBU7RjHU!3?4s82`m +rri?!r;HT?s*t~> +ao<1Urr<#sqWuOfA5Q90[)(#7cH!fBd*0Dta90T/b0'P$s2t>b&'`/=a2H0DbKeJ\e&fPE`qmdR +b5B<\`r3mV`;dgjZaQoK9i+r1Oe];'cHaVTaMu6?K#e8@c-=JSa2Q0Cao9L!bK.T3ZD)M51bpX; +9p!'4_Tg->_o)Gms2>Mcb.l'?bgFSZaNquIbK@s+a8j6Za:ZG6_oBgAX2`?2d)a;Qbf\/Po#UjN +qoBf#aMl3>`5]j8[D%u.9hJ&W@\DNJqu-QprVQHgrVQWpqu?WGs*t~> +ao;PDrVZTgrr2p-khtRcirB&Trr<#rqu?]SrXSu+rr)lsr;4k3qZ$Ehs8DrrrrE#rrquZorr2p$ +rqu]os7uQl%ckpbf^]"Aq>'m^r;Q`rK)PoNqYC!arqQ]orr)fpr;RH(m.9Jli;N]Urr;ono_ndh +s8N#sr!iZ!s7l?fp&>!jq#C?ip\ko_eC^rVk=HJ,~> +dJj@KrVc`prr<#ts8NW-s8W)j\=]:cXS)G\r;ZfPrXSu+s8N&uqt\P,q#C0es8)]prVc`mrrW2u +rr2p0rr)Kfs8Mccjg1\a]A*2\q#1*iK)PfNrqZR/r;-6bqYpNXc,%?/VR+kEq"F^es8;lrrr2lr% +/^)(qu? +bl@_A!WW/us8W$0qX)dg>>J4-\AQ/+dEg%YaN!bkrQ=rWs2tAc&'E/:`l6'Ec-iQ5dFQFYbkfB\ +a8=!uaMu3:`Poj:aN2KC]Yhh+]XXYJ8PN30U9D&ArknlWa3'"T2Tj7gbK7iHb082Ua2,9kY,I.b +5r^535^BNMa3`,U_oKO.`lQ6@`Pos8beUs6`mN8[a4&8PrlG)YrQ#PaaMc6?aiMZH`lcWQbKJ/Q +o#UjNqoBc#a2Gs:`PfR*[uOrg8P)liOlZ60s8W#qqtg0dqu6cqqYU6As*t~> +ao;D@rVlg'rqlZos4?Mnl0/-H"8i&rr;Q`UrX\u-s8DrrrVu+30td8\qtp?lrr)utrquZmqYpWr +qYgBm$2X]"s8V<2fBi;3rri;tr;Q_JrX&Muq>0p^q>1'fqu6lYlgEodd-^f3#5e/hrqcTkrqc]p +rr3N-p\"%Uqu?]jq#C6krVu`irX\u-r:g6kq"k!gs8Vrms8VWgs8W&ss8;oqqYq!%jQ#Ckm,Qq% +s7lKgnc/Xgf)L7~> +dJs4Fs8W,us8W,u'`\.2s8W&kV5TfZ[dF+kqZ$Tlqu>XS&,lP.rr;uqs5kX[\Ffgtqtg9nrVlip +rr)isrr2g5rVZ]qrr)fjs7cQ\_P3m?dI7)7s8N&srr7WMqu7<.rVQ9fs7lKklGL6D[Ap=Up&4mi +"9/?#rVZ]qrr2lprsJPtmd^&OqZ$Noqu-QmrXSu,q#CBiqu6Qos7uQls6K[as8W&srt>8,q"E=? +T:2LFT!J"grr;orrr)isrr)cqrm:[q~> +c2RnEqtp?js8W'2s8;EAFCn0ID6:k"b0ePU_o]phaSs?UaT'E^`sfr,b0J_[#ni`TfZM82a8j9W +aF$VT:1,1t3 +UU\1eb/hTG`5fj9`r*mga2>a-cHG%nc-+b`d)jPLrPnlY&^&26aMY[/`4a%/bKnMVaj/,taT'E_ +aSa'p_SNmmOBbIQ<)?kUh"LaIrr)`mqtg0fr;Qlrq"Xa9s*t~> +ci=%Equ6Zqrr3<&qu6WqhrNbPnG`IfqYgHQrW)forsJW%n7a$f/V*Knr;?TprW<&rr;Q]irsJc( +p&Fmcs8)]jqu6U!pY4Q`oDJLcKDtoKs7l]mr;$?rm,[NncJAI!%K?1rp&"dgqu?QhqtpBkrso&% +pY_$=/q;7ErVuims7uWurVuins8Vrnrr`2us8;Eds8W&srquWm#P6a6n`o<"o`"jmq#:9go)Jah +f)L7~> +dJj4Gqu6j!s8Muqrr2p.rqlMpV4O9knG<(YqZ$QjiVilXqu6U0qY]_l*#^5Qnc/F_r;HWprr2lr +s8)`prsSi)r;?Nnr;ZZjs8Drss7H`d_kjKFe)p9%s8@NJrVllsrr3K-s7>[HiQApPZ_+V`o_JLd +!WN&srrDonrri?"r;?QnrsIbA:E=]*q#(0jqY^BlrW`?$rqufrqu$Hrr;Q`oli-qa)>sO7r;6El +rm7R8TpqUH^ZbXqqu?]ns8N#ss8MuurVl`p!<1RLJ,~> +c2RnEqYL*brt,+sg4!L-:N7M[)C&, +`Pfj@`l-!taT'E_bU:TXaNV5157Lhpcd:%\`6?3>`l?*@b0%cG`PTX9_8sdBcHXMSbf9%ks2tA_ +&]Vl4`50:.^l2Jj9MSVrNQ^qlrrr,nrVcWjqu6cno_A=5s*t~> +ci=%B!;u`o!<)`n"mF\"jP9V.s5Eqgqu6WqqYm?:.39]Y:=K";rr)lqr;ZcnrrE&rr!EB$s8W&t +s7ZHdr;Qoab15A8r;VBJ"9&,prql^#q<@25k0N/`r;R0!r;?Tpqu$Kor;?Qlrt"u+nq/PA'dY+J +oD&7_s82Tj!;?El"o&&rrVZWnrrN,rnc&RgrVlip%fZM.rr<#sqpt'!lM9`-qYpTjqYpKtrqu]n +rql`qrmq+"~> +dJj4Gqu?Zp!WDrnrXJi']V1pkWS%4Mr;ZfpnG`Feq>U^Ko +s8<#srVl]o(B4@6rr<#ps7u]pnbr*sS>WX2i9g1:K)YcL(&[t+r;-3go\@Bt\uV=qrVlisrqu^*pA4-&-Q`mE+ +bl7eBq"Xa^rsnnqiJV#:9NmRqc,n8Ua7.1L`qd^S`Xp&'_oKsBeqFJJ%1rt$YKY2haT'BW`W4*Z +bl>icaT'6r`QH6?bK7N<]#r1-`3a_Y8PEH=OI`_mK?,=W^qe%:eBYk0RX.pl1H76E@>Ckj\Auk3 +`l?-@_SjU?aN2NJrQQ)!d`c5<'ab][!6WL.b0%T?_o9X:aSs +ci="A!<2or!<)]m"mY.6hs'q8rrrE%r;6KmrVllsrVZ'^&HD\,rr2gu-QaNT,:+S,rVlcq!<)op +s8Mrrs8E#rrqd-%qu?TnrV-9hr;Z]kqu6fUcI^q>qYpQprquWl!;u!Y!W;rjquQfpmJd+brVl]l +rr2lop&=pis8N#qrr2Tj#4CU5j4)BDqZ$To!WW,rrrW)srr2rsrX\mu/L;Va)&jYEK(o +b5W:WrVlforr2lqrVuopp:R)oT!d8Fs82]mrrN-!r;QZp!<2lqq>U9k!<)or%Jj*L)&sM7+!-mG +qY^ +dJj4FrVm$!qY9mbrVllsrVmW%fSEU(8njU(b/q`Kb0%fF`Poj:aSs?^aSX!QaSj-Y`>$/,aNW$h +$jdIU&J#4sd)sJQbK7m%`[AjPccs_WaMl'3ahu3A_o]s6_o9R=bJ_<(MGlT+;eqGq[CElc_oDJm +s2P&ZrlY/[rl43D#0P$0aNDTHn&PRMaN"(tr6"rY!li=$r5el[s2b,\rlG,Zs2[FI`l5g4_S3.: +HVujW/0uZFQE@s?_p$ELbK7`D`lH?OaNDTJbg"J[e'`LQ&/Q6$'F4hHcI1"T`l5j7`lQ7#aq)k> +bKS;Sb0%`A`5TX3b/X;!!6Y8]rl4uZr5oVm`l>s6`4;">;b9Y`=aSceo)/OfrV6BqqtB[WrRCjt~> +ci="Dp&>?tq#:13jqu6NnrpKgdrW)lnqu6Nlqu?TorW2usrr3'!rVlcq$iU#$qtU$fs8;osrql^" +o^25*ceA-hs8N!!qZ$KmrttV4qYpKlrVlGd.jH;a*ul:D*@!2mq#CBYrqucrrqu]orr2g&qtg0e +r;-?jqZ$Hkrs% +aSu8>rVulr(B=@4rV<(`US=XFp\Odes8Dutr;-Bkq#Bpar;RE.r;)p,)]'V3)]r&C7)rVZQiqYL$P`MBEGa5H:Zs8)Wm"T8<"qYU0is8EB*rr;rqrr;ur +rr26`"9/?"s8N#srV?Hjr;uusrqQNmrqZRDrr;uts8MroqYU0fr;Q`rrVccrq>UEfs8)ZlnCl!s +]rIa2fCo4?rVc`prVuj:qZ$Kms8Vlor;ZcorVuPf-QX3G(Ddr0)BLB^pA4g\rqucrrr2lrrr2p" +rr;usq>V*+s8W&tqu?Hii2EH@USjQ]m/6k_rr0h8J,~> +bQ%S?p\u!+m+#TM;,CMl^;e7=cH+#H^:_;$b5TWgb/V?:`q%1N`r=!l`lH6GFp&$V(_R]"1pkHN +cca;KrPnfW6c[-M;aNDZDaM5a+ +^7/A)6r.)nHHPLInG`Uhqtp?@s*t~> +_>aoBrVQNls8VKEjQY7orr`,lqYpHn!;uil"8i#qs6oses8W)ur!rMM:*pr',TeGJpAb!fs7lTn +rrW,pr;6L!r:Tser;6BjrVlotrVZ["o$,G3i:?mFrr`2rqu-Kn!WDrpr;ciqs7ZHWr:'^as8Drm +r;HNkr;Zd#rr)cnrVlcq"oeAprr;lkrs/Mlk3(p`d-CT0!rMonqYpKo*;][4r;6Bip&Fj"9dCW$ ++s&$W,TJ'M+_LcLqZ#j[r;Qp!r;6EirVlfo#lXYtr;-Emrr)fq#2J>*n_W-frr3-#r;?Qn_Z,,~> +_>jQ5s8W,r$1YHqTW4aJqsaR`rrN,sp&FO\rVuoq&,4FC+Vbh5(aZifs8)]orr)lqrrV'*rr;rprqH3MW1KBKP+TA]p:UEU~> +^&K)EjMu[J:Kpts_S"%;bf.H5_oTm@c-=JR`l#^6nAkXPa8X'iaN:D5%1/]rPnlYs2kDeb/jP$s2b,\rlbDcaSNn)b/q`F`lH3AbKA#P +bfe2Ud)Eu@]=Y__X.4W?2(0^q/7+^T`PK@0aSs?^bl>g1c-4;JaMu6?bKe2Zd[)Qm":u1V()[o! +'+"q7gWR[^`l5s;mDoIN`Q$!Ab5TTeb/hZDrl+oYs2tA_&BD`,_ntdRV6sPMsiV'tbJ,~> +^]+Z?qu6NnrRg;pjk]q9!W)`nrri;qq>C0irrW2tr:0aurVlfrrr2lps7ZJD.Nol_II$k3!W2ik +rY#/-rVuils7Z?frr<#squ?Tlrr)iur:g3errgokdGO9drrr>srVHEhp\tBpqtg3equ$'pcrqQNlrquZtqu-HjrVlfr$N0_ss8Mros82Zlqu6lejm:mKf'WG9"ShT^qYU-g*rYp7 +s7u]pq#C0bdTS1L+"&16bk/4c+ +_>jQ7rr3B$r7e$FSY;n:qtpBls8W'#qu$Korr2osnbrUgrr2oss8<9(p&'4a)]0fGlM^_`qu-Kn +rVd<)rVccpq>^3erVlisrqu]orVdc5s8Vrgq=a@8[%=/$^tAM[qu$Hns8N&sqtpBkrr`2tr;QBh +s8Mrr!<2oorr)iq!WW/arrN,trVHZorVlcq!<2ips8E#sq#:Nrs8W∨Q^,qWuqP]#(qRZHW(= +q=jXZrr;usrVmu=qZ$Tls8VloqtSQ?-mKZV*`pMTYoar)(*4j@s7uZis7-*grVulqrrN,tr;Q`r +(&\%1rr<#sr;ZHKUn=KTTWFmGq#1$drrE&9s*t~> +_Z']9q>:0k)XlmuCL9_.=II%HbKnAP`l5s3DjdE*]u.q2_oKj= +`Q%nts2YJgbg"DUb/q`GqT9#``l?!:_o;Pprl4rV#/eEt_o9^>rQ+rWs2b,\"3AX-bl,ckbfIfC +_nj1/r5^>0bg+JWa2Pm1_8F1-`5T[;d*0MI^9F8jF]^RV3\r3OCT"VX`lH3Fci(r``ZN.7bg!uF +cbe&Od^)=](_@>e5dB"4%M0?d&eh(raiaG!n]:aMs2b)[rlG)Y( +^]4<2#lFT#s4Hf%lIZ%8#lX]"s8)Njr;QZp!W;ibrW)onrX\l*q=_lW-:m_-rr;fls82Wk!<<&t +!W;oqrs8T's8)cqqu$Hkrr`2to_81]#5Qcne)06_rVllrp](6ls8W,uqu$6gnc&Ugo)&^hq=sd_ +r;Q9es8E0!qtpU`uoB5&pkh=;:r;R!!qYgBfp&+[cs8O,3r;Zfis7,B&.NolV ++@`g9r;65.,U"BT,>n@;s69O_s8W)tquH`krrN)tqYpfrhWaFombc=fs8VusrkSPa~> +^],2Mrr;omqV\'FS#E+@q>1'erVulps8W)trVlcrs7-'grVc^.s8N#os7c-',9]JEs8Dunr;ZZm +s8Doss8Muur;HWp%/p5+qZ$Tns8N#trr2os(&Rk-s7uBcpA+R7WhH>t^tS8Pqt^-grri?!qu$Bj +qZ6Wnrr2fpr;QZp!<2inqYog\!WN&qqulutrr<#rrVlfrrUp1*r;-9is7Y^6d(m6"X/!/`rVZWl +qYgEn!<)Zl*qfL3s7QE`l?js")B0Ya[JKk!p2;)l)AsPiq#16lqZ#s^rr2utqu-Nn!rMoqrr*E) +r9Ve,TUV:BUS$W@rVHHl!<0k8J,~> +_Z'W7rqIN4s8M]V]4bJ><*,a/_o]m>c-+8Wb/hQ>`Q69Ib4/]s2k>crlk_mb/hQ> +_8!h+r6#&`s2ub3ai;98_8O:0_nj.$\@8lLRXf*K3@u^0.nt`"\A?/+cILRsbf]q)rP],^`k014 +c,7oH`*iQY&ets0QIaU8r?e^;X_qSqpDqo\fW( +_Z'l?rVZ]qqu$L9f +OXDOs+!;Vrs7QEkq#9G(+=/$M,ddUOkPkMZrr2Zl"9/?#rqud#iU,_!n`J6trri<"q#(-,s*t~> +^&JW@s8DojophbKV5r)Cs8)Nfs6KXarVZX+s8N&qqu?KfB%?hZo(rCcq>UEkrXf&.s7cNmqYg3d +r;-Hnq>^Hnr;cioru(e1p%S@YpAFRUq9l+:Wj'CslL=WGs8W#nr;Zfq"T/,orVcQk!WW/hs6TaX +rs\o*rVZQiqYU0frVlfprrW2trVlftqu6Tp&F\`1`kJmbX.H]Oo(MYJqYU9l"T8,mr;QQm!<)os +)Yj7-p5gRH(`OG6ScAHas8)cY,SqC6(a$$]rr2fpn,E@er;Hcrr;?Nl)?0R5s8;lrqY/O0SsH7F +TVMAVrVl`pr;Zfrrknbd~> +_Z(MPqY9j_rr<#sl-WsD:/tY^_90d:cHjb]aSs0ZaSs?Pa9'K+b5THs`lQBEbLFnf6a+kc_T:*H +_p$-?aN4A'3m>jpc,%BC`llHHbfIuK]#W%>b/V94_8FIBcd'\Rb0%W8_n!:cLJgc98m6@gMOh&k +aiDNLda-(UrknlWa2\+prkncTs2OrWqo/HPrQ+oZqT/ZY!6G)Xr5eiV"3&:$b5KO6b/VE<`PopA +c-=__aM5?sXI=QO;F3H&1,q-mKrMMm_T'U;b0%fHbfn0-`rF$X_]ck:ai_]MeC/LN((:`c#_C^N +cd'_c`=X"6'b1V7eBZ4Xqo8-HrlY&XrQ5l#bfe&E`llB:PuCOQ=\r:Bf%K9Zq#(0irPnkf~> +_Z'o@qYL6lrVZQlrr3,Uio\tQrVlusqYBpcrr;ltrr<#^rXSu-r;ZKdqu?Hjs8DrsqYC-jr;Q^& +rqQNnrVuios8)`or;Qcprq-EirVuosq#:Tkg!\F&iUQpErrDobs8W)uquZcnqu$9hqu-Hkrp]sf +rW<#pq>U-kq>:*hoD]!nr;?NnqY^@"rU]::j58M>j7rHM"9/5qr;?TkrZD1C6,s*t~> +^&S-2)?9^6qWt#PUmnF=oDedcrr)`os8N&urr)f]rr +_>aN5rqZWnrr3W.keq7@<_H__[E?V6bf[lD`lS)#n]:[Os2b5[!6G/^&'`)9bg+5PdE0JN_T'U: +aSs=Abg">SaN;HAf%JR,d*'SK`m;uT`l#R+_84+5cI(%baN)?LdEKSBZ'fAp3B]c1EKHotZaRK[ +^&Gqc_o9U7a2>a2_nj1,_o9U9aND`Nb/VEt`r4!Tap,r0aN2BB`r!jS`VdaUaSs?[bU^iU`Pf^4 +`Q66Kc+LZuZ`'.3>X:5"/hf.XFKVp\ajS\gdE0>D_8XRBc,fk'rl$&#`6H?Qc[lH7#S@RXHJ6fd +ahkpBb0=?6*uc"-7+06#aSX!IaSj9WaSs +_Z'l?q>'g`s8;fmrrqTEjQbXmrr3#qrr2p"r;6Bhrr;Qgs8Vuq%fcG(s7lWoo`"mjqYpNmq#1m* +rqQNmr;ZEGTum?1p](9krqucsrquck#P[les7Q?eq>($qma]V1hrXA)qYp`sqtg0er:U$ir;QKh +qtgEiqsF@_s8N#tr;QR!q>:!_q"agbrqcWqrVZWo$3'bjmHrf^dGFZprr`9#s8Mus"9/5rrV?Hm +r>kq9[oOIo*@MqOl1juIqu?Znq>^9G.3BWS*c(TOl2Ch`qu$Bkqu?Tn(]412s8N&so\o$"l0RTn +s8W&tq>U +^]4?4%fcD&rr2WcpUI#iUSPlqrr2rts8N#t!ri/snc&Rgqu.**qu$Khs8V`js8Vrps8Drsqu.6. +rV6Emr;Z?AS]1X'pAb0lrVc`pqYqQ5rr;rsrV$'es7ZEgqX;_3TVJm-bhVFQqu?Tnrr<#ts8W)t +qu?Wo!WE#fs8Muus8LsVs8E,urVc`pr>>J4oAeHD]:'frr`5tr;HKk +&c_h.rqa!!(*4>>)Kb30()\!'p](6ls8VKcrVuoss8Dcm!<)lr%fYe?WM,lK +SYNIdrV?Khrr3#us8Dr7s*t~> +^]+E3q#1*hrtY(deq@O/;,hqFa3DiPai26?bg"ASnAtXOqoB8i`Q$-=b0e#Ic-42MbJaD"s2b5_ +s3)2)c,.Q@`n&AIJuIPRb1"_`c-"&DrkTht`lQ6?^qn(.bf7E7`l#9sZ`]jE<_>_H6r[fCL6nj@ +]>VhjbQZ86b/hZDr5J]W"Nns5c-#n(q9&]X#0+a(`l5s:r5ScUr58QRs2GDeb08)Sc-OYYaN"1t +s2Gko^qI:\TSIVu:H^Tq1ce'8N2<\f`PomsaU-/1aN)9;`5]m?qT'r%a2uWUPrf6a%2K7Ub1+VV +aj%lF`QcN9*ZZ%-"%UY]b/hTBmDoIRbf\)LaSj-YaT'E_bl>iu`l#d3WJFeV91DfgIamZPqY0me +"9&,qrP\_d~> +_Z'rAr;-?jr;Z]prr)j0mcNWok4nuVrqucqs8;ckr;Zferr2rqrr;p(s8)cqq#C?is8Mops7uX( +q>^?lqZ$8Q,qUPmEn9s`quH`prt58.qYBm]qu$6_rV6EmrVlirqu6s$gsja(h;IYqr;Qltqu-Hh +rqcZmrqHUj%r;6C6frsJ]$n*0$$kM+_Jn,!%pqYUMK7s8'ef*[MjK+LCbrr*#sr;?Bes8W) +^&J03rqcWo%0$2!]V:pgWQk,9r;?Hl!ri/snc𝔒Q`p$NL#'s7u]oqZ$Qlr;ZZn&GZ;'s82ig +O!#eq+`>d#qYg?kq#;E7s8Vurs7lNlrVc`nq"O('Z)Xb-]"ueRo(`._rr)irq#:3iqYp6h"TJH# +s8MZjq#9sd,6%K;rVQ?Zl/^.+]",)@TrPrhp@\1Yrr2ios8W&ts8;cmqu?Kk,Q7Z<`@)QE()e3u +o_\Iarr;lqs7cQhVA^Ep'e-Nas8N#ts6KXas8MuurVlWm&H;_0r:o[&TqS$PUn+piq>:*i!W)ip +rke\c~> +^&J03s82fq(&7.HMd]CS=GXH0ai;<;_oBjCc-4?#aSs#>J4MLP3^cYLHBY#+ +\\5bpa7m[Rb5'9Zb596^`lQ0@qo/ZU`r$HO.jRW6K!ri6"rVaY6J,~> +^]+E6qtp^9j +r;Zfrrqucm!W;rmrs8JZcHO_iio]n#rrrE%rVZQlr;Qcro`+sjqu6cts8W)prs8W&qu$BjrVlfl +rsASnnF>Yqccb)8o`+sjrqmi;o`+g_qZ$?jrVHEkrqcZnr;ZFo,oS*R+)CKGrVlfn%K6=uqi)gD ++sA:bq>^EXrr;lrrr)j(rqZHfp\=[cq"t$hrs.66n*K<#hV\;3rVQZpqYpZsr;?Q7s*t~> +_Z0Z8p\tp)qsVLnS"u^iqY^ +_>jQ6rVufo(%geccsW'aSj-YaSa3MaSj7+aiD?;bK$4e'G2)i%L>(Z +cH"5Ra2c0<_T9^7ahu3=b08#NrlG&\3QB%S^UgkSQ#T_i5!DA-?[J*5XL5[S`5p'Bbg4Y_c-",H +`5U$Mcd'e^cd'_Va2Q$;`lH0Ab/ha)aT'9jaMu?Ba3)WObfRoE`lH*u`F$[-bfIT5]t:k`YGRnL +G@XW=4$G\a1d,&qTsM8C_8XF6aN2NFaMu6=`l?6=b/V96`kBL5`5U*G`6$'Be'C8m&0);h;Ua1A +b/D08ajS>`D@@$f$OL.bc,[oFaN4>&n]:aSs2tA_s2Gnm`Q,s +^]+H9qt^-grr3#trr2p$qrm2)i7e21#lal#rVuohrVY+Cs8N5srUg+=rZN@%-QFNY,UK/NqZ$Tp +s8W)us7uWnrVuosqt^$^q>C6krrW2trqcX%mG$(4ce.7?kP>#Hrr`9!s8Drp!;cKjqYpHn"9/8r +qX4@nr;6NhlfR3ci8NPIf&HK$rrE&orso&,qtg0dqtg3iqZ$NopAY(9rql`js8VcldO61\*[)]W +r:g$cqZ$K`SfT*s+sJD)s7uWWrW2rrr;R$$r;$'\qtKm`rs-sAoCDG:hr4P6"TJ>srr2`n"9/5r +rl>%h~> +_>jQ6q#CBm'Dpq7U77pY[.s@nrVu`ms8Vins7?6fs5j7[ruCn7o_p*S(`3l.(*X\@,bsc&s8Dlq +s8N&uq>L?mr;ciprrE&sr?)%=s82Q_pA".0^ojQ.VR""Ybi@jQp%nR`r;$3drVlfr#QFc'rVZTj +q>UBmrrN)rq>U?ms8E&sqYpEpr;HTnquQ]mrVuos&c_XlkN_$SaMPQrY,7n`Z-DV6q$6fsrVlcp +rVc]o!WW/prrE#srrDfms!%I>s7u]po_m&Z(`=23+4U8br;ZcrrpcO!+;l.>,FSQ+rVli_rW3&u +rVZ`qqYq0)s8Vuoj.**AS"QOQ\GZ'trql`qrW)orrke\c~> +_Z']9qu-Kn)ZBO0qu6KdmE_D085rr5[^sApb.b^7bJhfMo>psO"NAC#aN45#!Q`FUaSs=&aN;T: +_SFb5&/c>r(^_#j&-dO$c-aeXb0.lJbJX>"r5pA1c-=S\c-=DP`l?-@^q@1SK4@J72*=T?D0:l( +TW,6*]=tql^;'Z_&]Dc8bK7iH`P]d+WW!UD!Uons7lWWrqud2r:p-^pAP!gs8N&uj7)[8r:AS*s8Muss8Mcm"9/5rrl>%h~> +_Z']:rVcNk&H2V,qsq\$S"ZgipAOshrr;us!<;Whr;YmX*rkm3s8&H7'c.]1()n,0*?Q=OL?&%( +qY^0hqYC0dq>VT:rVcZmrVliqqtp^Bms8Dorrp"8A(`4,5:%eJb%J@,",9.OG*GOd4q>^9is60FarVZWnqYq3+rqZKEWhc)LR\#k` +rV- +_>aN6r;RZ5qtg3hrVcWeh3;>E:fqD:_8jX;b/M??bOWaS`WjE%`lQ6Db5BHbb08#uaC!0&^WaiO +'b_Q+*XiPg'GM)c&Sf86e'H7ZdDs8Qa3VcE`lQBKcdC4hccsVP_o'U@bJhE:_nNUfW/"kU7n,j3 +85ro/E-RY:TVnou[^`fY^qde&_ns=2a2Z*=aijM$s2QY0`5T^9aMl3@aiqoI^V@1XU7%-tH"U>W +7mo^05X%P+<+giPXKoOS_Ss[sbQH#/`l@trs2I%>a2cccF5L_84CCa&3N_ +*#fVLc-FGOccMJ-(D[`,#>2nZajIoF`l?*BrlkDblc9g\`Q?'9aiD37_82=@<^o5>9i[_Gn+m"] +rP8G`~> +])Vd/"9&/rrr2p-oASrqhrXV4qY^Bhrr;lCrZM%:s7H(^+t+WV+bV3e,T@aH)]U;>bP_;Uolk1J)-db!72i8j4qqUb`Xq=a@Glf[ +_>jQ6s8Mlprr!H.r:\1,Tq.d`g].-Js7cHkr:0dbs5s;'s8)cqo_(os*uPe3INfdQ'Gqi.)CB%9 +p\=[^q>^6dqYU +]`8$1s8)iqrr)j.p=YgEF+s%L2D@['f% +MBHb$PQ:8f@&*kb1+MTa2Z*2>-cHF>Qbfe)Mb5TK^`r +_Z0W7qu?]ns82rtrVlfr"oI9@kMt:qrrE#qs3goHr>kq:Zn!+:+r:U'prr;uqq>:3lqu6Wn!rMurqu7-'p]($\o_8(;W10=.r;Q^:rVu`hK.%`\,TfPQ +icHIe-QsU*\G?1#p](!fs7Y^V!W;rqrs&K"rq-'erVca$gZ.Dcp[[A:rr3'!s8KG+J,~> +^]4?5!WE#orso&.s8DW7URe$RX7#ueqYgHErr)lsr?)(;YpL/!(EA+tnWtOJ*?H.=*Z6A#[dj.f +qY1$_rr2lp!<2lq#6+T"s8W&qrVnSNs8W#nrVQBhqtKU>c+'mKTqeNdY-G:@]Yhk:e_8m=l1=fN +rr)ckqYC!`qYC!^rqRQ*m,QsSe'H7Z_nEUk[BHR)T:MOG[E7(apA4OXrr3,ur;Q]oq>^?kqu79- +rVlcmq#CBd2V59a^RL#:uq=t!irqZNlrW)utrk8>^~> +^Ae?5qY9sdqYq0+o\H6R:eOo#YJnW&bKIoH`p(SBao]f0b4`pT`rF(^bKPtZ&K)K&E7*$W&K)B' +(DRYn(H@o3eBlI\e&'2Ib08,Tbf[rC_84%,`P][3_o'UAccsSQ`P0!u]!AQ>VP'*#B3S#!7R]^4 +6UF79RFTa,`QZ0?c+_9Ab08#Nn&YOKs2b2^(s't=`lG[&^9N]&>Z"*e;I5jOnGWCerVlfrr;FA0 +J,~> +_Z']:qu$?k!WN#orW)iprrqEMi9'"jrr;uod/G'ar;::P,:"H`cM@M>oX%4;+X8!L*>fkJS,3-a +p\Fghrr)`prr2p+p\Omgqt^*crVlcmr:9jkpZ^VjcdVjD"P;2Vg=lP\!o2ViqVqJ3!oD_drn.Y1 +eCE$qd*p\0nc&:_s7ufoqYU3j#6"Gss8D`aqu6ctr;HWis!@43o\,3q-mp>h+1h7Go`+ses6:aQ ++!MOI<@T4?+!)Ssp\+X_rr3)tr;6NYrr;oprri?!qtL$ers7rKl/h9slK@g +^]4<4!WE#mrs\i(p')BTk;)AX;=QM1.Q +p&G!irVZ`qqu6ctrVl]mrs/Q%rr<#tr;HWps8b;$VO=!JTqeH_WNED3\@K5a +pq?X<+1\ni['?g7W268^SY2jd^s1WtnFQ>Fp\XshqYgEnrr2p"rr;rrrr3N.p\t0jr;HTns8N&t +s8N#srVumDoDSUGP"?lB+X.l7p\jdbs7u]X*?Z7@'Hp@$+!DO@*h +^Ae<4q"jsart#,&hPXpk9j)1l\\uP+_85Z_rlXuVrlXoTrPg#'bKA.%$6(0-)6D'-dF+F>'G)#n +'bLc\&UDjQd)=>SaSj6_aMu-s_)9-L`l>a0aN;TGaN;QD`59F4aN)05_8O4)\[8`AQ%3RJ7Q`=[ +2E*TX5X7h3:Jt1n='/I$qc3Yp*`5a/8k;953AW67,9IpN0LT)aLRP0J\@]MqbKIoHrl5Mjb0%fI +a2Q'=_n`k&`le8()Tp%<`lH3CaNDZLcGIlO[:q3'%h9*OQHRC^rl"rk`!$&U*!m6F)AF,)&J'NC +bKn5VbfmuC_p$9Gbfn5N`l@Sj"NJF"`lS)#&]DZ)^Vd=( +_Z']:r;?($Xrs\\ll/pjYf[A'jcd'T-`XL&5b0/)Yf@f'A +lLOrIrrrB!s8W)rrr3H)r;?Hdq#16kr;6Els7lTls"= +^&S-3!<)orqYq!&r:Ja3VOEpRg@kFBrr;?aqZ$3eqYpm!r5g3)&0;fsqYpL,qt^!2B-89<(Ej_? ++<6./s7uQls8E0"rr2lqr;SDJr;Q`pqu$Bks8W)rr;QZns8Muqrqu]kqY9m\p\O[UkMFb5a1]'k +XJr(nVP4!`rLk:1VP^8kYI(dS`6?immIg;Jq"agaqYU3jqtL-jr;6Kns8N&u$3'l$rr)clr;Zfp +rr>P6rVulnr:A+&UR@aBUSd8JrVHNls8W&gs8W) +^]4<3qZ$Tl')28&s7YBY?s?)g>*QM9bLFh[o>gpSrlbGdaN44toZ7!N,/qRIbKcgi&JHB,8^>At +`m<,]W_*X3(D@i*(D$UZbgOPQrl+oTs2>&ZaN4;%&'`58`Q63C`lH-Cc-4>Na8O4!ai208^V7@k +[^s>k9`@fc:bPaF:esth>$Y`TFF]C@V6-i'[(!TW]tVM%]u8"0_T0sE +air#SbK7lIaiMNDc-cI1s2I@Gbg"AQ`PTI/c-4J0C(M$l)%@N"'GM)"dE'JJbKnXd$5X9p',)K"% +M*@(d)aPQbJ1m7`l?*Ab08)PaMu3<`q.7q`l5p:aNDZLb/MH=]Y:b4=&;+N7U0iKi:QjFrVcWeq +YgHmrVHNrrVQKja8^Y~> +_Z'`;r;?QlrrE&qrr`9#qYU9l"m+n8j50#!rrW/sr;?Qor;Za!s8N#qr8IVsqu6DE.2jWT-aisO +rqufqs82]TJL;Q^)^-:K,Uh=Crqccprr2fp#6+Ptq>1!dqYpd!s8W)ss8W)t"o\Ats8N#prrE#M +rtYJ/qu$?fpA=mgrVlisrqucpr:g!aqu6`rqYpEjs8FtUrr;urr;-6)L+"Dk,9%gL+sA-M,pSHL +qY^^Bgrr2ifrr;onrqud$mFUXmmd')err<#t#5nN# +p\aaar;Zfrrqlcq_Z,,~> +^&S'1"T/2ts8Muss7m3(pu/3DTpqmon,!"]s8W)trri?$s8N&trW)uprqcZerql^;qu6>@,8215 ++L1nEs8N&rs7uKPJL)?W(`XA6+!fM;qu6m"rVcZlrVlcq!<2ut&cVb-rqlTks8N&urr)fprVZZo +s8N!#rVlfor;QWqr;-Eds7QEcrq-!Y!;?Bc!quB`r;$Nns8W)rrrE&qrs&K$r;Q`rrr2rtr<<3# +rVQHjqYrMPrVc`or;-3&JgM]]*Yob5)Aj>**Z^.9qYgEnqY^"5*>KJ2*>B]=k5>)Us8N&ss8N#t +q>^Bjrql`prr)lorr2rqrr<#uq?lZ+Tr=WQT;\^NrVlg#rVuoos82Efs8L% +_>jN5q>V90qYL!_s8Mrkk.5D-9L`-2[`6J5b0%g)`r4!Y`rF*[b5KNeb/hZD`r +_>jQ7o)A^hr;QrTio]I_g&:pVrr;rsrqQHhr;Q]ur;$0dq#CUEorrrr2fpqm.[i,pXWY +ZMaY#p](6ls76-hr;QTmr;6KkrrrDur;ZZhr;R#[j72L&j4<)ds8Mlqrr2rtrqZTnrk\Vb~> +Z2Y@6qZ$Qmr8FTKT:hjShY6sIrr`6"s82fqrr2os!ri/sqYgKprr2rtq>LBor;Q]q+T1FJ)\s5. +9(W#]rr2rss8W#os7)C'*Zc=>)Ajjcr;HWp"oA8urqu]irrE&srrW2urr2ourr)`nqZ$Ek!WE#r +rU0UYrVZZfrsA]&rqufrr;Z`qrr"/@rr<#ps82ijr;Z`ns8W)f_gWdM+WD.8*#Tb:,Tn-J(*[nu +r;Q^/r;ZVt,8;+:)',mVr;ZNkrr2rhrr2p!rr;uorrE&srVultrVlg/qu6WopuSEFV4=3OS[.5P +rr0)#J,~> +[K$7)s8+&:s8VfV]5_%P<*!P%\\cV;a2,^3_T9g<`Poj>c-OVVb/h[$`W4*Yb5'*Yao'4Hai;07 +_@@A#)Ab^]2.M_ZRlt`lS)#rQ#Jf_8!^t^r"+6b0S>TdEDO8!6tMc36&eW +`Qc6:bJVEHdF?=7B+Yaq(D.Aq%1W[V'G_Gm%T^oq`PKO2bKc4]%NQZ.&!PJbdD=)MaN=1t!6Y;^ +#KFp2ccs\V`r3jr`lQ:7;+F;W>(OZ]rVccqrUKpfrPnkf~> +YQ"\'r:U'h&aSKAki:Ums8W)rs82]nq#(-jrr`8tqu6BjrVlipo)9d3rVhZo,9J9\W;lhrs8Mrr +rr<#qq>^Kd\l'Uo+sS;'rr3E'rVuorrr2rtr;6HmXT&.t7K!2aqu?Tfs8;]ms7ZHls8Dfos8Dij +ql4Zc,U4NU*Zl[R)_+I>hRb*_B[unXqu?Tnrr;or9ICf"+!kUms763iq>^Kcrr;ltqu$Bjrr2fq +rr)j#rVZWko_JIc#l +Z2ak$s8Ni0s8;/kUS4?SW5eQ)rVQTls8W&ts8DrsrrN,to_njjo)AXg%#GfA(`jirs8Dutrqu`p +&Gu8&s7*Qm(`F82*1?d*s8;lr#Q4Q!s8W&qrVlirrr2rsrr2rnrr)j!rr;utc2RP=%/g/(qu?Tf +s8;]ms7cNm+oV9;s8Dilr2O`a+WhaC(`=G=(aqq4gUA=NA'suLqu?Wort,,,80JZ\(E[2Zs763i +q>^KcrW<-!s8Drpru:t9rVZWjqu?]ns8W)mo[B_6UmIaIVonW.q#.>pJ,~> +ZMu!Eq"Xmhq"EjhKk"7b='gKe^;n.1^r4L8`l?!:`le;)!m8U*qo8ZW"Nns4b0'=s6-$pfCCMF/ +*u0R^aiME9^;.M#b/qfUeB4.=&/Z<&&;/TZ`kB1-cd'qabJqB8aihN:b07rG_o9dBb/V98b08$+ +aSj*\aMu<@rlG)]q8iNWiQ+g;aMl!1^r47L +YQ"_&q=X^crs&8Tkh>7^k5G;_q#'pbrqZTnrr<#]r[Im80-MGX+sZ[Yqu?Zqr;Zfrrr;uor;ZK[ ++s.sL-(k,8rVu`oq>UEnrVlosql0Q"r;6?js8N&rrr5+[rVlisp](9kqu?EhRj':),8q[C*ZuIO +<0bu2s8W(3eG/tAs7lTks8W)sq9C96+=&0VbQ%V +Z2Xh'rr3]3s8DihaJ>c%Vl-p"o`+sgs8Dutr;H]pqYpHnli%7kmOT=q()n=`s8;lr!;lcq(]OI6 +qY^BblPgWX(E].Crr2rqs7uWmrVc`uqt^6jrr!-%s8Muqrr2rt^]+62s8E3%rr2imqYgEorVc`r +rr2pBq#CBlqZ$9dRNNpu+;Pq4)&sM?;O#Z.rVcY+de8aT);9s8Dcn +nc&Rgs8N#rr;QlurVZTjrt55-fZ9ndS>)CEU=K&7qu-NkY5a"~> +XoB%2qXj")RUol!='BIS]?JL=bJjJ#s2b5[s2>#[b5KE[`rF-[ao]f0b4E\>b1+QQ(a'_3$d?u8 +`l6!;aN;HEcHOAPe'QVW'c.GoK%/)baM#^7c-Xe]c-Xkgd`fq_dEThRaN`&TaMYp:b4is[b/h`H +b0e:,bgFh_b/hTDb0%iIbK7cG_oKa9`Pfa7`k9=8aNDiMe:%c=%1rs]%20Bb'Kp]Jf[n^)5HN5\ +e^DR^`lZ9@aj-ss(`45,$`DS*`QuK?ammIP`rF-YaoKZab5THrcca>H`l,d1Q$cJ+8l8&YC9-%O +p&+gnqY9j^qu*u'J,~> +Z2Y%-qtKm]qu-Kn$eXLuk2c(4s8N&nqtL-irr<#]rY"k&+=.pK-D1>9rVcZos8MurrVlg+rr;qh ++s\?X,0'Z[s7QBk#lO`$qYU6js8T5#rVZftrr2lr5Q(QVs8Vrms7lWkrr2rppg,3`+!_XJ,:=[B +Y2oESqZ$3fpAb!hrVH9gs8;fkqu?ToAge`E*@G4fqYpBks7$$arrrE"qtp +Z2Xn(r;HWp'E.e)p"-%:StDjqo_%tYrr<#trVc`qrVQTms6T^urUd!-+;>_:S,`Ecrqufqr;HWn +rr<#t$i6>3*#]h<_Z'E3pAY'pr;QZkqtp?lquH]prr2itrr<#trr<#:rW2uqqu$Trrr2lr4oYKX +s8Vuos7u]mrr2rnp0&US)^#e:+=&%7XQ0-Pqu?6ep&FmgqtTjas8;flqu?Ql@NlU*'d-]Oq>U9j +s760hs8W)rr;uuus8N#tr>55,rVlisp@5PdTUqsNXeOMBqtU-hqu3buJ,~> +YQ"V$rr3r7oBb,-AmA,-Sb/_N@^VRP$bJM0<^s0d +Z2ah$rqQQkrVm<&f&lD\khc@>qYU0cq#BFSs8=AB<$N2&-m@jPs8W)urVucns8Mllr;?N`-RBiZ +,Tlp\rVZ]qq>($grr3*"r;?Mmr^["fs8Mops8W)urVZ]prr;orq>^6fOWPPi+<)dT +Z2Xq)s8W)srt"o&o[BP4V449Xhu*3IrqlZmrr)orqu6QomJ[Ikr;';5&f`/;kPP8Y*<,j8q>C9l +qY^ +WrE\0o'P&-Bjt+5;d5j4`mN2Vb5TE\`<*lnaSs?^aSj-Ga?dkjfK0cW)&WRma2c0=cI1Cod*KqS +_Sa=9b7#'t((pc%cHF5Oa2,a=ai_cG`Q$*Hcd1(fbfIfFcdC"[`l6$?rl+lVs2b5_s31Je!mJa* +ouR0QilD,BrlkGerlPYjbfIoG_o9R3_oKg=rm*RRb0.cQbLCG7%iuGo((*'Qa2cBMccaGPfZDL^ +a2u`CEja<@aN)?GbL4!0()eJ:':@G"_SsU8o#M9[_8!n,aND`Occs_Yb5TC%dDs;I]!7B"9MIuD +8mcPXmIL&Ls8Durqtg*_qYU6!s*t~> +Z2Y+/r;QWkqtg6irVm2[f^.qfh>I^$br;Zfrqu6fuqtTsZrVm0& +jQlC$kjdcar;Qosq>C3fr;QluqtpB%s*t~> +Y5\M#r;R9'r;,l\RAZXMVq1hCr;QZnp\t-knGX7(rr2lo^De76(`di#rr;rss82clqYL3irtYCB +*>KG,)iF=cs7ZBcqu?QlrVZWnrr3-#rVc`prr36&rVc`ps8W)ts7?3is7QBks5EqWrVlfps"aTM +s8W)urVHQiqY^$Wo^htQs8)Zg@j2m.,>k&sr;Z`qs8Mfms8V]grV#--80T::p\t1)rV6?ipk0_# +'Ghrbo)&IdqZ$*b!<)or"98B!rVcWorr2p:qZ$HeqU;:5U6hCMUnR;Tq#: +WW*\2o^Ch]E`Q=::LBI-air&Sb/hTBrl"lYrlY8^rPn?J(!4P1CO1_8ajJf$r"E +b5]O3a3'hW%2KR`luZLbf%HEajJYgdF6Ij`QcKNeOU;g'-0Dpb1+h^aihZ>a3`A]f$VRFAh=Du +Cs1/Ebg"5NbL(#;%fRFP2UBRh_SF4_a9T`&_8F73aNFG)!6Y;^*5p1A]t05)91qQA>[VBtmIpS[ +r;?Nip%nO^qu*l$J,~> +Z2Xn&qYU6k"9&/qrVca"eE?2[h=LUF!;uiq!rVrmp\b!hs8Vims8W,u%fQU +Z2Y"+r;6Hlrr2p.rqZKgq:_F4T:ht#oDALbrVl!ks8EW/qjS]F*Z6KA#+rV:8 +*h<90r;Zferr;rprrrB!qYL*grVmi2s7*RaS"6%?URT@#o_eObs8N&uqu?ZprVc`%s*t~> +Z2Xn'qu-No(&e(1rV6$KfWAO[9i>,H[DgA7c-4?0aSs?ZaSEjMaT'B^a>(`YHjgE!&K&1.aMPX0 +a3;cPda#qM[_0]-/I3F7&dlCubIYg=\P\I+d*KtV_SO.-rl,,\_8!b$`r=*baMu6@bg"E3bR2M6 +`l5j5_8!b$`W!mQaSj-rldmZb1"hedDWekH=]Sf&Jkgug<\*mcsHqh&I_n"d`0,E +^;8%%4>gl1k2Vs8)Who(`+\YlB4~> +Yl=_&rVm'#s7uTlrr2p&pYFonkM>(nrr30$r;?Heq"O^brr<#orW2usrr3]3rVU@S,p"-Rc1h25 +s8Vinrql]mrVmc/dO6=Z+X1Y#qtg?jp7rrW/6n7]p&G!hs0)DrrVZQhq>'R2\W^u41*@ti,UOZU ++se_(r;HThX"#86+sZg\r;ZWlrqQ<^`.00]-lsBT*[DpUlMU\[rVlins8/-*+ +YlF\$(An(1rVuoor;$*8U7S!OTWd#Bqu-Nnn,N.]!WE#srtPJ2qdplj(De+5o_eRcs7lWor;QWm +ru1RV,9.=6*+f*Gr;Z]fTcb=&=H(Jrrr)fqrqQNirW)oorq6/)]Kp`r;Z`nrVucpq3)^7)^->M +p](9lrUKjfrVl]o"TA8qr;HWp&,Q%LVjX-IR@BkE_ts3*rVHNurr;urr;HW%s*t~> +Yl>O=s8Diiq>L +`PTd=`koR7`N0Ud',M-NeA],B`lW`9#STF>VT@'^b6c80`l#X-^VRn/qoAf^c2PreapH//`P]O, +^:qA$rl4cTrPmj<:rU2ca3E&\dF$(>Qul7f'a5*W&f2;t(DIBuc-+>WM@pU:&e*@AbfRW:a2ZEN +V.U>P%g<7T(`jD#^W+C6cHjYMda3.E',;5h;o?\sa3!kmrlY8^s2P&W'ZS5:b08#D\X$r0<),qV +=`'hspA+[e"oJ,jq"O`js*t~> +WW*)"r;Q]nrrpj0jlkshrr<#q%K-&$q>L?nrqlTjrVZTlrr<#gr\^f)+Bgdo`"mes8)Zn +qu$Elr+RAu+W;f[q>^Koq=e2@)^HUT+t.ZEl1b/Rr;Z]nrr4nTs8W&os8Drss7lWkqu?]nrr;ro +rqlTmrqu]or;Q`or;Q`qrr;los8Mrqs8N&ns82irr;Z)Ed,#ZP^qY^?mrUKjn +s8Mlgq>:'crr2lr%/U##qq^H+p[7Y4jR`BN"oSE#rr2ipqZ?]prilEQ~> +Z2ah&rVuosrVuos%/fajUn+$MW7U\>p\k'j!r`0!rr2`nnGXO.WZ`5r*>ou1Yl=7ns8;oqrVuiq +s8Mk+*#BG),LZAdrtG5#=WS7t)^-4HF0k!#qtg6jrVlfr#6+Z&rVHQmrr3i2s8;fps8;osrqufo +r;Zfqr;Z]os8;forVmE*rVulprr;utq#C6ks8;ofr[7aBs5V8$Me=4T+WVUG*$#e3)AsM7(D[l+ +-i!`ApZ`k<)]L*-q>^El,l``O*?Q18+!275(`4&4Vu-Jns8MoqrV6.3,90FtrVQQns8DKes8N-! +rVZ[3rVlisr;$XO$V;rVHQnq#:?nrr)lr[f:j~> +YQ"b&q"X^ar;Rf7q"F(%DduX68m%+_a2cELbg4ANaiVWEa2lBDaSX!JaDfI`%M9Eu(DKW*e]#\T +]u%@uahGI(aO*Zq(`Nu!Zc^;'_8jql&e5]i'+#+OR*=+/b/h`D`6$$=`Q69D`m2WEaiD3>_o'R: +_o9[7^r*t)bf7T@bfIrMaMuGZ,"V%1a-h()75d% +M9Hs)As:s#g1?8bK1/*(_ROIe()OX`llnJ'bM2o$kEjW&g/>7'7n3Ba3W,OaN)BM#7q;&VpE5t` +QlZLo>i#rcd'_SaN;NBa2Gs +WW2horr32nh=9gljl?@?%JTerqYpHlrr;onq>C0hrr<#gr^-9`-la?O+!W:%ZM3thrr<#qs8Vol +n/ro%+Y6:Xs8)Qks7%Q],on*S+=/6T- +Z2ak&r;Zcqr;RW5q>/+)W1TWY[.""op&G$irVZTms8W)rqu?0b%fPs$+qth/(`aqdYP%Jbrr4_N +s8Vrlm2?l`(aVZAs82]ns6V'L*>KG6)BTt<+BFKEp&+jbs8Dlqqtp0gr;Z]orr2ourr;us!WW/t +rs8N#s8Vuprr;uss8W)us8W#srsJc'r;6ElrVZ]mr:0b6s/.@n*Z#V5*?Z7<()@o1+r_gL&fDi1 +*@'D6rr;do*ZYt4)-rr48:PTUha*$-";+3YqY^$^s8W)tq>^Ko!<)lq\,Us~> +YQ"_%q"Xa]ru1e"gm;JQ8OZTpYK"f'b/VHA`5]m?aN)9@aSX!Ja?\"r5SaqK(D7;m,*:-ha2,X7 +_oTd3b0120+r_UZbL=5;b14iS',qPr'+>B^$ku0MUs.3:b0eDPa25g6e'-&8_CWaIaiMTFb0%oM +dE0MO_SjL;`Q?9Gb0.rL`Pom>`l?-DaMu6=`m2WEai29ia9p(8%M]`k%1`mZ&H3>0(D7Di(D75s +,Sq$uYJA6*dm"Zi&JS9uf?2@`dEQhD&/Q#l"pY\U-Pm[62:':]aNDcCaj/.o#a$R'-oDSF]rVllrrqZZmrVHNorO2`V~> +Y5\_*r;6Bhrr2lr&,uV,s8V`Bh^]s` +(]4.1s8DfhqXaF\rr<#kj6c:'jR)6en,<7grVl`krVlotr;HKnr;O#%J,~> +Z2Xk'rql]rrr;usrr3H)rq=a6SYMmSVTJ<,q>L,`h9br;$Bj +qu?>:,Sq%-*jP\Arr;`i\/Z;.*M@9t,T.aI(`atMD6,Tdm=*ZlOI*?l\8KoaTe*#02- +,K'HZs7hQq(E=>Do^r1`r;$^E_rr +U&Pr'oA-BZ;c$%]=+d]t_TBj@`l5s<`Q64!aT'9NaDf;Ja_qe2)%mc$((1e#bfn>RcbmWGb[qh5 +)&L>AoP/N&eboh$CAcT +bg1;F(DmZ"fZqsi`Pg'5"VV=Q$9*" +YQ"h+r;$-`qu6Km!ri#prr32kiT9Cjj5Tk6#5nK#r;?QnrVuEes8PR\dsrbg+rMaO+W_kZchIJ1 +s8W$C*?ZUS./!W=s8W)kF<2_RFo(t-_hq23-R0cY.46L&q#0scqRaDjkkOoMpAb'js82]n$2OT" +q>^?lrVc`nrVuj#qZ$Tmr;Zcq#5\8qs8N&unbt`PqBR4-,oA$a8SO +Z2ak'q>^Hm)?0[9rVuorjhRRYSYE'kmJ-YXrVZWorr)iqs6K[as&S^:H6=+F&g&)5)BaOTo`+I] +rq[ZN(E4D>o)J^hs8DJ*(EOW:p\46oL.N:,*?,tC+X)[6r:g0d\[g/Mp\+LWs8)coq>^Hmrr;um +rr;foqu?Wnrqu^"rr;ips82`orr*,ur;?Tos8VWg.0'&`)&F5(+tQ/oNNgaqq"OL]p%3bS*>fog +q>U?mf,Z"N*$)Qfr;$?l')#-N=/b>2q>]llTpqXDR&Q^fhYdBMqY^?qrVZWnWrIS~> +TDo;mkeE!Y8OuT[Dlp_P_Zn&ua2Z'=bkoK]`pq,]b0A/;C(q3m$lg-&&J8]\dFZ:cdb,*C*$?15 +e'Z.Ub0e^F&Ju-cf[S6>CGcG2%1np@eHos*t~> +YQ"h+r;$0cqu6Ek$i9eps8UI-k3hV +,paZ\+IW3-s8Musq'md2,.77Hs82ion"t=R.j#rX*GbKNq=cZk+sn[1D1\CdcKkE)p%JC[rr2p4 +rr<#qq#CBnr;?Nns8Dlqrr)lsrV6Bl"TAAts7u3a6iZj/+=&$ZU\"^9fr;OD"o_&7Ys8Vq2+L3bqu6Kms7-'hr;HTo% +fZM.rr;rRjQuO/m-WEPr;Zfrs7u`oq>UHorqlcqZN#F~> +VuHktr;?QnrttY5p\sf\WLTZQUo`VMp%\C]rr;urr;Zf`r_NRhs8W&mhNfB2(`OG;(*+K2Y5\.c +Q6.+`*ZC=@rVuors7IW\'-4CRs8VurqWstu*@2RB(`$`Xs7u@B+WV^M7VI4=YKH&(p[e%Up\t0l +(&n75qtL-jrqu]ms8W&qs8Muss8D`lrri<#qu?K^rX/\t,T%I9-(j`&p\st-s8Duos8Vb^)AO,4 +FSc%9s8,>%,8_A=q"t*jrr3bKo(DVRpAb*cAf2O()f,'Fp&G'fs8Drs#l=Puq#(-gs8VZhs8W&s +'`@k+s7ZEIXeMAWR@:"FYPS;!r;QQm!ri/srr0&"J,~> +Z2Xh&qu?ZorVlopqu6U4o'b+MC/Ii&=(Ir4\@fVo`5]g;`lQ6Db3m>U`k'(5eCVN`%209i*[DL; +'317Pe'WRW)AjG(I+?K^`lZfc()mVgPK_4qajee]KO"p"%2BTd:sRG*`X`=^%Lt0jB7uSSb1b@i +bKn5QcH=ARc-FGOe'H7\aSs9ma2Z6Ba3)TG_TU'Ga3MZG_stfDc-$Y5+;l&ObKS8[d`p%YcGmuN +c@ZZA'+e$`a2H9U2[gN3#ZT6pb.bU+b)XQfb0n;ZeCIM.(_dK\c-^Knq=s^\rV6BsrVQHfq"jrus*t~> +Z2ah&rqufqp\t^HlrVlisnc&Rg;>g:js8)>b:`p\t+C9mrr)iq!W)fls8N#&s*t~> +VuQbp*<-!>[qY^<_s7Z<#9HtGt,4bd3oc5+r)]9h;*$H^O+Wj +X8`;!qYL0hs8VuprtkS"g:(j':KLS#Ejrj&_na42ai;ECb0'.nE5oi7`lQQVc,t`!&JH$%)ANl$ +09G#u&Jc&m%b]7Q`5TaDW=fdZ'u\P=`PBR<_Um>qTfa>4)%Od6aN">o(DRGr%1j0k%Lre"9i>ha +T?kQuahZ3HccXPYc-4>SaiDQBa32KAbKn)Iahl$8ccbk":W1IQ*ZQ"-Us[N4c-4;M_TBj:bgNX3 +)As2Ccd'GHd!-02%gilscGdl;]#)e3cHsn`bgFq%%Mfcg1"=Ll^<+7=ai2W@bJMBFc-FAHbONXs +`5fs?a2Z6A[(1ci;b9AK>@hK +ZMt%+r;?Qgs8W)mrs7iGhX9Uiir&fQs8W#qrr<#grZ(b6s8Dusp](0`\n3B7+WDIH-6F?W,T\*X +JGJp;s#Tk9,p"..qYU +X8i1u!r`,trVmT0qtg9krr)]\\YGXkT;&IJo_n^ar;Z`ps8DKe*;KR4qu?]ks8;Gu@jN-9(DRf0 +)&aV<(E+NGp\+Rc3qeRU()Kd?qZ$KnqZ$ToqZ$?.(_e&9p\k-K,8q+6+!;pP(`"23*u>k>,oA/o +s8Dutp@n@Up\Y!jrr*K-s82irq#(0brr2Wks8DimnbtiSnpD>i)]>1?rVZ]qrVufnrqcT\V&U +Y5\_'q"FLXqu-?js8EK+qX`dlMe?$n:f1Yp\,O5G`llL"b43Pk_TpBJcc3W=aN9oJ)%mMi()dts +$5+'c&eeX!`6QWI`5$4#',3[acH3uH`luoTbgY"=$k=!\bK%l8%hoa$'+G`f$4%:T'+56]'a5Dp +d`9SZ`5g$Aaii#Tb0%fGb/MNG_T'a5aN20CbK%TAn]4ML`+B]$*XdJ@ai_lQa2Pj:bf%WCN#<`Z +'be[/_o^H@*"NMd$_>tobe_-8`QlrR`Qc_m?lBXh&dphOb0RQ/`6H`Yc-+#?_8=+2ccF)qa:ub? +bJqH9]<7W2;cud`7Sd +ZMt%+r;?Qhrr`8ur;QWo!;ZQm#3"D(l/U:]p](9ms8;lrs8Mros8MrrDZ0M5r;HZnr;Zcfc@@/b +-6"-Q,U"9T,U;[Ss8Vlos7fhF+!jOVl1b5Tr;QTls7lM\-mBp=qYg?=,9n:DpW^sYRr;de,Ut;b +,q:&9rquckC+:T8n+Zk^rVc`qs82iqrVuN*S"-8>r;ZNknc&Re9UdIQ+t.R1s8Domq"sjZe>S48 ++^Emq#C6kqu?]prVlfr +pAY*i!<2lq$N9JOnaQ#:lf?mlr;Qiqrr2iq"oS/kqu$Hhs8W)*s*t~> +X8`;$rVc`mrtkY3rVc`ks8DiefW(@5St`12o`"^arVlcos8N&ur;QWos8MuqDu]_2s8Drsrr)ls +o?Db0+Wh=9)]]h7*$-0cr;Zfls8Vjs*u>qcU#u%Hq>1'erVuWgQQd@i<;HLjc5mo>?h2=\TU'>! +-6FN\(a(+Dq>L9kph2$#=RGh]s8Doqs8W#srr)lg^R:OblMU\Vs7$"^r0JTC)'X%qrquZgpA4OS +dAD\-)]BS0*$t@Zr;ZTg7i< +YQ"e)qY'XXqYgBhrtPJ4q>^9Ygp(s'<_ZJ#O0l^<_8aRlb4`pSb&>YLaj%c@_S*e/e^:R1#7MI` +'b_5n',D2daO&5S_T0U53Y<)G3/bc$eBlUhaiVoMdd*BbTb/q`BaiMTO_i\nXFLoQ:_9MMk4iPWo)AsM1Z"'e:/YMeh!b1@"T%oepAFmh!W2ins8Mu%s*t~> +Z2ak'pAb-krVm!!r;?Qmrs.iCj5oCcmIg>U"TJH"q"k!i#QFYsq=sd_r;6Njrr;ors$QS]j,k]; +,U"BU+!E%]rVQWls8Mu],TmsM,9J=)P.pG_rV6^HkrVZWnpAYR#r;?Qns8Duss8;cn +r;R)ii9'RuoCV8(n+-MVri,pJ~> +WW3"tqu?Zpr;RK1qYKWlT:hdHUpnYCqtp(KqYp?gs7B56(`J>1r;3B6)BWeir;6UEorVu]nrq'eG+=#;4s8Muer]gG^as@c=*E2[thT_:2A0E$;+WMI@ +(E489Fn>Y5q>^JM*$H"A,k_07q>0jGX\p2^)&aM1*Z?7DF8bn6s8;iqr;Q]orVZ]os8Mus"9/5u +rr2p2rr;`kqt\40TqIgCT:DOehu*HOrVl`p!<2forVl`p!<0D+J,~> +Y5\Y'qtp?jnGa:!mF.2/>#7jlD2Gd;`5g-HaiM`Ob/sP#s2b2^r65/_s2\rp`Pod8cHjVZZtTpa +',29"'G;$ce]c@[bf\2G%20Br((Cm3J?7GYd`BV]d5VgM$?"/1c%HK>*FRCBcd:.gcHOA>SUYQM +>0=k&aO*g!&e,&>c-+>Mbg"5FaMZuONe6qgHdN4eBHqY^Bnr;lfor;QcqW;hA~> +U&Y/lrr3*"r;?EirsSh[ipH$kiTgFBs8;lr"9/,iqu6Trr;6Hg!W2lns8)^Xs8;`nrVZ]ir2<76 +,9e6W,lI]BqYpElqm.Ih,oRpR*@)^S.W26KqY'(q,9SP_q#C,Y-QsS+qYpKlrVc`q-M[K8s8DNg +rVlfmBI"]F,U]/_p&G'cs7QElqu?M),U4Yar;Q]onbt6?rS8YD,9S=11*n@o,q'r[,p+3h"-d1J,~> +RK"3(rqH0^e#&k3S=cdti;!?Drr<#trr<#trVlZns8N&s!W;olrb)9/qZ$Nls7Z8a7NNNg)'C't +rr;ior;QW#*uc=;*[;RH)BpMEWTa-KiuB$V-d28apR!-C(nLI$rqlWkrr<#or;?Tmnc/Ugs7g%B +(E4G@RfE$[s7ZKes8VurpL,'^+OBrbrr)Bds8>(6*??%8+&+@2,9.^I)]'J1)BKb;*[)WXrVuZm +s7bUs)BB_9_"@QfV-G2`+WhR>)BBqC,&Yd'r;$Bhr;Z`p!WE#rrVl`pr;ciprtkY-s82`gs82cd +cFTgES=5n>StsHtr;N&_J,~> +T)Sljqu-Kn(&I=TWGPj67o!B#%LP6V^ZtT%33&QiDR~> +RK!u,glPXrr+Xe9W)^64E+=&@U[Jg($rr3#rr;-Ejr;HKnr;QWo#QFVlqZ$9hrr)j(mG7$mlLOQ6ip$B) +s*t~> +T`=rhs8N`2qu-KeqWkeoSYDaIW7189s82fq!WE&trq$0drabp+rVuoprr;cko>55f/n*Z6qYpNm +s8Vk6*$#u?LfYiH+<)%;+=B`i9-"ud..I90rH9+u+JAE$qXsmbqY:*gs8Vups8)]os7p.E()\)2 +)K,BDrVufqs7Z?dqILTa+3scPrr2p\n0Snd)\jP:)AX;4&fr23*ZZ1?,Y*jis8Vfms7lTa:Db#e +)K1O3*[MUI(EO;1)BL,?Z24@nrr<#rrVucop\t6lrqm$"rr2ros8Voort5/(k.[RcTUhdJT;&pV +q>C3jQiDR~> +TDo&kqY9pcrVmT,kM=+5@7sHm:0ij]^V7=sb/hNDrlbJeaMu3p_Z@`rqT*3db/_WI`Q6EIe'Opj% +M_CBbf7WC^rXdI<=KQP@qme$#8%RW&-i\*<^@H<$5Cb0^X#mf&f?VP_T9^Fbf[rJ_oKpAcd^1Z` +Q$(s)&X>,%h)XoaihlEa3)'3aOElq&e(tgn&Rc6a3VmA(EXn<'F4pL'GLZ['abK_$OR@pDV!Fe_ +T^0;bfVgP'b_*aFup'I$Ps0`#nIFS&6G1Pe^2[hbJV9aNDNIdDErCb +eCZ`G#h[?77KX=A<+dsmdg7As*t~> +R/[0aqu7B"gYh2_i90"ps8Vlgrr;upq>:*hqu6]rr;QQnr;-Btqu?Zks8W&orVoLgoCDkXs8Vop +s8)Ze.N]lYY5%bWYAZ!?*[`'O+WqaD.!5Ccs7U(L+!Mn&Ck8RidGY$!s8Dorp\Y!hrr;h.,9J'P ++sS70i;!^3kq>:0irrrE!rV?*arVm5sf@o`] +mI9<%hY$jI!<&5`J,~> +TE"rjs8Drr(B+74q#('aaJl#1W0jHbg@bLGrVuorrVufpq>^^KnqYgFhqsa+Pqu?]n +s8Vuop*Ue$*j#25mBCIX,TA$N(E+/+'I%MmrVuM"*#KV7883OMXj5f$p](3js7ZP[Drr;fnrs&(*)]BgDqX=DJs8;oo<#?Df*#'>8+W;IL,9g-1QF,*4pA+FZqYgHms8VbK +,oR^B)C$1H(E+22*[<.RZMXIopAb!hrVQQnrr)cop](9ls82orrr2otq>UC+r:JLaJ,~> +T`5&kqYp6iqu-O7rUK7:esC2[<)uCf@["%2]Y2;*`QZTNb/hTA_tq1M_oDPoAAug7_o^'A`5g!G +f%&$fd`]kY]ZA"*b1%+9'Fg8RaLm7*(DR8e#n7R^%h9@VeB?7_7Lg%E%P("QKoE(Be&TnYaj%iL +dE0JLa\*6])&F,-&idJGbfIf>aN2]M7h$"'ZI@rmUnl +,fn*I_o^3DCD7I"(_IPp)%7)f%h/sY +U&P,lqYpcurqlTms8Drs#N=Osn*'&rn,<7hqu$6ar;6KprqlZh!VuZirW3&trr51\rr;lqqY'je +s8DuopAapcs8:%g)'C:#s8)NhqX;Ul;C*n>,9eH^c2I\>pa742+=/'g]r;Q]prr`8qs8)]o +$L?j;jmD^/l/q@/rr3)sp\FfTs*t~> +T)SunrVcZmqu$I*q#(!L[A9:fS><+%iq`WSr;HX!rquZkr;QNlqYgNqrVlg\rVliqs82Nes8W&t +qtU3frr;l;,SV4CpAb-is826,P>WYR*??+B,0Kf_qXl$N*>on>*>f_:+f\9',_Q&,I7:Gs8DusqYXnE*$EQ(rr<#hrr +U&Y/k!;c]i!rMrorVmN-o(24iL1EnJ6r.-=U:nRa_T2Yus2Y8]`PqenrPeTRB?J9:bfRoHb.ba/ +_TUBSaiD0,^q7A'bH_uq',&sE_njIBc`VIG"r@j^$kNiJda-(a$kaHl(`4&%',2&f#cuFubL+VY +b08)La[QdR(`X52(CUb8eBZF]a1oF66jsV9YKb/.`q%2@`l,g>@Mg4.*uG7l9kAgVYgU\AcI(1` +f$2Lcd)a8F_Saa0%Ls*i(CqAl%2KTp@@b +UAk;oqtp6i#5e>qpAFpbrr38ss5E5.l/1FprVlrpqu6Km!W;cmp]C9gr;-Bus7cQnrquWhqu6UW +rr)fqrVHQns8MonNZBJk1-es7lHis8W$= +r;Z]op](9mnb?rJ+Wh[H,U4[k^ZYXos82irqZ$Hkrr_fhs8Drrq>UNqr;?Ki!;ucp!;c]p$0C70 +melP3lKRs?rs&Duq#C6^rg3Y8~> +T)Tc/rVZTls82irqZ$ThqtKj.bFbK#TUi(.o)&@ars&K#qtg3frV?KirWrPus8W)rqYU6jrrrE# +rVulprVnSLqhuC:*`D_1s8Duss8;fdm]1FP-7-+qrVu`g,o7I>)]ft@*$H:D,h;YhrV6-err!0& +q-tH`*1n/h)ZCfhL\^ZDrqHHeA/u[5cMRV@nc&Rg')hWl*#9D2?h3^Xr:]sdq>^6drr<#s"T8;t +s7lTn(A.E<+rhL;*$HFNKYHUKqZ$Hms8)cmrVlujrVuiqrW)onrqQNlr>5M.qYp&sWh,ZWTp;4E +\(UZUs8Vlos7_iZJ,~> +T`>&jrql]n(]474rVuons750CNDiPE;,_.l\%ol&`p1WXb/)3FaMu08^;\7:aN;KC_S*t*`Poa@ +FUfB)5Ldln]u\FOeC;OWN`uSl#aNiccd(/U&Jl,n(`=2*(CgfZZHgnA_SO=6cd0bW8.Z:GQPCJW +(D.$kf[%sd]>qrX%1s&Sc,doDo#O>@aMc>M'H%r/9\%J;gXFEp`Qc9>bK\MZbK.oI`kTX9`P'Ys +()@Sr&J>TcD5,,)b/q]Jd)O;KaihlL\\uV1bfn5PaN2C"`W*sXa99N#_oBdraqr7:_o&d&?qrs\ +9LMcbJ?nD0rVuTks8A8`J,~> +UAkAoq"O[br;R#uq>C6dr;Zcprs8DZj66($jQQI7rrE&sr:^*ms82chqYgFSrqlTmrr)lsrU^'h +rql\%-6Fh*r;ZfrrV-'drVuZlp&4a^p&Fmes48qE+=d*BeYT$ZA1f5'r;HTos8F)>rqU1Q+skP, +@3Qa5-7;sopAb*kq.h3!-.;_jrr)Bd&bl8(_CZoV+(kHKs8Dfnr;ZZnrrN&irr3#pqu6U!r;$Bm +nlYl=&kdhoo_JOer;Q`ls7QEis8;omrr3#orr2fqrq??orqH*_qYprtr9<;-oChA>m+pe%rr`,p +q>?KWJ,~> +Sc9W-rVc`qqYUUC;rqH0drVu]lo_eOZo`+abs3iG4)'nb,d@m4L@4W\tqu-Kn+9)69"Fp+!=PXoDedhph1Ze+3sc_s7-($s7lTn^F'p?).NI>s8;]lr;Z]orrN)jrr3#pqu6U7rVHQo +mo(AQ,"@$so(W.`r;Zfns7ZKks8Duorr3,srr;utrr2ios82rsr;QZp!<)op&cV[]d]fC6St2"< +Unt]kr;?Qms8Vusrg3Y8~> +RK"Z5q"Xmhr;Zfqs7Z$)UMbK.`A_o9gA +a2l<<\B)h6ajWKb$Q"0BccF#B_o9pCaM?'?bfS&LfZVRk\/Geg'\gF1KRli_"ougEb9G!KaNr5X +c:el_&$sq^&.K$c(-pX$e&T\T7h61BZd6_4`U_)>`kKF@Sei"S$UrOjf$MUa`lPs8aiVK8bfS)H +`Q?0A_nOIIcohsQ%kqLcbg+S^aMu?;aLoR2a2>s6aN_oDaND`Lb/h[%`WaH+b08#IrkfMkb08)N +^6XR`:J=MV4AK!nPM,R'r;6Kn!WN%`s*t~> +UAkDpq"OR\rr2p"rVuosrr3&ts8Dlq#MSA*m-WfalMLS]rr2fqrqcZkr[IgFs8Dutp](3lrr<#t +qu-Nos8;iqqu4Hs9.Jp!s8)]orr<#qs8Duorr*f8qYpKjdip(^@f-*$qY^9dpA=^ds82irqYpL5 +rqU1Q,::b6q0je?*?c[UdJNt?q.Lrr-.2YYrrUEkqu?WBdd6i0q>^Bhs8Drls82irrr2rsrqu]ns8Dlmr;?Qfs8Vfnr;-F"k2PdpqX3e +ScA`h!r`,sr;RW5qYpBjqu$0CW2#lOT:_dnn+lkXr;HWorr)cm!<)`m&,lM-rVuols8Duss8W)q +rVlisr=K#*rP4Oc-JnY"qYpNos8W#rs$$;Zs8N&orVcN;*$-)+q"jm`qtp-\qYL6lqu?]ns8N#r +pL50a+jBcUH6j[K)''pGq#C0aA/lO1c27M>s7-*gs"X8o+;l+<,l%?7qZ$?jr;ZfmrVuoqrVHQo +rr;ips8;`lqT[=Lp\agdr;6Nns7u]mqZ$ToqZ$Tprr)lprVHTnrr4#)OK +kPP5Trr2rtr;HQkrg3Y8~> +RK*6_!<)lr(&n75p>N;o>Y\$o=^?HX]"Z#"aNW!/d0.e?bf\*(aCiQ7bf@iJ_9'a>b0/&Pa2c3A +a2H*Eb0cYs.LX#Ad) +`l>p=f%I:6bLG(bdDj&D_Sa(0^rQGn#KOg'`5K[;ao0B^aSs3Za9B`1c-=JPrl+oY'ZRtsQ=j#h +6r-9M>?>RVkkb>Zrr)ir!r_uoQiDR~> +UAkDrq=sd_r;?Qis8W)rrs.fIk2Pdiipm$J"oeJrpA4aas5O"_rV?-[q>L +SH&Wgqu6Zqrr)fq)Z9C&e[;9MS>DdN_!Umor;Zfpqtg9fr:p3gnG`Cbrr2osrr2oq#l4,cq#(-i +rr2oq#6+Z&rr2rtrr*`4s7Wc@*["kbrqu`ps8Dors8)cos8Durr>PBC)&aaEr;ZDq,U!m@(*]RL +rUj\C(`pius6osdr!`EH)&XD=q#C?nqu?Kis7lTlrs/Q%rVZTlrVl?er;QTnrr*u=qtp?irVZQl +s8Mokq!R1TXJ)A^TU_IAa2@<@qtpBm"TJAurr/2_J,~> +U&P,kq>Vf?qYL*fs8W)sqtg*Yl.iCg>#%I^;-SLO\%fc%c-4M[eBQ:X`l@Sj!QrXbblZ,3aSs1Y +aND`Oc,mrCair&Sai_iPccsVO`Q6->`Q63Gc-ae%$P3b5cHs_WcHaVVcHF5La3)<=_o^*HdomCp +$DGVic'/bW',M,kMpg2-:)=NUZ-g\7`UV"[`lQBR$4..J!mJs2c,IoArl+oWprNER%EcrCe'l^h +b/V?8_8F1f`VmgJa +U&P8pr;QWnr;6Qoqu6ZqrqlcprVm/PeE$)dn_3'urVllsq#B@Q#64Z!qu6WqnGY?Bs.1M[,,,&6 +s8W&qrr)Wjs8;ois8Mrrrr;gn+sJDbqYpKmgES-l,:+UWr:aeJ*[f\@rr)?crr3E#:*;&/-d;Ac +q=t!idJit>"o.ros8;fjrrhrLjQc45klTl,eF`bBrqub^s*t~> +Sc8]hqZ$Tp!rW#qr;R<*q>9]^T;/0LSsHP'oDSUdrs&Juq>1-jr:0darVlfqs8;lrrri8srr<#t +rr2lorr2rsr\s]QRNNOiSc8Kcs8DlprV6?kr;ZKjs8Duss7f;-*$`u0rr)`H*[;UC*Zo@so3`LQ ++kHVkrVuEerr3>t8K&il,Kfc\q=ssho`"dgqu6KmnG`7`*rGp9s8;`mrqufop$gtVStD[RTV8*K +VPr\Nr;6Hlrr<#s!W;n\s*t~> +UAk;nqYU*g-2[Q9qu?]qrV6*]q>'XIcZ3/e:J"G[BSW_$]Z&%=c,n,MbK%Tma9]r5cd0k\bf\$+ +``1%%b08#I^r+.6cHF;Obg"JYbfIlJb/VE?aNDZHdX;N5$@paNbg"8Nb/qZHe&]\Fahts8b0A@! +'bC_L`6-?Q[gEog(_dBWg=f@?',A.,aN)_84%/kf=gbaN`)Sb0J8Na32K;X+!i45=In4;G_%Pa6**nrql]ks8)fpPQ-.~> +SGrfmr;6Bhr;QZp!WN&rrrW3"rr2p'e)KicmI0&kq>UBur;HQmqYg:3e +BIFlD,.@ILrrDc;rXA`%q>'g^q>'g\qu6NlrsJDThs^+)mc*9\f(/hBr;6J[s*t~> +PlLd_!WE#os8W$-qraTCSXZ7LTr-*&rqZHhrrN)unG`Idrr2Eeq#1Borr2rrrXAi!J0GgKOR`/F +q>L'es!RX=s8N&qs8N&trq7f\)^+bLs8VrjqGn[V()S2kej^Pp-KkC.rr;Nf$MjT!p1#6[(`]jY +rr3#ns7$$cs8W)rrrE&trUTs\ru:q:s82Zgp#a2hSYr0RT9uCLWoisPrqlTkrql]o!r`,tPlH7~> +UAkAnp@e@]qZ$TorVmrO`r3mS +`X9Z%`Q$$A`l6$?b5TTgb08,SaN"2"2pK?P&eG\+eBQ+SahuL`5T^:cPdN1%*H]8 +cH+)U3>3)8$4T&94<#%Qb0\8Ob43Ob`Q?TU:Djl_%[Y\md`]>Cb09h,!6kA`r5]Dg`P][6aN2B@ +`Poj>dF$5^V..UKO@YU8H(se>A/H(hXUC;s8W&lqYL*fP5g%~> +S,`Eas8N#ts8Mus"TJ>rrVlfr'&W!AiToa`hY[3Ms7uB_q>1!dir/rVrr2lpnGY?>BcS<@.8Xc) +T<6Z#p%/4ZpAb$cqZ$Nlrq7HZ+"$pcq"Oggq=oF`.3Tca*[2gO/GT5Err;Nfs8NQ'rgY2T+sNBJ +p](3ks3^iGrsJc'qt^$]pA4^`q>C7#mbQ^^m-+$#mH*$krr3,trr<#sqYpZsr;?P\s*t~> +U&P2nrVlNj!<2`m&cVJ!pYDO>Tp24ESZ1#or;Q]ms6]gZrrE&ts8Drrs7uWqs8N#ss#0O^(E"/9 +94rI>X4,kqnc/@UrqcHfs8MusoGS\d+o;66p](9hp3I]')]C%>)B'D=p&4pis7-*grt"l%QQ-bY +)j9jes8Dutrr)Eequ?Zps8N3#rVZTmrUp-ks8N#lruV%:s8D`R`2TB'Tph[@USas7nbrLcrr;up +r;QZorfR52~> +UAkDop@S.VrU^%0rVH#Ra`<)-_QQ*[s3_8jgGc-#Y!!6Y;b!m8U(p;R$Nrl##Y +`Q#p=rlY5a"3AL'aSs1;`CC.H(`55';0R\p[EQhIdEU+^`PTg:_oBk,((^u*d`02Ib/;J7%M]?V +((D'#(`:iKb/h`qa:ZeCa45eV)]TH;dE9eU`Q--Gr65)]r5]&]_nj1,`r='Z`WjT3e^`!jc2>fa +b5TK^`[\sI`lQ6Db/_ZH`4j(,^9sS\?;sm#85DWU@s"[(nbDqXs8W)ss8DilrK@22~> +RfE3_s82lrqu6Zlqu76#hWO7emH +U&Y,jo)J[fs8N?#rr)Zeq=Vo0U^WW_SYWI?jSo2Zqu?Q]rq-6jrr;uurqHHmrr2rtrr +UAkGrqY9p`qu,m](&d^efpu\[>YnEu6b05e_'-.i[eCMdYahc.!bl#W[a:QM8_nj1,aNVlNaMuBIe^`"Ebl#W]a +T'6]`Q#pra;r7;^q[XsYEsWC:fUFd8m#)$F/\!bq"jsdqtg3gr;QcqP5g%~> +PlCmcr;?QnqYpQpqYq&nhr*Y^m,Hg[r;?Tos8V'Wrr;uss8VWgs84aAH"/s82fnqtp'E9-YE++<_jQqY^BlrUKjts8DrodNfq[,ZOO:qu?Wndf04F +!;uin!;u`o$Lcm/jQ>UimHNQcrVm9(s8Dlns7lNlrql]nquH_\s*t~> +UAt2kr;Z]or;Z`p)?9^8qu-Kkp&4gZ^S[ZoSY2RM[GC!Dp&G'\rql`nrr2rtrW)utrq$0hr]'rV +r0DJ3,UsfX)&=>7(_n)--6"$Wch.8;rr;O:*#9dms7lWls8DlloA)nX(*aV4(a&MMs8DodrXJo+ +s81+a)&s_qpAOmgmJd(a"9/8trr2p!rr)fcrW<&trqcX0rVH'DbH[b7TV/$TTq%t0mJ6VSrr2os +"o%oos82fns8N"as*t~> +TDo)nqtg0drU'UurU][Db):1J>?+Qo:LK0Q]XlA3n&YOKrl"lWr5_dU`Q$3Kc-",KaiVQA`P][6 +`l?!8_oBjCb/V9;D-0FH(((op&/Gle#7q(Q"Tet,`6ZHBbK1P9%MRCAaNhZ?_8FF<]IXBq*>fe3 +$e38ef](uao]YT%qu$Hni;W`Smf#'?s8Mfjp@mFn +WL\'G.k2hk.4-&_hu3TSqu?=<+!E!,q>^ +U&P,lqYp]trVc`prr<#tr;RZ6rVHQms8Vlop\X0gV4sERT9u@Nbh_sfrUBgbs8N#srV6?ls7cNl +rrE&trAFTPs8McfoCgteV3u47-RKrY,U"!Lh#%-Nqu?74(E+Ikq#C3hs7cQmrr;V$+VYk4*?b+U +rr;Nf&,Q2's7ddLEgjcCq>^Kjs8N#ks8W'!rVlcqrquirr;ZZn"98B#rr2rnrZ2%X2=0!q#(0hq>^Elrr2urq>^HnQiDR~> +Sc8ljqY9parVZZqrV6Emq\Ar(rUp$OjN)[6-@9d_8XLAdEThLa3)TUd)r]#ML88o$k3OP&IedG]@>6Pa3MpE'G:o'aOA)Gbe_TCaO\g5 +&Iod"(CJO3a32Zra:H;0a3;[,:L&1/cbIKF_or&#p;RZbb0A/M_o9X?ccsVM^V7J%qoAlZaMu=# +`r4!Y`rF-[arAFA^q6nAH=9oR;bKbX92TVjb3&0fqtBRTpA+I_s8DupQN)I~> +UAk8nr;QQor;QNls8N#t%K?;&r;HZqqu?Kep\4[crsJGWkjA!9ki:Xorqucrrr)cprr)llrW)ln +rW)utqucotrr)co!;uTj"985ps8Musq^qaCq"a^Vm*W/0L1gP_rVufqq'-n--2@N=rr;lqqu$Ki +qYuO$+W_mTp\t0lnG`Fe%/9f"pA4^eq#CBgs8Dior;?Ejq>C9lq>^Emrqu]np\tWij5B%cm-X-( +k2u=6rs\i$rr2forqZQmr;HNlrfR52~> +RK!EhrVc`prr<#tr;Zfr"985trr)j2rr)TLa.f2pS=l:CX30>rr;HTnrr)lqrr;rrrr2rrrr2lq +rql]rrr)co!rr9!rr2utrr!-%s82`or;?QkrqcZh.JE;rcEEUeAGu<$s8;ok*Z$"DpAY$is8;oo +rVuZfreMX7(EOamrr<#frr2p,q#C6_p\Y!ds8VinrVlHhs8N&srVulrr;ZZns8W,urr;uss8W)t +s8=/>qY9d>^oa9#T:MI@S=QOmiqiTLs8W)us8N&uqZ$TorVQQn!ri6!Q2c@~> +Sc8]grqZZmrVccrrVucqrVQTtqt9g\rr2p3qXNISQ=jAr9i4M\@=k#\^VRn/aSj9[aSs?^aSs0\ +aNDa*c2Yugb/aM##0+^+aiqoMrl@CJaMYp8b0SJ]b/h?8cHOMO`QZ`TbKeGWaKLbTAOY>#d*KeY +cj0pg#1(TaSj-X`V[X[aNDcP +aMu6@rlkVh_nWq#_u.LR`qd^S`ZW@B`l5d.\!qbV<`)^h;,U:oAr!kOmIL5UqYU'Zq"t!grrW/p +rVc`urVQKjQiDR~> +U&Y&io)J^gr;ZfrrquZn$LH[.kj.F"o&99@rr3/tqXsX[r;HWtrr;uqrr!3%rquZkr;Q]qs8;im +q>:dX!<)oo%K-2(rqu`i.junur;HWorr`9!qu?Wm$+290+>*Bfs82iTrr2rtrW)loqu6Nn +rr;orqu?Klp]C9gr;$?mrVlftqtg +R/d0bmJeL2s82Tgpt`TYT:hjHU8FU(i;3?Mq>U?mrr;uts8Dfor;6Ekrql`qrr;rcs82fqs7QBj +r;ccpq@3?#rr2iopF.F<.Js&Brr<#t&,cJ*qtg,o-QsK\p\t3is6oses8W)urVulss8)`gs8Drl +ruV1UWVS_BgJcGZJJ,~> +SH&Qdnc/Rdr;S8Do'PGINbVct9h.lT:3r;9]u7h3b0.uNbKS5Ub0J,J`5T[6a2Z-?b0'_-!6G)X +s2b)Ws2G#Xs2YVkbf\#H`lQ6Db/hZHr652c!RK'jbl>j/bf\#MaT;GE!mf*7bK7lI`P]j@c-t7- +$3gJ6bKS2Nam[=N`WsT/c-=JR`l@krpr<Uc-+5K +`P]g=`kf +JcGcLqYpomgu7VbmdfDlkP+rT!W;oqquH`mrrW,pqYpEmrr],jkK%ursAVtq>:*hs8W)tLAuc~> +JcG`Ls8^Blp\tHsrVZQiq>UBn#QF]"rVuosr;Q^1 +rVQNdjNOs'St)=DT:MOHTXrqOrdk+Hs*t~> +JcG`L/H5P?mG>jKC0FY.5Y4dSEfdTBbKS,Pb/hWEbg+GUbKS)J_o'I4`l?*@b0'P$q8VX>s2Y/Z +,0.dHd)=>Ub.ts$c-4DSbK7cDaihcNc-O_?G]n2RbK%cKh8oE3rlG#[q8iTY.*TiM_oBa=b0.rN +c-=AM`lQ6?_ns!\LhTa`8kVrV:JY)'L9fCoo_nagrr%NMJ,~> +Jc>`Mrr)rrqu$I$f[A^>k3;-oi9gL@s8W$*r;Q`prVZQhqYU9kr;Zfro`*kKs8N +JcG]K(&[n)qtg*AWLKWWTUqjPU:Jb?pAFpgrrN-!rqlcqrVuoss8Duss8N)ur;HTlrr(dSs8N +K)ZtlqY9sdr;?Tnp?]SE@TcDr92APfDMtU*_8jdFbK@oJrl4rX$HgT6aMu6=`P][9p<*BY!6X?C +s2bJ_`lZHNc--(0!m8^-rl,Gl_TC9Qf%.sgaiqlIaN)cN!QrLZ`rF-[b5KO1bKS8Wc-+8O`5Ta8 +a2lEDbIaO$@T#ol:.RoL;HdXQ[F+(&p&"^frr%KLJ,~> +Jc>uQq>1!cqYC-grsJJRg$.V]lg*Ejo(r@krr<#trVc`prVuosrquU?gqu$Hms8Dcn%->mkkNM:)nF#W(ip?RB +rqlcqJcG`LJ,~> +Jc>cNrr)lsr"o2(p\F7%XeDPWR@g:IZH2\2p\Y!jrr)irs8Dus"98>urqucsrVZWmqu$Km!W;oX +rW)utrX&W%qu-Hms8)Zlrr2os#l4N!qu6Khp\t0l"9&8trS@JQs8;lorVlfqrVl]qrVl]o!rVon +rr)ruqu6L1rVlflm_bluVOj +K)YuPq"OU_r;S/An`7f[C0+P4:/OteAq%"n]Yhb0`PfsA`lH-Bb0.rMaMu6=_o9^pb59E^blQ&2 +k/[PErl>Mo`Q-*Ccd^+]bKS,Mrl,Jabf@]Fai_ZLda$%VbJV9Ia90T+`l7nrr5eiZ--Xc`cHab[ +b/_B6^qRY'`4`=$>Zars7nQBK +K)YuQqt^!]rqQQlqYpokg$/%ikihHtj73$Hs8;rsr;Qitqt^3c!;ucps8;ln!W;rps5X(arV?Kn +qZ$Bgs7cKprVulprr30"q#C9js5 +JcGQG+TD?;qtg3Vbb:l2R[KV?UT25lq>L0fs8N#rr;HWnrVlZn"TA8rrr2iqs8E0"r;6Ejj8K>_ +q>^Kks7uQlr;QWo"9/?"r;Q^#r:pm4 +s8;Q`qXW=UW1Tc[U7@dGTqA=$iq`HJq>:0js8W)urVl`pr;chOs*t~> +JcGKE(&dgkjNXKtQ]=l2__un!!b/sG$qoJf[rQP8c!R/^Ha9]i(aj%iPa2uU* +bS84@`l?!;`l6'@`m2rTaMQ0>`Q-!WaT'9WaSEsZaN"2"rlY8^s2P)X,0%dKbg+MXbKJAW_7mXe +P'0r&:fC+Y77^9[E0\2pjR)R9qYpZpqYL/Cs*t~> +K)Z2Wqt^'_p\Oa^rVHBj$iB,Fm-3j%khk.VoCi1crqlNjp]:3grVlotqu-UBop\=^hs8)Zlrs8H#r;ZfqpAb'Mrr;luqu$BkpAb*jqu?]q!;uin!Vu]nrqcX(oAe`h +me-)5iT94Xm.UAWs8E&rp\ssgqtg +JcG`Ls8Dut%K?D(rr2]lrV#^&YG.onSI2$]Upnb6p&4acrr2crrVulns8MusrqcWsrqu]ml2C\] +rVlfp!rN#nrr2umr;QWo!W2iors8K$rVuosp](3Orqufrrr;rqr;HTmrqlWorqudIrr<#trVlis +pA=UFaK_V7S=H1>R@pIS]$BO9r;-0_s8W)us8Mrqrqu`nre(6$~> +JcG]K*W?!:qYp?krV$$]k0KZIB44Y18kVcUC5JXh^;%Sb_un$$b/jG%rPnfWrQ>,`!6XQI!6>&Z +rl5\kcGRcLdDa>Rb0%fF`l5p>_SjRq`sBN*`5g$>^C2gShsL(/qYC-oqtg*arIb-#~> +Jc>fIrVl]o!<2cn%/&W5jlu$un*/]cmf*.as82oprr)iurqu]mrr;oqqu?Qorr)lXrr2j"s82ip +r;$?lqYh$'s8W#lr;Zfpqu?ZpqZ$HPrr;luqu$Bkq#CBns8W,us8;cks82lrrVuoqrVmB'lf.!l +mHsW8n+5\pjRi?L#Q4JsqYC$drqcWsqt^'eL];l~> +Jc>cIrqcZprW)usrYYP2pX?RFTq@dFUSFN^^Y.c>qu6NjrVliqrpp*hrW)oWrr2j"s8;orr;$?l +rr2lr$2so(rV?Els8DlprrW)tqr7VQs8W)urVuforV?Heru(e8rqlTlqXN^r\"oXhSXH"2R&$IO +]\3&Vrr<#ts8N-!rVccprdk*"~> +Jc>`Jr;Qs!qY9d[qu-O3mGlj$LM:-s92&,V;-eC2XLlBi`59I3`r='Y`r*gK`oP5>`u`.?`Q#g? +bKJ&NaMu6=`Pfm?`4s40a2Gj9`Q#d<`Sno<`r4!Qb5]Q_b5]]bblc24aMn.r*6-.C_o'='Xdt/] +=&N$t:f'SR=^,BlY1;LtoD8Cb!<2ut!WDlop]:6iKE$H~> +JcGWIs8E6$s8W#srV?HlrVm8ohra4imHWcliR[8brrr>tqu$HmqZ#^W!<;op$30r&rVulsr;Zfp +rrS(rs\l(qY^6dq>C9mr;-Eirri8qq"XiDs*t~> +K)biLrquiprr)ls"TAAuq>UBn'DhL\^n[ToS=Z=CTVnX%i:QmCr;Q]orVulos8)`os69L_s8)^& +s8Duss8N&rs8W)tr;R9*r;Q`rqZ$Tprr)irqZ#ORrr;usqu$Nor;Qcrp&>I"r;?Eer:o3jWMcJ_ +rga"Xs.9Rk\)@,Zs8W)trr30#rr<#tr.4nFs*t~> +JcGcK!<2ut"oJ)fpA"C\rttY'n)rN=P\jf.:JXe_<*j'dU:%YI^r+(c`W*p[`Q#m:pr2L=!6P)Y +(rsS7`Q?3EaNMcJaMu6=a2uBA`QQ<;`lA"r"3&O'al1>@`r4!RaplG3`lQVbf\#HrP]\q +_nNdiQZlG.9hJ&R;,^V(@:t;&gZJ,'q>L9l%/p)%qt^*cqY9j^qu)0IJ,~> +JcGTH"9/5rrqucur;6BhrVmArm,mHrmd90%i8`_cs82cp!<)lr"8V]bqYL3qrr)ipqu!)cqu?]p +s83K)q"FU_r;$0gs8;iqrVZ]pqu$I(o]kArl/q6slg!j!gZ/&)rri5oq"ap^rrrE"qt^-gL];l~> +K)Z&Sr;6EirVlZn!ri,sr;S/Cp[Q/.Un"$LSslOKVPh;chYR0Ks8;ioq>L?nrr)lrq>(!eqt^0g +s5O%Vs7uZms8Drms5!\Ss8W)prVc`rrr2rtr;Zd@r;HZor;Zfps8DNJgVg@kTqS'LTq7gHTqf*E +l1OoNr;HWls8W(Ls7lVE~> +K)YrOqY9scrri;sq"jmes"F?Jqtg*Wj40ZPC0Oe?;bU1e`Pfs?`l6'@ +`50@3a2R#YrPnZSrPniZ!m&C$rPefV!6G/^iQ2&=s2b,\s2ch7aiMN?_o0O3`QQNKbKe5Nb/V?> +`jhh1G[O<@9hJ&R9M8&[BS`b5i9^(3qu6iuqY9j^qYL'hrIY'"~> +JcGWI"TJ>rr;QWo!<2um!VuZkrs\DVhraCilL=!!j5'2"rri5qqt^6err`2oq#$ibqu6]rqu6Nq +qt^*fr!*-"s8Dlqr;$?sp#G#ik3Va>m0)Y4hWF%rrr`2rqu$ +K)YiMrqccprVlZn!ri/tqu7Q4q>0U4\tbacUR@^NT;/?a`:ETtqu6Wjrr2p%r;6Bfrq?6cs5O%V +s7uZns82fms4mSRs8N#sr;uuqrVHNprVl`p,5_<9rVcQcpYEusVOa6IURe'RUnXT_[cQuRrr)cm +qY^ +K)YrOqtp?hrrE#squ?Trs8Drqs!dg7lIE2!D-U4G7n?KO<*Wg\YHk^P`lc6?aNV`E`lH-C`5]sB +a2Z*;iQ1u;q8iQT#ft04b0%fF`l7qs"j"j/bf\)faT'9[aSj6la2uNHaMu9A`P][:bfRrLrl#eo +_nNdqT8%)a8ju*>85<5h>$PZd][>g/q#1'h#Q=AgpA"L]rV6EmrJ(?&~> +JcGZJ!<2rps8Moq!WN&srW3&urVm?+khkLil/q6kjmM6rq#:9prVu`lrsJ]$s8;Zequ$?fr1a2h +s8Dp%s8Mrnr;6?frr3-"qY'XYqu72ujQPdjlL=91l0INggZA"krrE&tr;ZbIs*t~> +K)YuQrVZTloD\gir;RW1rVZQ\e@;L?nrqu]rrr)ips8;lmrr`9! +rr.ZPJ,~> +JcGBB#6"GrrVc`prVn8@p?gnbWeY7i;GB\T84crcBS;h^^V@n.b0.oNbK.`Lb/VKEbK@rcaSX!O +a90T/b0'_)!64uYs2kDeb0&_bs2P)[rQ5PnbfIcC`Pf[gSo(;YPrqud"rVH +JcGcLs8Vckqu6fur;6 +JcG`KqYpQpqu?]q!r`,trr3r:qYgBjn`@X"V4sfYSXGt=U8PTIhtm0HqY0sfrrE&srrW/us5EtS +s1eR4s8W)ts!%:UEorr2llrr<#qrr2rsrWE,s +r;DBMJ,~> +JcGZJ!<)co#6"DprVuioqu7u@i2HZe+F/q"t!c +qY^?krrrAuqYL*fo`#$lqYL/Gs*t~> +K)Z#Rq>'pcrql]urquZhqtg +JcGWI"oeJur;HWms8W$#r;HTnrqQL*p=I@s8W&np\XpbrVZE`p?LAFX.lDbUS=9MStDIGWOfk$me6JTrV?Hks8N#t!<2ors8E-!s8N&t +rr2rrrW<#rreCH'~> +JcGBB!r_ohrr3-"qtp?krVm<)q"4%?gpiu3DIQUCr_*u(='0*gTAK%\^=_Q9o_7tRqu-KnrVcTg +qu,s_"9&,orJ1E'~> +K)Z#Rq>'pcrql`qrr2cprqcWsrVZQirqQTlpAP"%q!Hu'jQ>Uflg!WkgtC][p&Ccc!rr9!r;?Ys~> +JcGWIs8<#srVcZo#6+T"rr)iqqu7''s8Vurqt]L#\"KSsSeI`kTV&!SUpJD.n+Q_Zs8N#trqtaS +rVuQirr;`lrr:jSqYq];r;Q`opAagGfZL\"S=l=@T:D@?TV.pNWP6sMp\+Oarr30"s8)TirV6Bo +rr)ips8Drqs8N"Os*t~> +JcGBB!r`#nrr<#s"8i&qrql^5\bhqdYq>L?mr;Zfq +rr)iurquWlqu?Wlrs/Gtq"FFVqYPjD!<7Q~> +JcGWIrVlZn#6+PtqYL-hp&>$kqu79-i8Ek`mHNcun*B3'jl,.[q=ajgrqu]WrW)lprr<#Wrqu]g +rq-4(mGQUKjlksnm-X93lL*ruhqI/\q>Up%rVZThqYC$ar;?QnrVlfnrr`8ur;QQm#6+Ptqt^-g +L];l~> +JcGBB!ri/sq#CBns8;lp.K'&?rr2rtrquHYc_mG2StV^CSYD[FUS4Na\'ja@pA4X_r;?Nmrr;uq +s8W&us6fjds8Muts82fms82fns760es7HSY)=BTV%jIX2ON$ +q#('hqu?Qmqu6Zqp&>$kJcGBBJ,~> +K)Z;YqYL*fs8W&rqtg0drV$6pqtg*`r;Q]q-iX/Gr;--Tkh!tNE+3-R$YZ[O06"# +^;%M#_o9U7`qd[U`pUnJ`q[UZ`l5j7`Q#prb5]Nc`l5j5`o"i^`l5d/^::_ZTo+)4@9HH%8kDNE +9h8/`>%(r`Qe:Nio_87\r;Qisrr)`o!<2inrVlrtqtU-`!r2ZkJcC6~> +JcG3=r;Q?gs8Mio(&%%Mio9%^kj%Etlg*cpjm2=-s8W)srs/K#rqcEcr;?Ek!ri/tr;HWms8N&u +s8E0!qu$Bkr;ZfrrqlltrVlfqrrrE%rVZQirr2oqs8EW/rr2inqtg3dqY^?kr;ZfrrqHF,qXES+ +k2kXblgF-,nF,]/l/(.Uq"4U]rq-6jrqQNkreCH'~> +JcFj3s8Mcm$NC#%r;,g6a/,N(rh'4]&>#MfTUqmWZ,G/Mh=pX@s82Zms8E6&rr2rsrVlTl"9/?# +rqcZmrqud#rr)cmrVc`os8W)ts8N#tr;cimrsAZ(s8Dlqs8Dorrqmi7p[7(rf>=kjU84QXTV%mK +SXuIET;/*V\C9g=qYgBl!WW.Ms5!^*~> +JcG`Jr;Z`op&G!hp]!&JqtTaKki:+'TPn@L>$"Tr8OuEH:/FnqBRPu5R^]fA_SX@:aiDKC`l?!< +`l?'=`PojpaTfi/aN2BA`V[[T`W*jS`W*sXb5TQibf\#G`lH*<`W!mS`W*pfaN;THb/q`Gb/_NB +aMl-t`tHJ5]s"&mMfiN0;H?dt;c-:_8H)3k;-dXNO1*[)nFl_Tqu-KTs8W&rqu?VGrrE(L~> +JcF^/q>LEprqZR!pugMjiofUorU:*]m,d +JcFC&$i^)(rr2lmpuKW+Vu<>#TqJ'MSt2FFVP^?0cIh7Srq[-&s8MoqrV? +JcF^/s8Dfo1&UkDq"F@FftF)4De!!O:eaSU8k_lQ;d!@4HAIl]\@fMg_8F.+a2Pm2`Q6*!rl5&Y`;[UZ`lH*=a2c`Q$!=a2Q* +JcFR+s8MTh(&[:Oh;@/PlL+**l0@?mm-EcunFZPCs8W)trr`9!qYgEkrVlrur;6Hg!W2lprri;u +r;-EirrMrmr;Qcro`#d'lJq$kkN1jilKdZumI0H,lL!]oiSWeeJcEsoJ,~> +JcF@%s8FSJs8N#qrVZQ^g:s\bTU_OETUq[IUR[jIT:;[Z[DL>MmI^,Fq>L +JcF^/s8Dfo0`CnEp\+=QoCMG7e[L`eC0ah8:/4AP9i4MU;H$CqAoN6\Trtl:]YVS+_Sa@6`Pqeq +$-103c-4>Qa2c3ub6,l,a2\%rs2G&[rlkDa4ibO\`lQBIbfS)P`5Kg@c-"2Ka2c3<_SX$qZa-j: +S;DK'=B&0p:Jk"g:/+JZ8k)6E=(H,lOfm!nmIU&Mp]:*eJcF@%J,~> +JcFR+s8N&u!<)co!rVrpqYqN*jPSnSj5K4gmIK`9p@7\AlK%$klg=3 +JcFF'5lL`_rr2lorVuoss8Dlhn`JB9XeheeTq%aIS=Q%6S=6"BTqeTn]?8X[io9%fq=j^^r;6Be +p\F[_r;HWps8;lps8E&trqZTor +JcF^/s8Dip48o3Xqtg'\q#C?kqXa(3eAA8HF_5)g=&2Xg92.uL:/+\j>[M,aH]"#XUS=Wi]Y(to +_ns7)_8aO8a8X-\b/sY+s3(MdaSX!WaSs<]`ra5u`W!t8aN)6;_og$:^V%:r^V.1_Un4'AN-T8L +=]/*s:ImlB7Rp*G:f^Y">?b9;B8WIrdH'cjr;QotqY'UZJcF@%J,~> +JcFC&!<2lqs8;rsp\u9-k2G=amH!^$na>i7nEoE"kNUs]gtpuMlL+B@rQY?Sr:p'Wk2PL_hWNq[ +kiqF!l0836$1@ +JcFC&"9/8urql`prr;mMqtg$Ujjh;XVPL,YU7@jFS"6.BR[ThCU8"E\X0B1PbL,&(mIU/Mp@\+P +p%@tMr;HWorrW/urr2rtrr;p\r;HTns8Mrlp\+CYq=sINp@n+>g![gS\?2[-VOs`YTV8'SURn*N +TUq^HT:MUJVR""dkOn]Lr;HTlqYg>Cs3L^q~> +JcF^/s8Dfos8GIbqtg0ap\4LZqY9dUn*K)eag@[sC0tCH=&Dmj9i4ee;H$_&UQ]tCqf\[oGfaihuVd*^7ec2,W_c2YucaT0:'h"8r&nrIP"#s*t~> +JcF7"!ri5tr;Qcrp&?6/fA5-?gu78Skj@d(lLF6,lf[g,oC)#- +jl,(Ng"Y?ElfmTrlg*d$kiqF!m-Nm6j9=N#iS`Pjq#:BorVQU!r;-9eq=sr?s4@:$~> +JcF@%s8<'!rVQKjrr`5tqYU3g1B%+Gk0h)?VP0oYTUq^GTq@mFTq@mJT:DOLT;&*XWN<8+]YDG/ +db*C6o(;SJp%J(Or:U-brq6Edo_&1T1[O5[f@%pb_n!4\WhlMdU7n6OS=Q=GSY)CASt)@BR\6IP +TqA$QTuYaLq"agarVccpr;6HmquH_Is3q!u~> +JcF^/s8Dcns8E)tq=ss_55P0Us8N&urVQ<[n*8cDUQ95/A8#.O=&i7$`N.l_'E+r`b=BJNt9hS&M9he5U +92&)T:f'ng?!UW<@:sACY0,YcmI^2Kqt^*er;Qfsqu6Nor.4n!s*t~> +JcFF'!WE#irrW2urq?@9rq>U +JcFX-rVlis!WE#ps8W&tquH]prW)onrs\i%r:]mNi6K +JcF^/s8DZkrr)ln!<2fo0)PG8naGi/khb.=\YGC@D.-UJ;bfhM7nQBC852lV;,C.g<**+%$+m+;Gg=j;c6UprDW_q!)EMhs%sY3;,gS!>?=s4@r?m^ +U9r,!k3MR/o^_PEqY^@#rVH?`qYL*dqYL,@s474#~> +JcF=$!ri/tqYpTqr;QTnquQcqqu6Zqq>UZmmdKo;j5g1&!p8b4rp0dTlg!d$rp9[N&*iEElKdg* +n*]Q/lg*p(mf)Z!md'0$l0e$/mdBH-lfm^"lg*j$l0.9kkN:gaj5/e^nF?AMrri?!qtg3hrri>t +q>1$_rrE%Ls474#~> +JcFX-rVl`p%0$5)s8Muqr;Q]qs8Mio)ZK[7s8Muss8Mc\jk%Sd[C3$(SYDjOSt)@CrL`tY!2'7^ +#+qQ]T:_dLrgs.^qORe[StDYPT)YE,S=Q:FT:VUESt;RJTqJ*STV\m%\\cbJlLarMqY^?ls8W)s +rrE&trr`6!rql]n!rDioJcF4!J,~> +JcF^/s8D]l#6"Q$s8Doqq#<5Jq=sa^q>:$^naGc&e&A\fN.#hjAQi;D>Zb!';,C%a9heAZ:ej\W +7n,s=84cBC779O68cDB_8H;9Z74Uo$91hW?77Tj>91qlM:/=_`:JXni='Jp7@:a"dH@gm6U9D\k +j65h"q#(-k"TJAsqY^6j$2j\sqY0d^qu-JEs474#~> +JcF4!!<2or#6+Puqu$BklMh=in`o9"lJUX^lg=$)nG_hUn,Dh`n*]W0n*]T6n*^,?,4=pfnaYr5 +kiV*so'u5?n*TT2n+#o7m-j?%h;dhglg=EFoDejip&+dfJcF'rJ,~> +JcFX-qu6$`s8N#rpAPs0rVlfpnE8QO`4WUhV4jNTT:DCAS=H.@SGo)ZSd1g[St)LGStGnOs.(=+ +S"cIGTU_UES=Q4@St)CFT:DC@TqA$W[(*W^bhD.Jq>U6or;HTnrp'O]rdk+#s*t~> +JcF^/s8DQhs82ipp](9ls82ip+TME=qtTgRm-!BdhUK`_Y+Ll7Jo,"&>#e?l:Jak_91f+Qs%*Gd +9LhH@77TlH8MEY'6:41.9M/#Q7Rfm;8kVcN9i"V_9h\;_?=e)'KSbqh[`-hVk3D:$o_/(TqYU5B +s1SG_~> +JcF4!!<2rss8N&r!rMonn,ELgqtp?brs8A`iS`_UjQ5V)l2U#Kk5OZKn)s-,rTkEin+,u +JcFX-qu6Ek!<2`ms8E9%r;HWps8N#srVlfnrt>>/qYBp]pZUMab.FaMTVA-QT`1S`TE_*\T:VUF +Qhm9XSXuIHS"lVTTH0c"T;&$OU8"?RStW3r`RNW'o(VkQqt9d`rr;usjT#8Z!r`,tJcF@%J,~> +JcF^/s8DNgq#0[]-2dW8q=s[TmHNZefYb+nQA'Bn@qB1Z?!:9.;cQdn;,0bX6:jcI9*n0[7Rfm; +:et(krDXY<>?kTG@q&kYE. +JcF:#rr2lrs8N#q"8i#orr)j!qt^-eq#:EprVc'^s8E?$r:p-crVZ0OmeuMPmeuMXq"OX\q>:*g +l2Ue^!rW&srr;ioq>^ +JcFL)rVl]os8;rspAY-lr;Zfrs8;rqrr!!!rVlfprr*o9r;6?hqtg6ep\4LSn*/leeBc=X`4W^l +\$Vs&qORYU*M9"/ZaREV^r4=BfA#9Kme-AOqYU3equ-NnrVQQls8W)js8MutrVc`jrrE&tr;chJ +s4@:$~> +JcEpn!<)oorr)9b9)SP^q"F=Lmd9?(kiLg^iRcJu]s4E'P)P0EG]I_9<_Q1^:/F\Z91MKG:h4Bb +H[^X+P+JVV]>r:Qi8j%bm- +%%EndData +showpage +%%Trailer +end +%%EOF diff --git a/doc/gnupg-badge-openpgp.jpg b/doc/gnupg-badge-openpgp.jpg new file mode 100644 index 000000000..d396b7c38 Binary files /dev/null and b/doc/gnupg-badge-openpgp.jpg differ diff --git a/doc/gnupg.texi b/doc/gnupg.texi index 478bb4395..d74a76ca9 100644 --- a/doc/gnupg.texi +++ b/doc/gnupg.texi @@ -82,8 +82,16 @@ Boston, MA 02111-1307 USA @title Using the GNU Privacy Guard @subtitle Version @value{VERSION} @subtitle @value{UPDATED} + +@sp 6 + +@image{gnupg-badge-openpgp,8cm,,The GnuPG Logo} + +@sp 6 + @author Werner Koch @code{(wk@@gnupg.org)} + @page @vskip 0pt plus 1filll @copyrightnotice{} @@ -111,6 +119,7 @@ the administration and the architecture. Developer information * Assuan:: Description of the Assuan protocol. +* System Notes:: Notes pertaining to certain OSes. Miscellaneous @@ -133,6 +142,7 @@ Indices @include scdaemon.texi @include assuan.texi +@include sysnotes.texi @include tools.texi @include debugging.texi diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 28d99673d..9d2cdfc46 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -135,7 +135,7 @@ below the home directory of the user. Set the name of the home directory to @var{dir}. If his option is not used, the home directory defaults to @file{~/.gnupg}. It is only recognized when given on the command line. It also overrides any home -directory stated through the environment variable @var{GNUPGHOME} or +directory stated through the environment variable @env{GNUPGHOME} or (on W32 systems) by means on the Registry entry @var{HKCU\Software\GNU\GnuPG:HomeDir}. diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 4c167ebf5..1e7368041 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -241,7 +241,7 @@ below the home directory of the user. Set the name of the home directory to @var{dir}. If his option is not used, the home directory defaults to @file{~/.gnupg}. It is only recognized when given on the command line. It also overrides any home -directory stated through the environment variable @var{GNUPGHOME} or +directory stated through the environment variable @env{GNUPGHOME} or (on W32 systems) by means on the Registry entry @var{HKCU\Software\GNU\GnuPG:HomeDir}. diff --git a/doc/scdaemon.texi b/doc/scdaemon.texi index 5265ed21e..cb165da35 100644 --- a/doc/scdaemon.texi +++ b/doc/scdaemon.texi @@ -86,7 +86,7 @@ below the home directory of the user. Set the name of the home directory to @var{dir}. If his option is not used, the home directory defaults to @file{~/.gnupg}. It is only recognized when given on the command line. It also overrides any home -directory stated through the environment variable @var{GNUPGHOME} or +directory stated through the environment variable @env{GNUPGHOME} or (on W32 systems) by means on the Registry entry @var{HKCU\Software\GNU\GnuPG:HomeDir}. diff --git a/doc/sysnotes.texi b/doc/sysnotes.texi new file mode 100644 index 000000000..6ca10c195 --- /dev/null +++ b/doc/sysnotes.texi @@ -0,0 +1,107 @@ +@c Copyright (C) 2004 Free Software Foundation, Inc. +@c This is part of the GnuPG manual. +@c For copying conditions, see the file gnupg.texi. + +@node System Notes +@chapter Notes pertaining to certain OSes. + +GnuPG has been developed on GNU/Linux systems and is know to work on +almost all Free OSes. All modern POSIX systems should be supproted +right now, however there are probably a lot of smaller glitches we need +to fix first. The major problem areas are: + +@itemize +@item +For logging to sockets and other internal operations the +@code{fopencookie} function (@code{funopen} under *BSD) is used. This +is a very convient function which makes it possible to create outputs in +a structures and easy maintainable way. The drawback however is that +most proprietary OSes don't support this function. At g10@tie{}Code we +have looked into several ways on how to overcome this limitation but no +sufficiently easy and maintainable way has been found. Porting +@emph{glibc} to a general POSIX system is of course an option and would +make writing portable software much easier; this it has not yet been +done and the system administrator wouldneed to cope with the GNU +specific admin things in addition to the generic ones of his system. + +We have now settled to use explicit stdio wrappers with a functionality +similar to funopen. Although the code for this has already been written +(@emph{libestream}), we have not yet changed GnuPG to use it. + +This means that on systems not supporting either @code{funopen} or +@code{fopencookie}, logging to a socket won't work, prompts are not +formatted as pretty as theyshould be and @command{gpgsm}'s +@code{LISTKEYS} Assuan command does not work. + +@item +We are planning to use file descriptor passing for interprocess +communication. This will allow us save a lot of resources and improve +performance of certain operations a lot. Systems not supporting this +won't gain these benefits but we try to keep them working the satndard +way as it is done today. + +@item +We require more or less full POSIX compatibility. This has been +arround for 15 years now and thus we don't believe it makes sense to +support non POSIX systems anymore. Well, we of course the usual +workarounds for near POSIX systems well be applied. + +There is one exception of this rule: Systems based the Microsoft Windows +API (called here @emph{W32}) will be supported to some extend. + +@end itemize + + +@menu +* W32 Notes:: Microsoft Windows Notes +@end menu + + +@node W32 Notes +@section Microsoft Windows Notes + +The port to Microsoft Windows based OSes is pretty new and has some +limitations we might remove over time. Note, that we have not yet done +any security audit and you should not use any valuable private key. In +particular, @strong{using it on a box with more than one user, might +lead to a key compromise}. + +@noindent +Current limitations are: + +@itemize +@item +The @code{LISTKEYS} Assuan command of @command{gpgsm} is not supported. +Using the command line options @option{--list-keys} or +@option{--list-secret-keys} does however work. + +@item +No support for CRL checks. By default the option +@option{--disable-crl-checks} has been turned on and the log will show +an appropriate warning message. The reason for this is that the +separate CRL checking daemin (@command{dirmngr}) has not been ported to +W32. + +@item +@command{gpgconf} does not create backup files, so in case of trouble +your configuration file might get lost. + +@item +@command{watchgnupg} is not available. Logging to sockets is not +possible. + +@item +The periodical smartcard status checking done by @command{scdaemon} is +not yet supported. + +@item +Detached running of the gpg-agent is not directly supported. It needs +to be started in a console and left alone then. + +@end itemize + + + + + + diff --git a/doc/tools.texi b/doc/tools.texi index 086f71df1..53233cbd0 100644 --- a/doc/tools.texi +++ b/doc/tools.texi @@ -12,10 +12,11 @@ GnuPG comes with a couple of smaller tools: * addgnupghome:: Create .gnupg home directories. * gpgconf:: Modify .gnupg home directories. * gpgsm-gencert.sh:: Generate an X.509 certificate request. +* gpg-preset-passphrase:: Put a passphrase into the cache. @end menu @c -@c WATHCGNUPG +@c WATCHGNUPG @c @node watchgnupg @section Read logs from a socket @@ -593,3 +594,504 @@ whicl will be printed to stdout. +@c +@c GPG-PRESET-PASSPHRASE +@c +@node gpg-preset-passphrase +@section Put a passphrase into the cache. + +XXXX +The @command{gpgconf} is a utility to automatically and reasonable +safely query and modify configuration files in the @file{.gnupg} home +directory. It is designed not to be invoked manually by the user, but +automatically by graphical user interfaces (GUI).@footnote{Please note +that currently no locking is done, so concurrent access should be +avoided. There are some precautions to avoid corruption with +concurrent usage, but results may be inconsistent and some changes may +get lost. The stateless design makes it difficult to provide more +guarantees.} + +@command{gpgconf} provides access to the configuration of one or more +components of the GnuPG system. These components correspond more or +less to the programs that exist in the GnuPG framework, like GnuPG, +GPGSM, DirMngr, etc. But this is not a strict one-to-one +relationship. Not all configuration options are available through +@command{gpgconf}. @command{gpgconf} provides a generic and abstract +method to access the most important configuration options that can +feasibly be controlled via such a mechanism. + +@command{gpgconf} can be used to gather and change the options +available in each component, and can also provide their default +values. @command{gpgconf} will give detailed type information that +can be used to restrict the user's input without making an attempt to +commit the changes. + +@command{gpgconf} provides the backend of a configuration editor. The +configuration editor would usually be a graphical user interface +program, that allows to display the current options, their default +values, and allows the user to make changes to the options. These +changes can then be made active with @command{gpgconf} again. Such a +program that uses @command{gpgconf} in this way will be called GUI +throughout this section. + +@menu +* Invoking gpgconf:: List of all commands and options. +* Format conventions:: Formatting conventions relevant for all commands. +* Listing components:: List all gpgconf components. +* Listing options:: List all options of a component. +* Changing options:: Changing options of a component. +@end menu + + +@node Invoking gpgconf +@subsection Invoking gpgconf + +One of the following commands must be given: + +@table @gnupgtabopt +@item --list-components +List all components. This is the default command used if none is +specified. + +@item --list-options @var{component} +List all options of the component @var{component}. + +@item --change-options @var{component} +Change the options of the component @var{component}. +@end table + +The following options may be used: + +@table @gnupgtabopt +@c FIXME: Not yet supported. +@c @item -o @var{file} +@c @itemx --output @var{file} +@c Use @var{file} as output file. + +@item -v +@itemx --verbose +Outputs additional information while running. Specifically, this +extends numerical field values by human-readable descriptions. + +@c FIXME: Not yet supported. +@c @item -n +@c @itemx --dry-run +@c Do not actually change anything. Useful together with +@c @code{--change-options} for testing purposes. + +@item -r +@itemx --runtime +Only used together with @code{--change-options}. If one of the +modified options can be changed in a running daemon process, signal +the running daemon to ask it to reparse its configuration file after +changing. + +This means that the changes will take effect at run-time, as far as +this is possible. Otherwise, they will take effect at the next start +of the respective backend programs. +@end table + + +@node Format conventions +@subsection Format conventions + +Some lines in the output of @command{gpgconf} contain a list of +colon-separated fields. The following conventions apply: + +@itemize @bullet +@item +The GUI program is required to strip off trailing newline and/or +carriage return characters from the output. + +@item +@command{gpgconf} will never leave out fields. If a certain version +provides a certain field, this field will always be present in all +@command{gpgconf} versions from that time on. + +@item +Future versions of @command{gpgconf} might append fields to the list. +New fields will always be separated from the previously last field by +a colon separator. The GUI should be prepared to parse the last field +it knows about up until a colon or end of line. + +@item +Not all fields are defined under all conditions. You are required to +ignore the content of undefined fields. +@end itemize + +There are several standard types for the content of a field: + +@table @asis +@item verbatim +Some fields contain strings that are not escaped in any way. Such +fields are described to be used @emph{verbatim}. These fields will +never contain a colon character (for obvious reasons). No de-escaping +or other formatting is required to use the field content. This is for +easy parsing of the output, when it is known that the content can +never contain any special characters. + +@item percent-escaped +Some fields contain strings that are described to be +@emph{percent-escaped}. Such strings need to be de-escaped before +their content can be presented to the user. A percent-escaped string +is de-escaped by replacing all occurences of @code{%XY} by the byte +that has the hexadecimal value @code{XY}. @code{X} and @code{Y} are +from the set @code{0-9a-f}. + +@item localised +Some fields contain strings that are described to be @emph{localised}. +Such strings are translated to the active language and formatted in +the active character set. + +@item @w{unsigned number} +Some fields contain an @emph{unsigned number}. This number will +always fit into a 32-bit unsigned integer variable. The number may be +followed by a space, followed by a human readable description of that +value (if the verbose option is used). You should ignore everything +in the field that follows the number. + +@item @w{signed number} +Some fields contain a @emph{signed number}. This number will always +fit into a 32-bit signed integer variable. The number may be followed +by a space, followed by a human readable description of that value (if +the verbose option is used). You should ignore everything in the +field that follows the number. + +@item option +Some fields contain an @emph{option} argument. The format of an +option argument depends on the type of the option and on some flags: + +@table @asis +@item no argument +The simplest case is that the option does not take an argument at all +(@var{type} @code{0}). Then the option argument is an unsigned number +that specifies how often the option occurs. If the @code{list} flag +is not set, then the only valid number is @code{1}. Options that do +not take an argument never have the @code{default} or @code{optional +arg} flag set. + +@item number +If the option takes a number argument (@var{alt-type} is @code{2} or +@code{3}), and it can only occur once (@code{list} flag is not set), +then the option argument is either empty (only allowed if the argument +is optional), or it is a number. A number is a string that begins +with an optional minus character, followed by one or more digits. The +number must fit into an integer variable (unsigned or signed, +depending on @var{alt-type}). + +@item number list +If the option takes a number argument and it can occur more than once, +then the option argument is either empty, or it is a comma-separated +list of numbers as described above. + +@item string +If the option takes a string argument (@var{alt-type} is 1), and it +can only occur once (@code{list} flag is not set) then the option +argument is either empty (only allowed if the argument is optional), +or it starts with a double quote character (@code{"}) followed by a +percent-escaped string that is the argument value. Note that there is +only a leading double quote character, no trailing one. The double +quote character is only needed to be able to differentiate between no +value and the empty string as value. + +@item string list +If the option takes a number argument and it can occur more than once, +then the option argument is either empty, or it is a comma-separated +list of string arguments as described above. +@end table +@end table + +The active language and character set are currently determined from +the locale environment of the @command{gpgconf} program. + +@c FIXME: Document the active language and active character set. Allow +@c to change it via the command line? + + +@node Listing components +@subsection Listing components + +The command @code{--list-components} will list all components that can +be configured with @command{gpgconf}. Usually, one component will +correspond to one GnuPG-related program and contain the options of +that programs configuration file that can be modified using +@command{gpgconf}. However, this is not necessarily the case. A +component might also be a group of selected options from several +programs, or contain entirely virtual options that have a special +effect rather than changing exactly one option in one configuration +file. + +A component is a set of configuration options that semantically belong +together. Furthermore, several changes to a component can be made in +an atomic way with a single operation. The GUI could for example +provide a menu with one entry for each component, or a window with one +tabulator sheet per component. + +The command argument @code{--list-components} lists all available +components, one per line. The format of each line is: + +@code{@var{name}:@var{description}} + +@table @var +@item name +This field contains a name tag of the component. The name tag is used +to specify the component in all communication with @command{gpgconf}. +The name tag is to be used @emph{verbatim}. It is thus not in any +escaped format. + +@item description +The @emph{string} in this field contains a human-readable description +of the component. It can be displayed to the user of the GUI for +informational purposes. It is @emph{percent-escaped} and +@emph{localized}. +@end table + +Example: +@example +$ gpgconf --list-components +gpg:GPG for OpenPGP +gpg-agent:GPG Agent +scdaemon:Smartcard Daemon +gpgsm:GPG for S/MIME +dirmngr:Directory Manager +@end example + + +@node Listing options +@subsection Listing options + +Every component contains one or more options. Options may be gathered +into option groups to allow the GUI to give visual hints to the user +about which options are related. + +The command argument @code{@w{--list-options @var{component}}} lists +all options (and the groups they belong to) in the component +@var{component}, one per line. @var{component} must be the string in +the field @var{name} in the output of the @code{--list-components} +command. + +There is one line for each option and each group. First come all +options that are not in any group. Then comes a line describing a +group. Then come all options that belong into each group. Then comes +the next group and so on. There does not need to be any group (and in +this case the output will stop after the last non-grouped option). + +The format of each line is: + +@code{@var{name}:@var{flags}:@var{level}:@var{description}:@var{type}:@var{alt-type}:@var{argname}:@var{default}:@var{argdef}:@var{value}} + +@table @var +@item name +This field contains a name tag for the group or option. The name tag +is used to specify the group or option in all communication with +@command{gpgconf}. The name tag is to be used @emph{verbatim}. It is +thus not in any escaped format. + +@item flags +The flags field contains an @emph{unsigned number}. Its value is the +OR-wise combination of the following flag values: + +@table @code +@item group (1) +If this flag is set, this is a line describing a group and not an +option. +@end table + +The following flag values are only defined for options (that is, if +the @code{group} flag is not used). + +@table @code +@item optional arg (2) +If this flag is set, the argument is optional. This is never set for +@var{type} @code{0} (none) options. + +@item list (4) +If this flag is set, the option can be given multiple times. + +@item runtime (8) +If this flag is set, the option can be changed at runtime. + +@item default (16) +If this flag is set, a default value is available. + +@item default desc (32) +If this flag is set, a (runtime) default is available. This and the +@code{default} flag are mutually exclusive. + +@item no arg desc (64) +If this flag is set, and the @code{optional arg} flag is set, then the +option has a special meaning if no argument is given. +@end table + +@item level +This field is defined for options and for groups. It contains an +@emph{unsigned number} that specifies the expert level under which +this group or option should be displayed. The following expert levels +are defined for options (they have analogous meaning for groups): + +@table @code +@item basic (0) +This option should always be offered to the user. + +@item advanced (1) +This option may be offered to advanced users. + +@item expert (2) +This option should only be offered to expert users. + +@item invisible (3) +This option should normally never be displayed, not even to expert +users. + +@item internal (4) +This option is for internal use only. Ignore it. +@end table + +The level of a group will always be the lowest level of all options it +contains. + +@item description +This field is defined for options and groups. The @emph{string} in +this field contains a human-readable description of the option or +group. It can be displayed to the user of the GUI for informational +purposes. It is @emph{percent-escaped} and @emph{localized}. + +@item type +This field is only defined for options. It contains an @emph{unsigned +number} that specifies the type of the option's argument, if any. The +following types are defined: + +Basic types: + +@table @code +@item none (0) +No argument allowed. + +@item string (1) +An @emph{unformatted string}. + +@item int32 (2) +A @emph{signed number}. + +@item uint32 (3) +An @emph{unsigned number}. +@end table + +Complex types: + +@table @code +@item pathname (32) +A @emph{string} that describes the pathname of a file. The file does +not necessarily need to exist. + +@item ldap server (33) +A @emph{string} that describes an LDAP server in the format: + +@code{@var{hostname}:@var{port}:@var{username}:@var{password}:@var{base_dn}} +@end table + +More types will be added in the future. Please see the @var{alt-type} +field for information on how to cope with unknown types. + +@item alt-type +This field is identical to @var{type}, except that only the types +@code{0} to @code{31} are allowed. The GUI is expected to present the +user the option in the format specified by @var{type}. But if the +argument type @var{type} is not supported by the GUI, it can still +display the option in the more generic basic type @var{alt-type}. The +GUI must support all the defined basic types to be able to display all +options. More basic types may be added in future versions. If the +GUI encounters a basic type it doesn't support, it should report an +error and abort the operation. + +@item argname +This field is only defined for options with an argument type +@var{type} that is not @code{0}. In this case it may contain a +@emph{percent-escaped} and @emph{localised string} that gives a short +name for the argument. The field may also be empty, though, in which +case a short name is not known. + +@item default +This field is defined only for options. Its format is that of an +@emph{option argument} (@xref{Format conventions}, for details). If +the default value is empty, then no default is known. Otherwise, the +value specifies the default value for this option. Note that this +field is also meaningful if the option itself does not take a real +argument. + +@item argdef +This field is defined only for options for which the @code{optional +arg} flag is set. If the @code{no arg desc} flag is not set, its +format is that of an @emph{option argument} (@xref{Format +conventions}, for details). If the default value is empty, then no +default is known. Otherwise, the value specifies the default value +for this option. If the @code{no arg desc} flag is set, the field is +either empty or contains a description of the effect of this option if +no argument is given. Note that this field is also meaningful if the +option itself does not take a real argument. + +@item value +This field is defined only for options. Its format is that of an +@emph{option argument}. If it is empty, then the option is not +explicitely set in the current configuration, and the default applies +(if any). Otherwise, it contains the current value of the option. +Note that this field is also meaningful if the option itself does not +take a real argument. +@end table + + +@node Changing options +@subsection Changing options + +The command @w{@code{--change-options @var{component}}} will attempt +to change the options of the component @var{component} to the +specified values. @var{component} must be the string in the field +@var{name} in the output of the @code{--list-components} command. You +have to provide the options that shall be changed in the following +format on standard input: + +@code{@var{name}:@var{flags}:@var{new-value}} + +@table @var +@item name +This is the name of the option to change. @var{name} must be the +string in the field @var{name} in the output of the +@code{--list-options} command. + +@item flags +The flags field contains an @emph{unsigned number}. Its value is the +OR-wise combination of the following flag values: + +@table @code +@item default (16) +If this flag is set, the option is deleted and the default value is +used instead (if applicable). +@end table + +@item new-value +The new value for the option. This field is only defined if the +@code{default} flag is not set. The format is that of an @emph{option +argument}. If it is empty (or the field is omitted), the default +argument is used (only allowed if the argument is optional for this +option). Otherwise, the option will be set to the specified value. +@end table + +Examples: + +To set the force option, which is of basic type @code{none (0)}: + +@example +$ echo 'force:0:1' | gpgconf --change-options dirmngr +@end example + +To delete the force option: + +@example +$ echo 'force:16:' | gpgconf --change-options dirmngr +@end example + +The @code{--runtime} option can influence when the changes take +effect. + + + diff --git a/jnlib/w32-afunix.c b/jnlib/w32-afunix.c index eac4f9560..c93d389da 100644 --- a/jnlib/w32-afunix.c +++ b/jnlib/w32-afunix.c @@ -49,17 +49,18 @@ _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen) struct sockaddr_in myaddr; struct sockaddr_un * unaddr; FILE * fp; - int port = 0; + int port; unaddr = (struct sockaddr_un *)addr; fp = fopen (unaddr->sun_path, "rb"); if (!fp) - return -1; + return -1; fscanf (fp, "%d", &port); fclose (fp); + /* XXX: set errno in this case */ if (port < 0 || port > 65535) - return -1; + return -1; myaddr.sin_family = AF_INET; myaddr.sin_port = port; diff --git a/sm/ChangeLog b/sm/ChangeLog index 0dcaa9c20..7a16cb570 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,6 +1,7 @@ 2004-12-21 Werner Koch * gpgsm.c (main): Use default_homedir(). + (main) [W32]: Default to disabled CRL checks. 2004-12-20 Werner Koch diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 935d50474..074027bf2 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -757,6 +757,9 @@ main ( int argc, char **argv) opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/ opt.homedir = default_homedir (); +#ifdef HAVE_W32_SYSTEM + opt.no_crl_checks = 1; +#endif /* First check whether we have a config file on the commandline */ orig_argc = argc; diff --git a/tools/ChangeLog b/tools/ChangeLog index 34e985947..38b9e9cf4 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2004-12-21 Werner Koch + + * gpgconf-comp.c (get_config_pathname) [DOSISH]: Detect absolute + pathnames with a drive letter. + 2004-12-15 Werner Koch * Makefile.am (bin_PROGRAMS) [W32]: Do not build watchgnupg. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index fe696301c..e4758c1e6 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1272,7 +1272,13 @@ get_config_pathname (gc_component_t component, gc_backend_t backend) else pathname = ""; +#ifdef HAVE_DOSISH_SYSTEM + if (!(pathname[0] + && pathname[1] == ':' + && (pathname[2] == '/' || pathname[2] == '\\'))) +#else if (pathname[0] != '/') +#endif gc_error (1, 0, "Option %s, needed by backend %s, is not absolute", gc_backend[backend].option_config_filename, gc_backend[backend].name); -- cgit From b16d30910ae2c79400d085d8626ed2b25bfe3961 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 9 Mar 2005 10:11:14 +0000 Subject: Add honor-http-proxy. --- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 3 +++ 2 files changed, 7 insertions(+) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/ChangeLog b/tools/ChangeLog index 4d520cfca..e39dd3b04 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2005-03-09 Werner Koch + + * gpgconf-comp.c : Add honor-http-proxy. + 2005-02-25 Werner Koch * no-libgcrypt.c (gcry_strdup): New. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e4758c1e6..dd35d3701 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -746,6 +746,9 @@ static gc_option_t gc_options_dirmngr[] = { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|redirect all HTTP requests to URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", N_("use system's HTTP proxy setting"), + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, { "LDAP", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, -- cgit From c6de0c2d4e38b23917b0da3ae711f0b36b24e371 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 9 Mar 2005 19:22:54 +0000 Subject: Fixed description for dirmngr:honor-http-proxy --- tools/gpgconf-comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index dd35d3701..5e6777e1f 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -748,7 +748,7 @@ static gc_option_t gc_options_dirmngr[] = GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, { "honor-http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", N_("use system's HTTP proxy setting"), - GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "LDAP", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, -- cgit From 3ff9a743bf6faeb99e8ee6113fe54af4f34cc288 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 21 Apr 2005 09:33:07 +0000 Subject: * configure.ac: Do not build gpg by default. * gpgsm.c: New options --{enable,disable}-trusted-cert-crl-check. * certchain.c (gpgsm_validate_chain): Make use of it. * certchain.c (gpgsm_validate_chain): Check revocations even for expired certificates. This is required because on signature verification an expired key is fine whereas a revoked one is not. * gpgconf-comp.c: Add gpgsm option disable-trusted-cert-crl-check. --- ChangeLog | 9 +++++++++ README | 5 +++-- TODO | 29 ++++++++--------------------- configure.ac | 11 ++++++++++- doc/gpgsm.texi | 12 ++++++++++++ scd/ChangeLog | 4 ++++ scd/ccid-driver.c | 2 +- scd/command.c | 26 +++++++++++++------------- sm/ChangeLog | 3 +++ sm/certchain.c | 10 ++++++---- sm/gpgsm.c | 12 ++++++++++++ sm/gpgsm.h | 1 + tools/ChangeLog | 8 ++++++++ tools/gpgconf-comp.c | 6 ++++++ tools/symcryptrun.c | 2 +- 15 files changed, 97 insertions(+), 43 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/ChangeLog b/ChangeLog index 013241648..cfe0f863b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-04-21 Werner Koch + + * configure.ac: Do not build gpg by default. + +2005-04-20 Werner Koch + + * configure.ac: Test whether GPG_ERR_LOCKED is declared and + provide a replacement if not. + 2005-04-15 Werner Koch * configure.ac: Require libksba 0.9.11. diff --git a/README b/README index 7e44765a6..7bb83f1f2 100644 --- a/README +++ b/README @@ -11,7 +11,8 @@ available in 1.9. You should use this GnuPG version if you want to use the gpg-agent or gpgsm (the S/MIME variant of gpg). Note that the gpg-agent is also -helpful when using the standard gpg versions (1.2.x or 1.3.x). +helpful when using the standard gpg versions (1.3.x as well as some of +the old 1.2.x). BUILD INSTRUCTIONS @@ -51,7 +52,7 @@ If everything succeeds, you have a working GnuPG with support for S/MIME and smartcards. Note that there is no binary gpg but a gpg2 so that this package won't confict with a GnuPG 1.2 or 1.3 installation. gpg2 behaves just like gpg; it is however suggested to -keep using gpg 1.2.x or 1.3.x. +keep using gpg 1.2.x or 1.3.x. gpg2 is not even build by default. In case of problem please ask on gpa-dev@gnupg.org for advise. Note that this release is only expected to build on GNU and *BSD systems. diff --git a/TODO b/TODO index 26b2cee60..6a0e9b18e 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,5 @@ -*- outline -*- -* IMPORTANT -Check that openpty and pty.h are available and build symcryptrun only -then. Run shred on the temporary files. - - * src/base64 ** Make parsing more robust Currently we don't cope with overlong lines in the best way. @@ -23,14 +18,7 @@ might want to have an agent context for each service request * sm/certchain.c ** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent. -** figure out how to auto retrieve a key by serialno+issuer. - Dirmngr is currently not able to parse more than the CN. -* sm/certlist.c -** ocspSigning usage is not fully implemented - We should review the entire CRL and OCSP validation system. - Okay. This has been fixed in dirmngr when running it in system - daemon mode. * sm/decrypt.c ** replace leading zero in integer hack by a cleaner solution @@ -58,8 +46,6 @@ might want to have an agent context for each service request ** A SIGHUP should also restart the scdaemon But do this only after all connections terminated. As of now we only send a RESET. -** Watch the child process if not invoked as a daemon - and terminate after the child has terminated * agent/command.c ** Make sure that secure memory is used where appropriate @@ -69,7 +55,8 @@ might want to have an agent context for each service request ** Support DSA * agent/divert-scd.c - Remove the agent_reset_scd kludge. + Remove the agent_reset_scd kludge. We will do this after Scdaemon + has been changed to allow multiple sessions. Currently in progress. * Move pkcs-1 encoding into libgcrypt. @@ -93,11 +80,7 @@ might want to have an agent context for each service request ** Explain how to setup a root CA key as trusted ** Explain how trustlist.txt might be managed. ** Write a script to generate man pages from texi. - -* Requirements by the BSI -** Support authorityKeyIdentifier.keyIdentifier - This needs support in libksba/src/cert.c as well as in sm/*.c. - Need test certs as well. Same goes for CRL authorityKeyIdentifier. + In progress (yatm) * Windows port @@ -108,5 +91,9 @@ might want to have an agent context for each service request ** No card status notifications. -* [scdaemon] release the card after use so that gpg 1.4 is abale to access it +* scd/ +** Release the card after use so that gpg 1.4 is able to access it + This won't be a sufficient change. we need to change gpg 1.4 to make + use of the agent. Work is underway. + diff --git a/configure.ac b/configure.ac index d0ffa8ca4..8654785ee 100644 --- a/configure.ac +++ b/configure.ac @@ -62,7 +62,7 @@ have_ksba=no have_opensc=no have_pth=no -GNUPG_BUILD_PROGRAM(gpg, yes) +GNUPG_BUILD_PROGRAM(gpg, no) GNUPG_BUILD_PROGRAM(gpgsm, yes) GNUPG_BUILD_PROGRAM(agent, yes) GNUPG_BUILD_PROGRAM(scdaemon, yes) @@ -313,6 +313,11 @@ AH_BOTTOM([ #define EXEC_TEMPFILE_ONLY #endif +/* Temporary hacks to avoid requring a libgpg-error update. */ +#if !HAVE_DECL_GPG_ERR_LOCKED +#define GPG_ERR_LOCKED 173 +#endif + ]) AM_MAINTAINER_MODE @@ -437,6 +442,10 @@ AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) # AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", have_gpg_error=yes,have_gpg_error=no) +_tmp_gpg_error_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS $GPG_ERROR_CFLAGS" +AC_CHECK_DECLS(GPG_ERR_LOCKED,,,[#include ]) +CFLAGS="${_tmp_gpg_error_save_cflags}" # diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index df2f71bce..ba98ae87c 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -315,6 +315,18 @@ By default the @acronym{CRL} checks are enabled and the DirMngr is used to check for revoked certificates. The disable option is most useful with an off-line network connection to suppress this check. +@item --enable-trusted-cert-crl-check +@itemx --disable-trusted-cert-crl-check +@opindex enable-trusted-cert-crl-check +@opindex disable-trusted-cert-crl-check +By default the @acronym{CRL} for trusted root certificates are checked +like for any other certificates. This allows a CA to revoke its own +certificates voluntary without the need of putting all ever issued +certificates into a CRL. The disable option may be used to switch this +extra check off. Due to the caching done by the Dirmngr, there won't be +any noticeable performance gain. Note, that this also disables possible +OCSP checks for trusted root certificates. + @item --force-crl-refresh @opindex force-crl-refresh Tell the dirmngr to reload the CRL for each request. For better diff --git a/scd/ChangeLog b/scd/ChangeLog index 9d246ffca..c5a1062b8 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,7 @@ +2005-04-20 Werner Koch + + * command.c: Use GPG_ERR_LOCKED instead of EBUSY. + 2005-04-14 Werner Koch * app-openpgp.c (retrieve_key_material): Rewritten. Return a diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 13e11e4bc..e9666ee17 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1274,7 +1274,7 @@ ccid_poll (ccid_driver_t handle) } -/* Note that this fucntion won't return the error codes NO_CARD or +/* Note that this function won't return the error codes NO_CARD or CARD_INACTIVE */ int ccid_slot_status (ccid_driver_t handle, int *statusbits) diff --git a/scd/command.c b/scd/command.c index 9881b1be0..7d777d8b7 100644 --- a/scd/command.c +++ b/scd/command.c @@ -263,7 +263,7 @@ open_card (ctrl_t ctrl, const char *apptype) return 0; /* Already initialized using a card context. */ if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if (ctrl->reader_slot != -1) slot = ctrl->reader_slot; @@ -360,7 +360,7 @@ cmd_serialno (assuan_context_t ctx, char *line) if (ctrl->server_local->card_removed) { if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); do_reset (ctrl, 0); } @@ -745,7 +745,7 @@ cmd_setdata (assuan_context_t ctx, char *line) unsigned char *buf; if (locked_session && locked_session != ctrl->server_local) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); /* Parse the hexstring. */ for (p=line,n=0; hexdigitp (p); p++, n++) @@ -817,7 +817,7 @@ cmd_pksign (assuan_context_t ctx, char *line) char *keyidstr; if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if ((rc = open_card (ctrl, NULL))) return rc; @@ -871,7 +871,7 @@ cmd_pkauth (assuan_context_t ctx, char *line) char *keyidstr; if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if ((rc = open_card (ctrl, NULL))) return rc; @@ -921,7 +921,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line) char *keyidstr; if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if ((rc = open_card (ctrl, NULL))) return rc; @@ -1021,7 +1021,7 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) char *line, *linebuf; if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if ((rc = open_card (ctrl, NULL))) return rc; @@ -1076,7 +1076,7 @@ cmd_genkey (assuan_context_t ctx, char *line) int force = has_option (line, "--force"); if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); /* Skip over options. */ while ( *line == '-' && line[1] == '-' ) @@ -1165,7 +1165,7 @@ cmd_passwd (assuan_context_t ctx, char *line) int reset_mode = has_option (line, "--reset"); if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); /* Skip over options. */ while (*line == '-' && line[1] == '-') @@ -1212,7 +1212,7 @@ cmd_checkpin (assuan_context_t ctx, char *line) char *keyidstr; if ( IS_LOCKED (ctrl) ) - return gpg_error (GPG_ERR_EBUSY); + return gpg_error (GPG_ERR_LOCKED); if ((rc = open_card (ctrl, NULL))) return rc; @@ -1244,7 +1244,7 @@ cmd_checkpin (assuan_context_t ctx, char *line) Grant exclusive card access to this session. Note that there is no lock counter used and a second lock from the same session will get ignore. A single unlock (or RESET) unlocks the session. - Return GPG_ERR_EBUSY if another session has locked the reader. + Return GPG_ERR_LOCKED if another session has locked the reader. If the option --wait is given the command will wait until a lock has been released. @@ -1259,7 +1259,7 @@ cmd_lock (assuan_context_t ctx, char *line) if (locked_session) { if (locked_session != ctrl->server_local) - rc = gpg_error (GPG_ERR_EBUSY); + rc = gpg_error (GPG_ERR_LOCKED); } else locked_session = ctrl->server_local; @@ -1293,7 +1293,7 @@ cmd_unlock (assuan_context_t ctx, char *line) if (locked_session) { if (locked_session != ctrl->server_local) - rc = gpg_error (GPG_ERR_EBUSY); + rc = gpg_error (GPG_ERR_LOCKED); else locked_session = NULL; } diff --git a/sm/ChangeLog b/sm/ChangeLog index b209b9d4b..aa8e8671f 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,5 +1,8 @@ 2005-04-21 Werner Koch + * gpgsm.c: New options --{enable,disable}-trusted-cert-crl-check. + * certchain.c (gpgsm_validate_chain): Make use of it. + * certchain.c (gpgsm_validate_chain): Check revocations even for expired certificates. This is required because on signature verification an expired key is fine whereas a revoked one is not. diff --git a/sm/certchain.c b/sm/certchain.c index 2e491f590..02e5b409f 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -752,13 +752,13 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, } - /* Is this a self-signed certificate? */ + /* Is this a self-issued certificate? */ if (subject && !strcmp (issuer, subject)) { /* Yes. */ if (gpgsm_check_cert_sig (subject_cert, subject_cert) ) { do_list (1, lm, fp, - _("selfsigned certificate has a BAD signature")); + _("self-signed certificate has a BAD signature")); if (DBG_X509) { gpgsm_dump_cert ("self-signing cert", subject_cert); @@ -816,7 +816,9 @@ gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, /* Check for revocations etc. */ if ((flags & 1)) - rc = 0; + ; + else if (opt.no_trusted_cert_crl_check) + ; else rc = is_cert_still_valid (ctrl, lm, fp, subject_cert, subject_cert, @@ -1045,7 +1047,7 @@ gpgsm_basic_cert_check (ksba_cert_t cert) rc = gpgsm_check_cert_sig (cert, cert); if (rc) { - log_error ("selfsigned certificate has a BAD signature: %s\n", + log_error ("self-signed certificate has a BAD signature: %s\n", gpg_strerror (rc)); if (DBG_X509) { diff --git a/sm/gpgsm.c b/sm/gpgsm.c index dae547702..fb6533030 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -130,6 +130,8 @@ enum cmd_and_opt_values { oDisableCRLChecks, oEnableCRLChecks, + oDisableTrustedCertCRLCheck, + oEnableTrustedCertCRLCheck, oForceCRLRefresh, oDisableOCSP, @@ -285,6 +287,8 @@ static ARGPARSE_OPTS opts[] = { N_("use system's dirmngr if available")}, { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, + { oDisableTrustedCertCRLCheck, "disable-trusted-cert-crl-check", 0, "@"}, + { oEnableTrustedCertCRLCheck, "enable-trusted-cert-crl-check", 0, "@"}, { oForceCRLRefresh, "force-crl-refresh", 0, "@"}, { oDisableOCSP, "disable-ocsp", 0, "@" }, @@ -973,6 +977,12 @@ main ( int argc, char **argv) case oEnableCRLChecks: opt.no_crl_check = 0; break; + case oDisableTrustedCertCRLCheck: + opt.no_trusted_cert_crl_check = 1; + break; + case oEnableTrustedCertCRLCheck: + opt.no_trusted_cert_crl_check = 0; + break; case oForceCRLRefresh: opt.force_crl_refresh = 1; break; @@ -1352,6 +1362,8 @@ main ( int argc, char **argv) GC_OPT_FLAG_NONE ); printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE ); + printf ("disable-trusted-cert-crl-check:%lu:\n", + GC_OPT_FLAG_NONE ); printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE ); printf ("include-certs:%lu:1:\n", diff --git a/sm/gpgsm.h b/sm/gpgsm.h index aafc4815d..1068e9d5e 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -97,6 +97,7 @@ struct { int ignore_time_conflict; /* Ignore certain time conflicts */ int no_crl_check; /* Don't do a CRL check */ + int no_trusted_cert_crl_check; /* Don't run a CRL check for trusted certs. */ int force_crl_refresh; /* Force refreshing the CRL. */ int enable_ocsp; /* Default to use OCSP checks. */ diff --git a/tools/ChangeLog b/tools/ChangeLog index 7fd4c2899..b5a104ce6 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,11 @@ +2005-04-21 Werner Koch + + * gpgconf-comp.c: Add gpgsm option disable-trusted-cert-crl-check. + +2005-04-20 Werner Koch + + * gpgconf-comp.c: Add gpg-agent:disable-scdaemon. + 2005-04-19 Marcus Brinkmann * symcryptrun.c: Add --input option. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 5e6777e1f..c49d1dcbb 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -449,6 +449,9 @@ static gc_option_t gc_options_gpg_agent[] = { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPG_AGENT }, + { "disable-scdaemon", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "do not use the SCdaemon", + GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, @@ -651,6 +654,9 @@ static gc_option_t gc_options_gpgsm[] = { "disable-crl-checks", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "never consult a CRL", GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, + { "disable-trusted-cert-crl-check", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + "gnupg", N_("do not check CRLs for root certificates"), + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, { "enable-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "gnupg", "check validity using OCSP", GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 8637987f8..f5fd496b8 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -124,7 +124,7 @@ enum cmd_and_opt_values oKeyfile, oDecrypt, oEncrypt, - oInput, + oInput }; -- cgit From deeba405a9a5868ea478db5003be6335ab9aac6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Jun 2005 08:12:03 +0000 Subject: gcc-4 defaults forced me to edit many many files to get rid of the char * vs. unsigned char * warnings. The GNU coding standards used to say that these mismatches are okay and better than a bunch of casts. Obviously this has changed now. --- agent/ChangeLog | 46 ++++++++++++++++++++++ agent/agent.h | 15 ++++---- agent/cache.c | 20 +++++++--- agent/call-scd.c | 19 ++++------ agent/command-ssh.c | 75 ++++++++++++++++-------------------- agent/command.c | 4 +- agent/divert-scd.c | 9 +++-- agent/findkey.c | 4 +- agent/genkey.c | 2 +- agent/gpg-agent.c | 11 ++++-- agent/minip12.c | 2 + agent/pkdecrypt.c | 2 +- agent/pksign.c | 2 +- agent/protect-tool.c | 21 +++++----- agent/protect.c | 29 ++++++++------ agent/query.c | 9 +++-- common/ChangeLog | 26 ++++++++++++- common/estream.c | 21 +++++----- common/estream.h | 8 ++-- common/iobuf.c | 19 ++++++---- common/iobuf.h | 4 +- common/miscellaneous.c | 2 +- common/sexputil.c | 9 +++-- common/simple-pwquery.c | 2 +- common/ttyio.c | 2 +- common/util.h | 2 +- doc/gpg-agent.texi | 8 +++- g10/ChangeLog | 5 +++ g10/g10.c | 4 +- g10/misc.c | 5 ++- jnlib/ChangeLog | 13 +++++++ jnlib/argparse.c | 2 +- jnlib/logging.c | 5 ++- jnlib/stringhelp.c | 97 ++++++++++++++++++++++++++++------------------- jnlib/stringhelp.h | 9 ++--- jnlib/utf8conv.c | 21 +++++----- kbx/ChangeLog | 11 ++++++ kbx/kbxutil.c | 2 +- kbx/keybox-blob.c | 45 ++++++++++++---------- kbx/keybox-defs.h | 5 ++- kbx/keybox-file.c | 4 +- scd/apdu.c | 2 +- scd/app-help.c | 2 +- scd/app-openpgp.c | 27 ++++++------- scd/app-p15.c | 28 +++++++------- scd/app.c | 2 +- scd/ccid-driver.c | 14 +++---- scd/command.c | 10 ++--- scd/iso7816.c | 18 +++++---- scd/pcsc-wrapper.c | 4 +- sm/ChangeLog | 32 ++++++++++++++++ sm/base64.c | 14 ++++--- sm/call-agent.c | 25 ++++++------ sm/certcheck.c | 14 ++++--- sm/certdump.c | 28 +++++++------- sm/certreqgen.c | 9 +++-- sm/delete.c | 4 +- sm/encrypt.c | 12 +++--- sm/fingerprint.c | 17 +++++---- sm/gpgsm.h | 10 ++--- sm/keydb.c | 9 +++-- sm/keylist.c | 4 +- sm/server.c | 4 +- sm/sign.c | 2 +- tools/ChangeLog | 5 +++ tools/gpg-connect-agent.c | 2 +- tools/gpgconf-comp.c | 2 +- tools/gpgkey2ssh.c | 3 ++ tools/watchgnupg.c | 2 +- 69 files changed, 558 insertions(+), 348 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/agent/ChangeLog b/agent/ChangeLog index 1a157fa52..055dbe53e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,49 @@ +2005-06-16 Werner Koch + + * protect-tool.c (make_advanced): Makde RESULT a plain char. + * call-scd.c (unescape_status_string): Need to cast unsigned char* + for strcpy. + (agent_card_pksign): Made arg R_BUF an unsigned char**. + * divert-scd.c (divert_pksign): Made SIGVAL unsigned char*. + (encode_md_for_card): Initialize R_VAL and R_LEN. + * genkey.c (store_key): Made BUF unsigned. + * protect.c (do_encryption): Ditto. + (do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT + and RESULTLEN even on error. + (merge_lists): Need to cast unsigned char * for strcpy. Initialize + RESULTand RESULTLEN even on error. + (agent_unprotect): Likewise for strtoul. + (make_shadow_info): Made P and INFO plain char. + (agent_shadow_key): Made P plain char. + +2005-06-15 Werner Koch + + * query.c (agent_get_passphrase): Made HEXSTRING a char*. + * command-ssh.c (ssh_key_grip): Made arg BUFFER unsigned. + (ssh_key_grip): Simplified. + (data_sign): Initialize variables with the definition. + (ssh_convert_key_to_blob): Make sure that BLOB and BLOB_SIZE + are set to NULL on error. Cool, gcc-4 detects uninitialized stuff + beyond function boundaries; well it can't know that we do error + proper error handling so that this was not a real error. + (file_to_buffer): Likewise for BUFFER and BUFFER_N. + (data_sign): Likewise for SIG and SIG_N. + (stream_read_byte): Set B to a value even on error. + * command.c (cmd_genkey): Changed VALUE to char. + (cmd_readkey): Cast arg for gcry_sexp_sprint. + * agent.h (struct server_control_s): Made KEYGRIP unsigned. + +2005-06-13 Werner Koch + + * command-ssh.c (start_command_handler_ssh): Reset the SCD. + +2005-06-09 Werner Koch + + * gpg-agent.c (create_socket_name): New option --max-cache-ttl-ssh. + * cache.c (housekeeping): Use it. + (agent_put_cache): Use a switch to get the default ttl so that it + is easier to add more cases. + 2005-06-06 Werner Koch * gpg-agent.c: New option --default-cache-ttl-ssh. diff --git a/agent/agent.h b/agent/agent.h index 350e5c0d2..7a646a85f 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -71,9 +71,10 @@ struct { int no_grab; /* Don't let the pinentry grab the keyboard */ /* The default and maximum TTL of cache entries. */ - unsigned long def_cache_ttl; /* Normal. */ - unsigned long def_cache_ttl_ssh; /* SSH. */ - unsigned long max_cache_ttl; + unsigned long def_cache_ttl; /* Default. */ + unsigned long def_cache_ttl_ssh; /* for SSH. */ + unsigned long max_cache_ttl; /* Default. */ + unsigned long max_cache_ttl_ssh; /* for SSH. */ int running_detached; /* We are running detached from the tty. */ @@ -107,8 +108,8 @@ struct server_local_s; struct scd_local_s; /* Collection of data per session (aka connection). */ -struct server_control_s { - +struct server_control_s +{ /* Private data of the server (command.c). */ struct server_local_s *server_local; @@ -128,7 +129,7 @@ struct server_control_s { int valuelen; int raw_value: 1; } digest; - char keygrip[20]; + unsigned char keygrip[20]; int have_keygrip; int use_auth_call; /* Hack to send the PKAUTH command instead of the @@ -289,7 +290,7 @@ int agent_card_pksign (ctrl_t ctrl, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen); + unsigned char **r_buf, size_t *r_buflen); int agent_card_pkdecrypt (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*,size_t), diff --git a/agent/cache.c b/agent/cache.c index a032b4fa7..32b6ac0c7 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -103,10 +103,17 @@ housekeeping (void) } /* Second, make sure that we also remove them based on the created stamp so - that the user has to enter it from time to time. We do this every hour */ + that the user has to enter it from time to time. */ for (r=thecache; r; r = r->next) { - if (!r->lockcount && r->pw && r->created + opt.max_cache_ttl < current) + unsigned long maxttl; + + switch (r->cache_mode) + { + case CACHE_MODE_SSH: maxttl = opt.max_cache_ttl_ssh; break; + default: maxttl = opt.max_cache_ttl; break; + } + if (!r->lockcount && r->pw && r->created + maxttl < current) { if (DBG_CACHE) log_debug (" expired `%s' (%lus after creation)\n", @@ -203,10 +210,11 @@ agent_put_cache (const char *key, cache_mode_t cache_mode, if (!ttl) { - if (cache_mode == CACHE_MODE_SSH) - ttl = opt.def_cache_ttl_ssh; - else - ttl = opt.def_cache_ttl; + switch(cache_mode) + { + case CACHE_MODE_SSH: ttl = opt.def_cache_ttl_ssh; break; + default: ttl = opt.def_cache_ttl; break; + } } if (!ttl || cache_mode == CACHE_MODE_IGNORE) return 0; diff --git a/agent/call-scd.c b/agent/call-scd.c index 4dff8e3c1..7a623fda4 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -465,7 +465,7 @@ unescape_status_string (const unsigned char *s) { char *buffer, *d; - buffer = d = xtrymalloc (strlen (s)+1); + buffer = d = xtrymalloc (strlen ((const char*)s)+1); if (!buffer) return NULL; while (*s) @@ -666,7 +666,7 @@ agent_card_pksign (ctrl_t ctrl, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, const unsigned char *indata, size_t indatalen, - char **r_buf, size_t *r_buflen) + unsigned char **r_buf, size_t *r_buflen) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; @@ -714,14 +714,11 @@ agent_card_pksign (ctrl_t ctrl, /* Create an S-expression from it which is formatted like this: "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */ *r_buflen = 21 + 11 + sigbuflen + 4; - *r_buf = xtrymalloc (*r_buflen); - if (!*r_buf) - { - gpg_error_t tmperr = out_of_core (); - xfree (*r_buf); - return unlock_scd (ctrl, tmperr); - } - p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" ); + p = xtrymalloc (*r_buflen); + *r_buf = (unsigned char*)p; + if (!p) + return unlock_scd (ctrl, out_of_core ()); + p = stpcpy (p, "(7:sig-val(3:rsa(1:s" ); sprintf (p, "%u:", (unsigned int)sigbuflen); p += strlen (p); memcpy (p, sigbuf, sigbuflen); @@ -895,7 +892,7 @@ card_getattr_cb (void *opaque, const char *line) if (keywordlen == parm->keywordlen && !memcmp (keyword, parm->keyword, keywordlen)) { - parm->data = unescape_status_string (line); + parm->data = unescape_status_string ((const unsigned char*)line); if (!parm->data) parm->error = errno; } diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 870afe059..a43fee24f 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -297,6 +297,7 @@ stream_read_byte (estream_t stream, unsigned char *b) err = gpg_error_from_errno (errno); else err = gpg_error (GPG_ERR_EOF); + *b = 0; } else { @@ -604,6 +605,9 @@ file_to_buffer (const char *filename, unsigned char **buffer, size_t *buffer_n) gpg_error_t err; int ret; + *buffer = NULL; + *buffer_n = 0; + buffer_new = NULL; err = 0; @@ -1381,6 +1385,9 @@ ssh_convert_key_to_blob (unsigned char **blob, size_t *blob_size, gpg_error_t err; unsigned int i; + *blob = NULL; + *blob_size = 0; + blob_new = NULL; stream = NULL; err = 0; @@ -1535,20 +1542,12 @@ ssh_read_key_public_from_blob (unsigned char *blob, size_t blob_size, S-Expression KEY and writes it to BUFFER, which must be large enough to hold it. Returns usual error code. */ static gpg_error_t -ssh_key_grip (gcry_sexp_t key, char *buffer) +ssh_key_grip (gcry_sexp_t key, unsigned char *buffer) { - gpg_error_t err; - char *p; + if (!gcry_pk_get_keygrip (key, buffer)) + return gpg_error (GPG_ERR_INTERNAL); - /* FIXME: unsigned vs. signed. */ - - p = gcry_pk_get_keygrip (key, buffer); - if (! p) - err = gpg_error (GPG_ERR_INTERNAL); /* FIXME? */ - else - err = 0; - - return err; + return 0; } /* Converts the secret key KEY_SECRET into a public key, storing it in @@ -1654,7 +1653,7 @@ card_key_available (ctrl_t ctrl, gcry_sexp_t *r_pk, char **cardsn) } pkbuflen = gcry_sexp_canon_len (pkbuf, 0, NULL, NULL); - err = gcry_sexp_sscan (&s_pk, NULL, pkbuf, pkbuflen); + err = gcry_sexp_sscan (&s_pk, NULL, (char*)pkbuf, pkbuflen); if (err) { log_error ("failed to build S-Exp from received card key: %s\n", @@ -1877,7 +1876,7 @@ ssh_handler_request_identities (ctrl_t ctrl, if (err) goto out; - err = gcry_sexp_sscan (&key_secret, NULL, buffer, buffer_n); + err = gcry_sexp_sscan (&key_secret, NULL, (char*)buffer, buffer_n); if (err) goto out; @@ -1984,14 +1983,14 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned char **sig, size_t *sig_n) { gpg_error_t err; - gcry_sexp_t signature_sexp; - estream_t stream; - gcry_sexp_t valuelist; - gcry_sexp_t sublist; - gcry_mpi_t sig_value; - unsigned char *sig_blob; - size_t sig_blob_n; - char *identifier; + gcry_sexp_t signature_sexp = NULL; + estream_t stream = NULL; + gcry_sexp_t valuelist = NULL; + gcry_sexp_t sublist = NULL; + gcry_mpi_t sig_value = NULL; + unsigned char *sig_blob = NULL;; + size_t sig_blob_n = 0; + char *identifier = NULL; const char *identifier_raw; size_t identifier_n; ssh_key_type_spec_t spec; @@ -1999,17 +1998,10 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, unsigned int i; const char *elems; size_t elems_n; - gcry_mpi_t *mpis; + gcry_mpi_t *mpis = NULL; - signature_sexp = NULL; - identifier = NULL; - valuelist = NULL; - sublist = NULL; - sig_blob = NULL; - sig_blob_n = 0; - stream = NULL; - sig_value = NULL; - mpis = NULL; + *sig = NULL; + *sig_n = 0; ctrl->use_auth_call = 1; err = agent_pksign_do (ctrl, @@ -2119,7 +2111,7 @@ data_sign (ctrl_t ctrl, ssh_signature_encoder_t sig_encoder, if (err) goto out; - *sig = (char *) sig_blob; + *sig = sig_blob; *sig_n = sig_blob_n; out: @@ -2684,7 +2676,7 @@ ssh_request_process (ctrl_t ctrl, estream_t stream_sock) secure memory, since we never give out secret keys. FIXME: This is a pretty good DoS. We only have a limited amount - of secure memory, we can't trhow hin everything we get from a + of secure memory, we can't throw in everything we get from a client -wk */ /* Retrieve request. */ @@ -2824,7 +2816,6 @@ start_command_handler_ssh (int sock_client) struct server_control_s ctrl; estream_t stream_sock; gpg_error_t err; - int bad; int ret; /* Setup control structure. */ @@ -2868,15 +2859,15 @@ start_command_handler_ssh (int sock_client) goto out; } - while (1) - { - bad = ssh_request_process (&ctrl, stream_sock); - if (bad) - break; - }; + /* Main processing loop. */ + while ( !ssh_request_process (&ctrl, stream_sock) ) + ; - out: + /* Reset the SCD in case it has been used. */ + agent_reset_scd (&ctrl); + + out: if (stream_sock) es_fclose (stream_sock); diff --git a/agent/command.c b/agent/command.c index ebf3a8220..c39bcc6ab 100644 --- a/agent/command.c +++ b/agent/command.c @@ -168,7 +168,7 @@ parse_keygrip (ASSUAN_CONTEXT ctx, const char *string, unsigned char *buf) if (n != 20) return set_error (Parameter_Error, "invalid length of keygrip"); - for (p=string, n=0; n < 20; p += 2, n++) + for (p=(const unsigned char*)string, n=0; n < 20; p += 2, n++) buf[n] = xtoi_2 (p); return 0; @@ -494,7 +494,7 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line) init_membuf (&outbuf, 512); - rc = agent_genkey (ctrl, value, valuelen, &outbuf); + rc = agent_genkey (ctrl, (char*)value, valuelen, &outbuf); xfree (value); if (rc) clear_outbuf (&outbuf); diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 41a5dfcda..9d2fa446c 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -139,10 +139,13 @@ static int encode_md_for_card (const unsigned char *digest, size_t digestlen, int algo, unsigned char **r_val, size_t *r_len) { - byte *frame; - byte asn[100]; + unsigned char *frame; + unsigned char asn[100]; size_t asnlen; + *r_val = NULL; + *r_len = 0; + asnlen = DIM(asn); if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) { @@ -295,7 +298,7 @@ divert_pksign (CTRL ctrl, int rc; char *kid; size_t siglen; - char *sigval; + unsigned char *sigval; unsigned char *data; size_t ndata; diff --git a/agent/findkey.c b/agent/findkey.c index 56433c9c4..1cb7efaf3 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -345,7 +345,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) } /* Convert the file into a gcrypt S-expression object. */ - rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); xfree (fname); fclose (fp); xfree (buf); @@ -500,7 +500,7 @@ agent_key_from_file (ctrl_t ctrl, const char *desc_text, } buflen = gcry_sexp_canon_len (buf, 0, NULL, NULL); - rc = gcry_sexp_sscan (&s_skey, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); wipememory (buf, buflen); xfree (buf); if (rc) diff --git a/agent/genkey.c b/agent/genkey.c index e07518d5a..d0319f7b4 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -33,7 +33,7 @@ static int store_key (gcry_sexp_t private, const char *passphrase, int force) { int rc; - char *buf; + unsigned char *buf; size_t len; unsigned char grip[20]; diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 6cc08f845..8732c98d7 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -85,6 +85,7 @@ enum cmd_and_opt_values oDefCacheTTL, oDefCacheTTLSSH, oMaxCacheTTL, + oMaxCacheTTLSSH, oUseStandardSocket, oNoUseStandardSocket, @@ -143,6 +144,7 @@ static ARGPARSE_OPTS opts[] = { N_("|N|expire cached PINs after N seconds")}, { oDefCacheTTLSSH, "default-cache-ttl-ssh", 4, "@" }, { oMaxCacheTTL, "max-cache-ttl", 4, "@" }, + { oMaxCacheTTLSSH, "max-cache-ttl-ssh", 4, "@" }, { oIgnoreCacheForSigning, "ignore-cache-for-signing", 0, N_("do not use the PIN cache when signing")}, { oAllowMarkTrusted, "allow-mark-trusted", 0, @@ -156,8 +158,9 @@ static ARGPARSE_OPTS opts[] = { }; -#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */ -#define MAX_CACHE_TTL (120*60) /* 2 hours */ +#define DEFAULT_CACHE_TTL (10*60) /* 10 minutes */ +#define DEFAULT_CACHE_TTL_SSH (30*60) /* 30 minutes */ +#define MAX_CACHE_TTL (120*60) /* 2 hours */ /* flag to indicate that a shutdown was requested */ @@ -369,8 +372,9 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) opt.pinentry_program = NULL; opt.scdaemon_program = NULL; opt.def_cache_ttl = DEFAULT_CACHE_TTL; - opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL; + opt.def_cache_ttl_ssh = DEFAULT_CACHE_TTL_SSH; opt.max_cache_ttl = MAX_CACHE_TTL; + opt.max_cache_ttl_ssh = MAX_CACHE_TTL; opt.ignore_cache_for_signing = 0; opt.allow_mark_trusted = 0; opt.disable_scdaemon = 0; @@ -407,6 +411,7 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oDefCacheTTL: opt.def_cache_ttl = pargs->r.ret_ulong; break; case oDefCacheTTLSSH: opt.def_cache_ttl_ssh = pargs->r.ret_ulong; break; case oMaxCacheTTL: opt.max_cache_ttl = pargs->r.ret_ulong; break; + case oMaxCacheTTLSSH: opt.max_cache_ttl_ssh = pargs->r.ret_ulong; break; case oIgnoreCacheForSigning: opt.ignore_cache_for_signing = 1; break; diff --git a/agent/minip12.c b/agent/minip12.c index 5ca85033d..31be15373 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -1552,6 +1552,8 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, struct buffer_s seqlist[2]; int seqlistidx = 0; + n = buflen = 0; /* (avoid compiler warning). */ + if (cert && certlen) { /* Encode the certificate. */ diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 42ce69697..1d64c1b15 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -52,7 +52,7 @@ agent_pkdecrypt (CTRL ctrl, const char *desc_text, goto leave; } - rc = gcry_sexp_sscan (&s_cipher, NULL, ciphertext, ciphertextlen); + rc = gcry_sexp_sscan (&s_cipher, NULL, (char*)ciphertext, ciphertextlen); if (rc) { log_error ("failed to convert ciphertext: %s\n", gpg_strerror (rc)); diff --git a/agent/pksign.c b/agent/pksign.c index 2a355e43e..e9df19351 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -117,7 +117,7 @@ agent_pksign_do (ctrl_t ctrl, const char *desc_text, len = gcry_sexp_canon_len (buf, 0, NULL, NULL); assert (len); - rc = gcry_sexp_sscan (&s_sig, NULL, buf, len); + rc = gcry_sexp_sscan (&s_sig, NULL, (char*)buf, len); xfree (buf); if (rc) { diff --git a/agent/protect-tool.c b/agent/protect-tool.c index e8f1d2c10..5f59d5e06 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -239,9 +239,9 @@ make_advanced (const unsigned char *buf, size_t buflen) int rc; size_t erroff, len; gcry_sexp_t sexp; - unsigned char *result; + char *result; - rc = gcry_sexp_sscan (&sexp, &erroff, buf, buflen); + rc = gcry_sexp_sscan (&sexp, &erroff, (const char*)buf, buflen); if (rc) { log_error ("invalid canonical S-Expression (off=%u): %s\n", @@ -378,7 +378,7 @@ read_and_protect (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -417,7 +417,7 @@ read_and_unprotect (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -434,12 +434,13 @@ read_and_shadow (const char *fname) unsigned char *key; unsigned char *result; size_t resultlen; + unsigned char dummy_info[] = "(8:313233342:43)"; key = read_key (fname); if (!key) return; - rc = agent_shadow_key (key, "(8:313233342:43)", &result); + rc = agent_shadow_key (key, dummy_info, &result); xfree (key); if (rc) { @@ -455,7 +456,7 @@ read_and_shadow (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -682,7 +683,7 @@ import_p12_file (const char *fname) if (!buf) return; - kparms = p12_parse (buf, buflen, (pw=get_passphrase (2)), + kparms = p12_parse ((unsigned char*)buf, buflen, (pw=get_passphrase (2)), import_p12_cert_cb, NULL); release_passphrase (pw); xfree (buf); @@ -773,7 +774,7 @@ import_p12_file (const char *fname) xfree (result); if (!p) return; - result = p; + result = (unsigned char*)p; resultlen = strlen (p); } @@ -932,7 +933,7 @@ export_p12_file (const char *fname) if (opt_have_cert) { - cert = read_file ("-", &certlen); + cert = (unsigned char*)read_file ("-", &certlen); if (!cert) { wipememory (key, keylen_for_wipe); @@ -1040,7 +1041,7 @@ percent_plus_unescape (unsigned char *string) static char * percent_plus_unescape_string (char *string) { - unsigned char *p = string; + unsigned char *p = (unsigned char*)string; size_t n; n = percent_plus_unescape (p); diff --git a/agent/protect.c b/agent/protect.c index 658c8c529..45bdae496 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -134,19 +134,22 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) */ static int -do_encryption (const char *protbegin, size_t protlen, +do_encryption (const unsigned char *protbegin, size_t protlen, const char *passphrase, const unsigned char *sha1hash, unsigned char **result, size_t *resultlen) { gcry_cipher_hd_t hd; const char *modestr = "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc"; int blklen, enclen, outlen; - char *iv = NULL; + unsigned char *iv = NULL; int rc; char *outbuf = NULL; char *p; int saltpos, ivpos, encpos; + *resultlen = 0; + *result = NULL; + rc = gcry_cipher_open (&hd, PROT_CIPHER, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); if (rc) @@ -250,7 +253,7 @@ do_encryption (const char *protbegin, size_t protlen, return tmperr; } *resultlen = strlen (p); - *result = p; + *result = (unsigned char*)p; memcpy (p+saltpos, iv+2*blklen, 8); memcpy (p+ivpos, iv, blklen); memcpy (p+encpos, outbuf, enclen); @@ -261,7 +264,7 @@ do_encryption (const char *protbegin, size_t protlen, -/* Protect the key encoded in canonical format in plainkey. We assume +/* Protect the key encoded in canonical format in PLAINKEY. We assume a valid S-Exp here. */ int agent_protect (const unsigned char *plainkey, const char *passphrase, @@ -469,6 +472,9 @@ merge_lists (const unsigned char *protectedkey, const unsigned char *startpos, *endpos; int i, rc; + *result = NULL; + *resultlen = 0; + if (replacepos < 26) return gpg_error (GPG_ERR_BUG); @@ -487,7 +493,7 @@ merge_lists (const unsigned char *protectedkey, return out_of_core (); /* Copy the initial segment */ - strcpy (newlist, "(11:private-key"); + strcpy ((char*)newlist, "(11:private-key"); p = newlist + 15; memcpy (p, protectedkey+15+10, replacepos-15-10); p += replacepos-15-10; @@ -669,7 +675,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, is nothing we should worry about */ if (s[n] != ')' ) return gpg_error (GPG_ERR_INV_SEXP); - s2kcount = strtoul (s, NULL, 10); + s2kcount = strtoul ((const char*)s, NULL, 10); if (!s2kcount) return gpg_error (GPG_ERR_CORRUPTED_PROTECTION); s += n; @@ -838,7 +844,7 @@ unsigned char * make_shadow_info (const char *serialno, const char *idstring) { const char *s; - unsigned char *info, *p; + char *info, *p; char numbuf[21]; int n; @@ -853,13 +859,13 @@ make_shadow_info (const char *serialno, const char *idstring) sprintf (numbuf, "%d:", n); p = stpcpy (p, numbuf); for (s=serialno; *s && s[1]; s += 2) - *p++ = xtoi_2 (s); + *(unsigned char *)p++ = xtoi_2 (s); sprintf (numbuf, "%d:", strlen (idstring)); p = stpcpy (p, numbuf); p = stpcpy (p, idstring); *p++ = ')'; *p = 0; - return info; + return (unsigned char *)info; } @@ -878,7 +884,7 @@ agent_shadow_key (const unsigned char *pubkey, const unsigned char *point; size_t n; int depth = 0; - unsigned char *p; + char *p; size_t pubkey_len = gcry_sexp_canon_len (pubkey, 0, NULL,NULL); size_t shadow_info_len = gcry_sexp_canon_len (shadow_info, 0, NULL,NULL); @@ -930,7 +936,8 @@ agent_shadow_key (const unsigned char *pubkey, /* Calculate required length by taking in account: the "shadowed-" prefix, the "shadowed", "t1-v1" as well as some parenthesis */ n = 12 + pubkey_len + 1 + 3+8 + 2+5 + shadow_info_len + 1; - *result = p = xtrymalloc (n); + *result = xtrymalloc (n); + p = (char*)*result; if (!p) return out_of_core (); p = stpcpy (p, "(20:shadowed-private-key"); diff --git a/agent/query.c b/agent/query.c index c1e4dbacc..b231f6fc3 100644 --- a/agent/query.c +++ b/agent/query.c @@ -58,7 +58,7 @@ static pth_mutex_t entry_lock; struct entry_parm_s { int lines; size_t size; - char *buffer; + unsigned char *buffer; }; @@ -372,7 +372,7 @@ agent_askpin (ctrl_t ctrl, { memset (&parm, 0, sizeof parm); parm.size = pininfo->max_length; - parm.buffer = pininfo->pin; + parm.buffer = (unsigned char*)pininfo->pin; if (errtext) { @@ -444,7 +444,8 @@ agent_get_passphrase (CTRL ctrl, int rc; char line[ASSUAN_LINELENGTH]; struct entry_parm_s parm; - unsigned char *p, *hexstring; + unsigned char *p; + char *hexstring; int i; *retpass = NULL; @@ -497,7 +498,7 @@ agent_get_passphrase (CTRL ctrl, return unlock_pinentry (map_assuan_err (rc)); } - hexstring = gcry_malloc_secure (strlen (parm.buffer)*2+1); + hexstring = gcry_malloc_secure (strlen ((char*)parm.buffer)*2+1); if (!hexstring) { gpg_error_t tmperr = out_of_core (); diff --git a/common/ChangeLog b/common/ChangeLog index 08fb06775..e7905ea58 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,9 +1,33 @@ +2005-06-15 Werner Koch + + * miscellaneous.c (make_printable_string): Made P a void*. + + * sexputil.c (keygrip_from_canon_sexp, cmp_simple_canon_sexp): + Fixed signed/unsigned pointer mismatch. + (make_simple_sexp_from_hexstr): Ditto. This is all too ugly; I + wonder why gcc-4's default is to warn about them and forcing us to + use cast the warning away. + * iobuf.c (block_filter): Ditto. + (iobuf_flush): Ditto. + (iobuf_read_line): Ditto. + (iobuf_read): Make BUFFER a void *. + (iobuf_write): Make BUFFER a const void *. + * ttyio.c (tty_print_utf8_string2): Ditto. + * estream.c (estream_cookie_mem): Make MEMORY unsigned char*. + (es_write): Make BUFFER a void *. + (es_writen): Ditto. + (es_func_fd_read, es_func_fd_write, es_func_mem_read) + (es_func_mem_write): Ditto. + (es_read, es_readn): Ditto. + (es_func_mem_write): Made MEMORY_NEW an unsigned char *. + * estream.h (es_cookie_read_function_t) + (es_cookie_write_function_t): Changed buffer arg to void*. + 2005-06-03 Werner Koch * estream.c: Use HAVE_CONFIG_H and not USE_CONFIG_H! (es_func_fd_read, es_func_fd_write): Protect against EINTR. - 2005-06-01 Werner Koch * Makefile.am (AM_CPPFLAGS): Added. diff --git a/common/estream.c b/common/estream.c index bf5b02001..70b3d9c6e 100644 --- a/common/estream.c +++ b/common/estream.c @@ -294,7 +294,7 @@ es_init_do (void) typedef struct estream_cookie_mem { unsigned int flags; /* Open flags. */ - char *memory; /* Data. */ + unsigned char *memory; /* Data. */ size_t memory_size; /* Size of MEMORY. */ size_t offset; /* Current offset in MEMORY. */ size_t data_len; /* Length of data in MEMORY. */ @@ -350,7 +350,7 @@ es_func_mem_create (void *ES__RESTRICT *ES__RESTRICT cookie, /* Read function for memory objects. */ static ssize_t -es_func_mem_read (void *cookie, char *buffer, size_t size) +es_func_mem_read (void *cookie, void *buffer, size_t size) { estream_cookie_mem_t mem_cookie = cookie; ssize_t ret; @@ -371,11 +371,11 @@ es_func_mem_read (void *cookie, char *buffer, size_t size) /* Write function for memory objects. */ static ssize_t -es_func_mem_write (void *cookie, const char *buffer, size_t size) +es_func_mem_write (void *cookie, const void *buffer, size_t size) { estream_cookie_mem_t mem_cookie = cookie; func_realloc_t func_realloc = mem_cookie->func_realloc; - char *memory_new; + unsigned char *memory_new; size_t newsize; ssize_t ret; int err; @@ -591,7 +591,7 @@ es_func_fd_create (void **cookie, int fd, unsigned int flags) /* Read function for fd objects. */ static ssize_t -es_func_fd_read (void *cookie, char *buffer, size_t size) +es_func_fd_read (void *cookie, void *buffer, size_t size) { estream_cookie_fd_t file_cookie = cookie; @@ -606,7 +606,7 @@ es_func_fd_read (void *cookie, char *buffer, size_t size) /* Write function for fd objects. */ static ssize_t -es_func_fd_write (void *cookie, const char *buffer, size_t size) +es_func_fd_write (void *cookie, const void *buffer, size_t size) { estream_cookie_fd_t file_cookie = cookie; @@ -1122,9 +1122,10 @@ es_read_lbf (estream_t ES__RESTRICT stream, *the amount of bytes read in BYTES_READ. */ static int es_readn (estream_t ES__RESTRICT stream, - unsigned char *ES__RESTRICT buffer, + void *ES__RESTRICT buffer_arg, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) { + unsigned char *buffer = (unsigned char *)buffer_arg; size_t data_read_unread, data_read; int err; @@ -1388,7 +1389,7 @@ es_write_lbf (estream_t ES__RESTRICT stream, amount of bytes written in BYTES_WRITTEN. */ static int es_writen (estream_t ES__RESTRICT stream, - const unsigned char *ES__RESTRICT buffer, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) { size_t data_written; @@ -2289,7 +2290,7 @@ es_ungetc (int c, estream_t stream) int es_read (estream_t ES__RESTRICT stream, - char *ES__RESTRICT buffer, size_t bytes_to_read, + void *ES__RESTRICT buffer, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read) { int err; @@ -2309,7 +2310,7 @@ es_read (estream_t ES__RESTRICT stream, int es_write (estream_t ES__RESTRICT stream, - const char *ES__RESTRICT buffer, size_t bytes_to_write, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written) { int err; diff --git a/common/estream.h b/common/estream.h index c201b666a..ebe575926 100644 --- a/common/estream.h +++ b/common/estream.h @@ -72,9 +72,9 @@ typedef struct es__stream *estream_t; typedef ssize_t (*es_cookie_read_function_t) (void *cookie, - char *buffer, size_t size); + void *buffer, size_t size); typedef ssize_t (*es_cookie_write_function_t) (void *cookie, - const char *buffer, + const void *buffer, size_t size); typedef int (*es_cookie_seek_function_t) (void *cookie, off_t *pos, int whence); @@ -166,10 +166,10 @@ int _es_putc_overflow (int c, estream_t stream); int es_ungetc (int c, estream_t stream); int es_read (estream_t ES__RESTRICT stream, - char *ES__RESTRICT buffer, size_t bytes_to_read, + void *ES__RESTRICT buffer, size_t bytes_to_read, size_t *ES__RESTRICT bytes_read); int es_write (estream_t ES__RESTRICT stream, - const char *ES__RESTRICT buffer, size_t bytes_to_write, + const void *ES__RESTRICT buffer, size_t bytes_to_write, size_t *ES__RESTRICT bytes_written); size_t es_fread (void *ES__RESTRICT ptr, size_t size, size_t nitems, diff --git a/common/iobuf.c b/common/iobuf.c index 52a388514..32b9e18c6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -675,10 +675,11 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, * without a filter */ static int -block_filter (void *opaque, int control, iobuf_t chain, byte * buf, +block_filter (void *opaque, int control, iobuf_t chain, byte * buffer, size_t * ret_len) { block_filter_ctx_t *a = opaque; + char *buf = (char *)buffer; size_t size = *ret_len; int c, needed, rc = 0; char *p; @@ -1762,7 +1763,7 @@ iobuf_flush (iobuf_t a) if (a->use == 3) { /* increase the temp buffer */ - char *newbuf; + unsigned char *newbuf; size_t newsize = a->d.size + 8192; if (DBG_IOBUF) @@ -1829,8 +1830,9 @@ iobuf_readbyte (iobuf_t a) int -iobuf_read (iobuf_t a, byte * buf, unsigned buflen) +iobuf_read (iobuf_t a, void *buffer, unsigned int buflen) { + unsigned char *buf = (unsigned char *)buffer; int c, n; if (a->unget.buf || a->nlimit) @@ -1915,7 +1917,7 @@ iobuf_peek (iobuf_t a, byte * buf, unsigned buflen) int -iobuf_writebyte (iobuf_t a, unsigned c) +iobuf_writebyte (iobuf_t a, unsigned int c) { int rc; @@ -1933,8 +1935,9 @@ iobuf_writebyte (iobuf_t a, unsigned c) int -iobuf_write (iobuf_t a, byte * buf, unsigned buflen) +iobuf_write (iobuf_t a, const void *buffer, unsigned int buflen) { + const unsigned char *buf = (const unsigned char *)buffer; int rc; if (a->directfp) @@ -2311,7 +2314,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, unsigned *length_of_buffer, unsigned *max_length) { int c; - char *buffer = *addr_of_buffer; + char *buffer = (char *)*addr_of_buffer; unsigned length = *length_of_buffer; unsigned nbytes = 0; unsigned maxlen = *max_length; @@ -2321,7 +2324,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, { /* must allocate a new buffer */ length = 256; buffer = xmalloc (length); - *addr_of_buffer = buffer; + *addr_of_buffer = (unsigned char *)buffer; *length_of_buffer = length; } @@ -2344,7 +2347,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, length += 3; /* correct for the reserved byte */ length += length < 1024 ? 256 : 1024; buffer = xrealloc (buffer, length); - *addr_of_buffer = buffer; + *addr_of_buffer = (unsigned char *)buffer; *length_of_buffer = length; length -= 3; /* and reserve again */ p = buffer + nbytes; diff --git a/common/iobuf.h b/common/iobuf.h index 0af94e22d..b991717c2 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -120,12 +120,12 @@ off_t iobuf_tell (iobuf_t a); int iobuf_seek (iobuf_t a, off_t newpos); int iobuf_readbyte (iobuf_t a); -int iobuf_read (iobuf_t a, byte * buf, unsigned buflen); +int iobuf_read (iobuf_t a, void *buf, unsigned buflen); unsigned iobuf_read_line (iobuf_t a, byte ** addr_of_buffer, unsigned *length_of_buffer, unsigned *max_length); int iobuf_peek (iobuf_t a, byte * buf, unsigned buflen); int iobuf_writebyte (iobuf_t a, unsigned c); -int iobuf_write (iobuf_t a, byte * buf, unsigned buflen); +int iobuf_write (iobuf_t a, const void *buf, unsigned buflen); int iobuf_writestr (iobuf_t a, const char *buf); void iobuf_flush_temp (iobuf_t temp); diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 86b0fcb3a..d81213ef9 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -66,7 +66,7 @@ print_utf8_string( FILE *fp, const byte *p, size_t n ) } char * -make_printable_string( const byte *p, size_t n, int delim ) +make_printable_string (const void *p, size_t n, int delim ) { return sanitize_buffer (p, n, delim); } diff --git a/common/sexputil.c b/common/sexputil.c index 802916b44..8a27ad978 100644 --- a/common/sexputil.c +++ b/common/sexputil.c @@ -52,7 +52,7 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, if (!grip) return gpg_error (GPG_ERR_INV_VALUE); - err = gcry_sexp_sscan (&sexp, NULL, key, keylen); + err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen); if (err) return err; if (!gcry_pk_get_keygrip (sexp, grip)) @@ -66,8 +66,11 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, are identical or !0 if they are not. Not that this function can't be used for sorting. */ int -cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b) +cmp_simple_canon_sexp (const unsigned char *a_orig, + const unsigned char *b_orig) { + const char *a = (const char *)a_orig; + const char *b = (const char *)b_orig; unsigned long n1, n2; char *endp; @@ -124,7 +127,7 @@ make_simple_sexp_from_hexstr (const char *line, size_t *nscanned) buf = xtrymalloc (strlen (numbuf) + len + 1 + 1); if (!buf) return NULL; - p = stpcpy (buf, numbuf); + p = (unsigned char *)stpcpy ((char *)buf, numbuf); s = line; if ((n&1)) { diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index 8a027e799..de3689810 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -404,7 +404,7 @@ static char * copy_and_escape (char *buffer, const char *text) { int i; - const unsigned char *s = text; + const unsigned char *s = (unsigned char *)text; char *p = buffer; diff --git a/common/ttyio.c b/common/ttyio.c index eab805e20..5749c59fe 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -322,7 +322,7 @@ tty_print_utf8_string2( const byte *p, size_t n, size_t max_n ) break; } if( i < n ) { - buf = utf8_to_native( p, n, 0 ); + buf = utf8_to_native( (const char *)p, n, 0 ); if( max_n && (strlen( buf ) > max_n )) { buf[max_n] = 0; } diff --git a/common/util.h b/common/util.h index d233dbf5e..1ced59b67 100644 --- a/common/util.h +++ b/common/util.h @@ -153,7 +153,7 @@ const char *print_fname_stdin (const char *s); void print_string (FILE *fp, const byte *p, size_t n, int delim); void print_utf8_string2 ( FILE *fp, const byte *p, size_t n, int delim); void print_utf8_string (FILE *fp, const byte *p, size_t n); -char *make_printable_string (const byte *p, size_t n, int delim); +char *make_printable_string (const void *p, size_t n, int delim); int is_file_compressed (const char *s, int *ret_rc); diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index bad6639e2..144745b4c 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -293,7 +293,7 @@ Set the time a cache entry is valid to @var{n} seconds. The default are @item --default-cache-ttl-ssh @var{n} @opindex default-cache-ttl Set the time a cache entry used for SSH keys is valid to @var{n} -seconds. The default are 600 seconds. +seconds. The default are 1800 seconds. @item --max-cache-ttl @var{n} @opindex max-cache-ttl @@ -301,6 +301,12 @@ Set the maximum time a cache entry is valid to @var{n} seconds. After this time a cache entry will get expired even if it has been accessed recently. The default are 2 hours (7200 seconds). +@item --max-cache-ttl-ssh @var{n} +@opindex max-cache-ttl-ssh +Set the maximum time a cache entry used for SSH keys is valid to @var{n} +seconds. After this time a cache entry will get expired even if it has +been accessed recently. The default are 2 hours (7200 seconds). + @item --pinentry-program @var{filename} @opindex pinentry-program Use program @var{filename} as the PIN entry. The default is installation diff --git a/g10/ChangeLog b/g10/ChangeLog index b33735e1f..0ae73b535 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2005-06-15 Werner Koch + + * g10.c (print_hashline, add_group): Fixes for signed/unsigned + pointer mismatch warnings. + 2005-06-01 Werner Koch * mkdtemp.c: Removed. diff --git a/g10/g10.c b/g10/g10.c index 0be5636a2..234d13f41 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -933,7 +933,7 @@ static void add_group(char *string) return; } - trim_trailing_ws(name,strlen(name)); + trim_trailing_ws((unsigned char *)name,strlen(name)); /* Break apart the values */ while ((value= strsep(&string," \t"))) @@ -3124,7 +3124,7 @@ print_hashline( MD_HANDLE md, int algo, const char *fname ) const byte *p; if ( fname ) { - for (p = fname; *p; p++ ) { + for (p = (const unsigned char *)fname; *p; p++ ) { if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) printf("%%%02X", *p ); else diff --git a/g10/misc.c b/g10/misc.c index 7012a8a25..516e80bcc 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -986,9 +986,10 @@ mpi_print( FILE *fp, gcry_mpi_t a, int mode ) } else { int rc; - unsigned char *buffer; + char *buffer; - rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a ); + rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, + &(unsigned char*)buffer, NULL, a ); assert( !rc ); fputs( buffer, fp ); n += strlen(buffer); diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index f308a7ea3..f0463c5b3 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,16 @@ +2005-06-15 Werner Koch + + * stringhelp.c (sanitize_buffer): Make P a void*. + (ascii_memistr, memistr): Ditto. + (ascii_memcasecmp): Ditto. + * logging.c (writen): Use void * for arg BUFFER. + * stringhelp.c (memistr): Fixed unsigned/signed pointer conflict. + (ascii_memistr): Ditto. + (ascii_memcasemem): Ditto. + * utf8conv.c (utf8_to_native): Ditto. + (utf8_to_native): Ditto. + * argparse.c (show_version): Removed non-required cast. + 2005-01-19 Werner Koch * logging.c (fun_writer): Don't fallback to stderr. Print to diff --git a/jnlib/argparse.c b/jnlib/argparse.c index 485c60786..980d1186c 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -852,7 +852,7 @@ show_version() /* additional program info */ for(i=30; i < 40; i++ ) if( (s=strusage(i)) ) - fputs( (const byte*)s, stdout); + fputs (s, stdout); fflush(stdout); } diff --git a/jnlib/logging.c b/jnlib/logging.c index 97a2b9c9e..c944006a5 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -87,10 +87,11 @@ struct fun_cookie_s { char name[1]; }; -/* Write NBYTES of BUF to file descriptor FD. */ +/* Write NBYTES of BUFFER to file descriptor FD. */ static int -writen (int fd, const unsigned char *buf, size_t nbytes) +writen (int fd, const void *buffer, size_t nbytes) { + const char *buf = buffer; size_t nleft = nbytes; int nwritten; diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index 5a3b41528..760398b0c 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -1,6 +1,6 @@ /* stringhelp.c - standard string helper functions * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004 Free Software Foundation, Inc. + * 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -35,45 +35,57 @@ /* * Look for the substring SUB in buffer and return a pointer to that - * substring in BUF or NULL if not found. + * substring in BUFFER or NULL if not found. * Comparison is case-insensitive. */ const char * -memistr( const char *buf, size_t buflen, const char *sub ) +memistr (const void *buffer, size_t buflen, const char *sub) { - const byte *t, *s ; - size_t n; + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buffer; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( toupper(*t) == toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && toupper(*t) == toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; + for ( ; n ; t++, n-- ) + { + if ( toupper (*t) == toupper (*s) ) + { + for ( buf=t++, buflen = n--, s++; + n && toupper (*t) == toupper (*s); t++, s++, n-- ) + ; + if (!*s) + return (const char*)buf; + t = buf; + s = (const unsigned char *)sub ; + n = buflen; } - - return NULL ; + } + return NULL; } const char * -ascii_memistr( const char *buf, size_t buflen, const char *sub ) +ascii_memistr ( const void *buffer, size_t buflen, const char *sub ) { - const byte *t, *s ; - size_t n; + const unsigned char *buf = buffer; + const unsigned char *t = (const unsigned char *)buf; + const unsigned char *s = (const unsigned char *)sub; + size_t n = buflen; - for( t=buf, n=buflen, s=sub ; n ; t++, n-- ) - if( ascii_toupper(*t) == ascii_toupper(*s) ) { - for( buf=t++, buflen = n--, s++; - n && ascii_toupper(*t) == ascii_toupper(*s); t++, s++, n-- ) - ; - if( !*s ) - return buf; - t = buf; n = buflen; s = sub ; + for ( ; n ; t++, n-- ) + { + if (ascii_toupper (*t) == ascii_toupper (*s) ) + { + for ( buf=t++, buflen = n--, s++; + n && ascii_toupper (*t) == ascii_toupper (*s); t++, s++, n-- ) + ; + if (!*s) + return (const char*)buf; + t = (const unsigned char *)buf; + s = (const unsigned char *)sub ; + n = buflen; } - - return NULL ; + } + return NULL; } /* This function is similar to strncpy(). However it won't copy more @@ -402,13 +414,14 @@ print_sanitized_utf8_string (FILE *fp, const char *string, int delim) delim) : 0; } -/* Create a string from the buffer P of length N which is suitable for +/* Create a string from the buffer P_ARG of length N which is suitable for printing. Caller must release the created string using xfree. */ char * -sanitize_buffer (const unsigned char *p, size_t n, int delim) +sanitize_buffer (const void *p_arg, size_t n, int delim) { + const unsigned char *p = p_arg; size_t save_n, buflen; - const byte *save_p; + const unsigned char *save_p; char *buffer, *d; /* first count length */ @@ -552,15 +565,19 @@ ascii_strncasecmp (const char *a, const char *b, size_t n) int -ascii_memcasecmp( const char *a, const char *b, size_t n ) +ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n ) { - if (a == b) - return 0; - for ( ; n; n--, a++, b++ ) { - if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) - return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); - } + const char *a = a_arg; + const char *b = b_arg; + + if (a == b) return 0; + for ( ; n; n--, a++, b++ ) + { + if( *a != *b && ascii_toupper (*a) != ascii_toupper (*b) ) + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); + } + return 0; } int @@ -586,8 +603,8 @@ ascii_memcasemem (const void *haystack, size_t nhaystack, return (void*)haystack; /* finding an empty needle is really easy */ if (nneedle <= nhaystack) { - const unsigned char *a = haystack; - const unsigned char *b = a + nhaystack - nneedle; + const char *a = haystack; + const char *b = a + nhaystack - nneedle; for (; a <= b; a++) { diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 412da3a0e..bdd7d561c 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -23,7 +23,7 @@ #include "types.h" -const char *memistr( const char *buf, size_t buflen, const char *sub ); +const char *memistr (const void *buf, size_t buflen, const char *sub); char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); char *trim_trailing_spaces( char *string ); @@ -46,7 +46,7 @@ size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim); size_t print_sanitized_string (FILE *fp, const char *string, int delim); size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); -char *sanitize_buffer (const unsigned char *p, size_t n, int delim); +char *sanitize_buffer (const void *p, size_t n, int delim); #ifdef HAVE_W32_SYSTEM @@ -54,15 +54,14 @@ const char *w32_strerror (int ec); #endif -const char *ascii_memistr( const char *buf, size_t buflen, const char *sub ); int ascii_isupper (int c); int ascii_islower (int c); int ascii_toupper (int c); int ascii_tolower (int c); int ascii_strcasecmp( const char *a, const char *b ); int ascii_strncasecmp (const char *a, const char *b, size_t n); -int ascii_memcasecmp( const char *a, const char *b, size_t n ); -const char *ascii_memistr ( const char *buf, size_t buflen, const char *sub); +int ascii_memcasecmp( const void *a, const void *b, size_t n ); +const char *ascii_memistr ( const void *buf, size_t buflen, const char *sub); void *ascii_memcasemem (const void *haystack, size_t nhaystack, const void *needle, size_t nneedle); diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c index 691176766..4df8b7b32 100644 --- a/jnlib/utf8conv.c +++ b/jnlib/utf8conv.c @@ -136,16 +136,17 @@ get_native_charset () * new allocated UTF8 string. */ char * -native_to_utf8 (const char *string) +native_to_utf8 (const char *orig_string) { - const byte *s; + const unsigned char *string = (const unsigned char *)orig_string; + const unsigned char *s; char *buffer; - byte *p; + unsigned char *p; size_t length = 0; if (no_translation) { - buffer = jnlib_xstrdup (string); + buffer = jnlib_xstrdup (orig_string); } else if (active_charset) { @@ -156,7 +157,7 @@ native_to_utf8 (const char *string) length += 2; /* we may need 3 bytes */ } buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) + for (p = (unsigned char *)buffer, s = string; *s; s++) { if ((*s & 0x80)) { @@ -187,7 +188,7 @@ native_to_utf8 (const char *string) length++; } buffer = jnlib_xmalloc (length + 1); - for (p = buffer, s = string; *s; s++) + for (p = (unsigned char *)buffer, s = string; *s; s++) { if (*s & 0x80) { @@ -212,11 +213,12 @@ utf8_to_native (const char *string, size_t length, int delim) { int nleft; int i; - byte encbuf[8]; + unsigned char encbuf[8]; int encidx; const byte *s; size_t n; - byte *buffer = NULL, *p = NULL; + char *buffer = NULL; + char *p = NULL; unsigned long val = 0; size_t slen; int resync = 0; @@ -225,7 +227,8 @@ utf8_to_native (const char *string, size_t length, int delim) /* 2. pass (p!=NULL): create string */ for (;;) { - for (slen = length, nleft = encidx = 0, n = 0, s = string; slen; + for (slen = length, nleft = encidx = 0, n = 0, + s = (const unsigned char *)string; slen; s++, slen--) { if (resync) diff --git a/kbx/ChangeLog b/kbx/ChangeLog index 7c112085c..4fd06d5ca 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -1,3 +1,14 @@ +2005-06-15 Werner Koch + + * keybox-file.c (_keybox_read_blob2): Make IMAGE unsigned. + (_keybox_write_blob): + + * keybox-blob.c (create_blob_finish, _keybox_create_x509_blob): + Fixed warnings about signed/unsigned pointer mismatches. + (x509_email_kludge): Ditto. + (_keybox_new_blob): Changed arg IMAGE to unsigned char *. + (_keybox_get_blob_image): Changed return type to unsigned char*. + 2005-06-01 Werner Koch * keybox-file.c (ftello) [!HAVE_FSEEKO]: New replacement diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 7fe6178d6..0569b5a67 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -386,7 +386,7 @@ import_openpgp (const char *filename) buffer = read_file (filename, &buflen); if (!buffer) return; - p = buffer; + p = (unsigned char *)buffer; for (;;) { err = _keybox_parse_openpgp (p, buflen, &nparsed, &info); diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 48bce28e2..67c74b777 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -646,8 +646,8 @@ static int create_blob_finish (KEYBOXBLOB blob) { struct membuf *a = blob->buf; - byte *p; - char *pp; + unsigned char *p; + unsigned char *pp; int i; size_t n; @@ -656,6 +656,7 @@ create_blob_finish (KEYBOXBLOB blob) put32 (a, 0); /* Hmmm: why put32() ?? */ /* get the memory area */ + n = 0; /* (Just to avoid compiler warning.) */ p = get_membuf (a, &n); if (!p) return gpg_error (GPG_ERR_ENOMEM); @@ -783,7 +784,7 @@ _keybox_create_pgp_blob (KEYBOXBLOB *r_blob, KBNODE keyblock, int as_ephemeral) static char * x509_email_kludge (const char *name) { - const unsigned char *p; + const char *p; unsigned char *buf; int n; @@ -805,7 +806,7 @@ x509_email_kludge (const char *name) buf[n] = xtoi_2 (p); buf[n++] = '>'; buf[n] = 0; - return buf; + return (char *)buf; } @@ -818,8 +819,9 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, { int i, rc = 0; KEYBOXBLOB blob; - unsigned char *p; - unsigned char **names = NULL; + unsigned char *sn; + char *p; + char **names = NULL; size_t max_names; *r_blob = NULL; @@ -827,28 +829,28 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, if( !blob ) return gpg_error (gpg_err_code_from_errno (errno)); - p = ksba_cert_get_serial (cert); - if (p) + sn = ksba_cert_get_serial (cert); + if (sn) { size_t n, len; - n = gcry_sexp_canon_len (p, 0, NULL, NULL); + n = gcry_sexp_canon_len (sn, 0, NULL, NULL); if (n < 2) { - xfree (p); + xfree (sn); return gpg_error (GPG_ERR_GENERAL); } - blob->serialbuf = p; - p++; n--; /* skip '(' */ - for (len=0; n && *p && *p != ':' && digitp (p); n--, p++) - len = len*10 + atoi_1 (p); - if (*p != ':') + blob->serialbuf = sn; + sn++; n--; /* skip '(' */ + for (len=0; n && *sn && *sn != ':' && digitp (sn); n--, sn++) + len = len*10 + atoi_1 (sn); + if (*sn != ':') { xfree (blob->serialbuf); blob->serialbuf = NULL; return gpg_error (GPG_ERR_GENERAL); } - p++; - blob->serial = p; + sn++; + blob->serial = sn; blob->seriallen = len; } @@ -863,6 +865,7 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, rc = gpg_error (gpg_err_code_from_errno (errno)); goto leave; } + p = ksba_cert_get_issuer (cert, 0); if (!p) { @@ -872,10 +875,9 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, names[blob->nuids++] = p; for (i=0; (p = ksba_cert_get_subject (cert, i)); i++) { - if (blob->nuids >= max_names) { - unsigned char **tmp; + char **tmp; max_names += 100; tmp = xtryrealloc (names, max_names * sizeof *names); @@ -964,7 +966,8 @@ _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, int -_keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, off_t off) +_keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, off_t off) { KEYBOXBLOB blob; @@ -1000,7 +1003,7 @@ _keybox_release_blob (KEYBOXBLOB blob) -const char * +const unsigned char * _keybox_get_blob_image ( KEYBOXBLOB blob, size_t *n ) { *n = blob->bloblen; diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index b58294459..7bbed8519 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -140,10 +140,11 @@ int _keybox_create_x509_blob (KEYBOXBLOB *r_blob, ksba_cert_t cert, unsigned char *sha1_digest, int as_ephemeral); #endif /*KEYBOX_WITH_X509*/ -int _keybox_new_blob (KEYBOXBLOB *r_blob, char *image, size_t imagelen, +int _keybox_new_blob (KEYBOXBLOB *r_blob, + unsigned char *image, size_t imagelen, off_t off); void _keybox_release_blob (KEYBOXBLOB blob); -const char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); +const unsigned char *_keybox_get_blob_image (KEYBOXBLOB blob, size_t *n); off_t _keybox_get_blob_fileoffset (KEYBOXBLOB blob); void _keybox_update_header_blob (KEYBOXBLOB blob); diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index fe02c1f9f..3883ce607 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -48,7 +48,7 @@ ftello (FILE *stream) int _keybox_read_blob2 (KEYBOXBLOB *r_blob, FILE *fp, int *skipped_deleted) { - char *image; + unsigned char *image; size_t imagelen = 0; int c1, c2, c3, c4, type; int rc; @@ -118,7 +118,7 @@ _keybox_read_blob (KEYBOXBLOB *r_blob, FILE *fp) int _keybox_write_blob (KEYBOXBLOB blob, FILE *fp) { - const char *image; + const unsigned char *image; size_t length; image = _keybox_get_blob_image (blob, &length); diff --git a/scd/apdu.c b/scd/apdu.c index 212b9df24..975fffa24 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -2393,7 +2393,7 @@ apdu_activate (int slot) unsigned char * apdu_get_atr (int slot, size_t *atrlen) { - char *buf; + unsigned char *buf; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return NULL; diff --git a/scd/app-help.c b/scd/app-help.c index 1c3c52b15..27cbea5c7 100644 --- a/scd/app-help.c +++ b/scd/app-help.c @@ -48,7 +48,7 @@ app_help_get_keygrip_string (ksba_cert_t cert, char *hexkeygrip) n = gcry_sexp_canon_len (p, 0, NULL, NULL); if (!n) return gpg_error (GPG_ERR_INV_SEXP); - err = gcry_sexp_sscan (&s_pkey, NULL, p, n); + err = gcry_sexp_sscan (&s_pkey, NULL, (char*)p, n); xfree (p); if (err) return err; /* Can't parse that S-expression. */ diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 1ff096138..11e6eebaf 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -948,8 +948,8 @@ get_public_key (app_t app, int keyno) size_t buflen, keydatalen, mlen, elen; unsigned char *mbuf = NULL; unsigned char *ebuf = NULL; - unsigned char *keybuf = NULL; - unsigned char *keybuf_p; + char *keybuf = NULL; + char *keybuf_p; if (keyno < 1 || keyno > 3) return gpg_error (GPG_ERR_INV_ID); @@ -963,14 +963,16 @@ get_public_key (app_t app, int keyno) app->app_local->pk[keyno].key = NULL; app->app_local->pk[keyno].keylen = 0; + m = e = NULL; /* (avoid cc warning) */ + if (app->card_version > 0x0100) { /* We may simply read the public key out of these cards. */ - err = iso7816_read_public_key (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); + err = iso7816_read_public_key + (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), + 2, + &buffer, &buflen); if (err) { log_error (_("reading public key failed: %s\n"), gpg_strerror (err)); @@ -1107,7 +1109,7 @@ get_public_key (app_t app, int keyno) strcpy (keybuf_p, ")))"); keybuf_p += strlen (keybuf_p); - app->app_local->pk[keyno].key = keybuf; + app->app_local->pk[keyno].key = (unsigned char*)keybuf; app->app_local->pk[keyno].keylen = (keybuf_p - keybuf); leave: @@ -1889,11 +1891,10 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags, #warning key generation temporary replaced by reading an existing key. rc = iso7816_read_public_key #endif - (app->slot, - keyno == 0? "\xB6" : - keyno == 1? "\xB8" : "\xA4", - 2, - &buffer, &buflen); + (app->slot, (const unsigned char*)(keyno == 0? "\xB6" : + keyno == 1? "\xB8" : "\xA4"), + 2, + &buffer, &buflen); if (rc) { rc = gpg_error (GPG_ERR_CARD); diff --git a/scd/app-p15.c b/scd/app-p15.c index 831f0d1f4..f03e5d5f0 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -43,33 +43,35 @@ typedef enum } card_type_t; /* A list card types with ATRs noticed with these cards. */ +#define X(a) ((unsigned char const *)(a)) static struct { size_t atrlen; - unsigned char *atr; + unsigned char const *atr; card_type_t type; } card_atr_list[] = { - { 19, "\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80" - "\x90\x00\x8B", + { 19, X("\x3B\xBA\x13\x00\x81\x31\x86\x5D\x00\x64\x05\x0A\x02\x01\x31\x80" + "\x90\x00\x8B"), CARD_TYPE_TCOS }, /* SLE44 */ - { 19, "\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80" - "\x90\x00\x91", + { 19, X("\x3B\xBA\x14\x00\x81\x31\x86\x5D\x00\x64\x05\x14\x02\x02\x31\x80" + "\x90\x00\x91"), CARD_TYPE_TCOS }, /* SLE66S */ - { 19, "\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80" - "\x90\x00\x66", + { 19, X("\x3B\xBA\x96\x00\x81\x31\x86\x5D\x00\x64\x05\x60\x02\x03\x31\x80" + "\x90\x00\x66"), CARD_TYPE_TCOS }, /* SLE66P */ - { 27, "\x3B\xFF\x94\x00\xFF\x80\xB1\xFE\x45\x1F\x03\x00\x68\xD2\x76\x00" - "\x00\x28\xFF\x05\x1E\x31\x80\x00\x90\x00\x23", + { 27, X("\x3B\xFF\x94\x00\xFF\x80\xB1\xFE\x45\x1F\x03\x00\x68\xD2\x76\x00" + "\x00\x28\xFF\x05\x1E\x31\x80\x00\x90\x00\x23"), CARD_TYPE_MICARDO }, /* German BMI card */ - { 19, "\x3B\x6F\x00\xFF\x00\x68\xD2\x76\x00\x00\x28\xFF\x05\x1E\x31\x80" - "\x00\x90\x00", + { 19, X("\x3B\x6F\x00\xFF\x00\x68\xD2\x76\x00\x00\x28\xFF\x05\x1E\x31\x80" + "\x00\x90\x00"), CARD_TYPE_MICARDO }, /* German BMI card (ATR due to reader problem) */ - { 26, "\x3B\xFE\x94\x00\xFF\x80\xB1\xFA\x45\x1F\x03\x45\x73\x74\x45\x49" - "\x44\x20\x76\x65\x72\x20\x31\x2E\x30\x43", + { 26, X("\x3B\xFE\x94\x00\xFF\x80\xB1\xFA\x45\x1F\x03\x45\x73\x74\x45\x49" + "\x44\x20\x76\x65\x72\x20\x31\x2E\x30\x43"), CARD_TYPE_MICARDO }, /* EstEID (Estonian Big Brother card) */ { 0 } }; +#undef X /* The Pin Types as defined in pkcs#15 v1.1 */ diff --git a/scd/app.c b/scd/app.c index 2c8c915d7..f27b400b1 100644 --- a/scd/app.c +++ b/scd/app.c @@ -357,7 +357,7 @@ app_munge_serialno (app_t app) gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp) { - unsigned char *buf, *p; + char *buf, *p; int i; if (!app || !serial) diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 9ac655e63..096a6811b 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -555,7 +555,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, all in a 2 bute Unicode encoding using little endian. */ rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8), 0, - buf, sizeof buf, 1000 /* ms timeout */); + (char*)buf, sizeof buf, 1000 /* ms timeout */); if (rc < 4) langid = 0x0409; /* English. */ else @@ -563,7 +563,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx, rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + idx, langid, - buf, sizeof buf, 1000 /* ms timeout */); + (char*)buf, sizeof buf, 1000 /* ms timeout */); if (rc < 2 || buf[1] != USB_DT_STRING) return NULL; /* Error or not a string. */ len = buf[0]; @@ -1155,7 +1155,7 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen) rc = usb_bulk_write (handle->idev, handle->ep_bulk_out, - msg, msglen, + (char*)msg, msglen, 1000 /* ms timeout */); if (rc == msglen) return 0; @@ -1188,7 +1188,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, retry: rc = usb_bulk_read (handle->idev, handle->ep_bulk_in, - buffer, length, + (char*)buffer, length, timeout); if (rc < 0) { @@ -1300,7 +1300,7 @@ ccid_poll (ccid_driver_t handle) rc = usb_bulk_read (handle->idev, handle->ep_intr, - msg, sizeof msg, + (char*)msg, sizeof msg, 0 /* ms timeout */ ); if (rc < 0 && errno == ETIMEDOUT) return 0; @@ -1444,7 +1444,7 @@ ccid_get_atr (ccid_driver_t handle, { tried_iso = 1; /* Try switching to ISO mode. */ - if (!send_escape_cmd (handle, "\xF1\x01", 2)) + if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2)) goto again; } else if (CCID_COMMAND_FAILED (msg)) @@ -2026,7 +2026,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_vendor == VENDOR_SCM) { DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n"); - rc = send_escape_cmd (handle, "\x80\x02\x00", 3); + rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3); if (rc) return rc; } diff --git a/scd/command.c b/scd/command.c index a308078d3..52a86871e 100644 --- a/scd/command.c +++ b/scd/command.c @@ -679,7 +679,7 @@ pin_cb (void *opaque, const char *info, char **retstr) xfree (value); return gpg_error (GPG_ERR_INV_RESPONSE); } - *retstr = value; + *retstr = (char*)value; return 0; } @@ -844,7 +844,7 @@ cmd_getattr (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; - char *keyword; + const char *keyword; if ((rc = open_card (ctrl, NULL))) return rc; @@ -860,7 +860,6 @@ cmd_getattr (assuan_context_t ctx, char *line) /* FIXME: Applications should not return sensistive data if the card is locked. */ rc = app_getattr (ctrl->app_ctx, ctrl, keyword); - xfree (keyword); TEST_CARD_REMOVAL (ctrl, rc); return map_to_assuan_status (rc); @@ -908,9 +907,10 @@ cmd_setattr (assuan_context_t ctx, char *orig_line) *line++ = 0; while (spacep (line)) line++; - nbytes = percent_plus_unescape (line); + nbytes = percent_plus_unescape ((unsigned char*)line); - rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes); + rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, + (const unsigned char*)line, nbytes); xfree (linebuf); TEST_CARD_REMOVAL (ctrl, rc); diff --git a/scd/iso7816.c b/scd/iso7816.c index e9dc6541c..742ed9433 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -153,7 +153,7 @@ iso7816_select_file (int slot, int tag, int is_dir, p0 = (tag == 0x3F00)? 0: is_dir? 1:2; p1 = 0x0c; /* No FC return. */ sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, - p0, p1, 2, tagbuf ); + p0, p1, 2, (char*)tagbuf ); return map_sw (sw); } @@ -285,7 +285,7 @@ iso7816_put_data (int slot, int tag, sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA, ((tag >> 8) & 0xff), (tag & 0xff), - datalen, data); + datalen, (const char*)data); return map_sw (sw); } @@ -303,7 +303,7 @@ iso7816_manage_security_env (int slot, int p1, int p2, return gpg_error (GPG_ERR_INV_VALUE); sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, - data? datalen : -1, data); + data? datalen : -1, (const char*)data); return map_sw (sw); } @@ -323,7 +323,7 @@ iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen, *result = NULL; *resultlen = 0; - sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, data, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { @@ -364,13 +364,15 @@ iso7816_decipher (int slot, const unsigned char *data, size_t datalen, *buf = padind; /* Padding indicator. */ memcpy (buf+1, data, datalen); - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen+1, buf, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, + datalen+1, (char*)buf, result, resultlen); xfree (buf); } else { - sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, datalen, data, + sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86, + datalen, (const char *)data, result, resultlen); } if (sw != SW_SUCCESS) @@ -399,7 +401,7 @@ iso7816_internal_authenticate (int slot, *resultlen = 0; sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, - datalen, data, result, resultlen); + datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ @@ -426,7 +428,7 @@ do_generate_keypair (int slot, int readonly, *resultlen = 0; sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0, - datalen, data, result, resultlen); + datalen, (const char*)data, result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ diff --git a/scd/pcsc-wrapper.c b/scd/pcsc-wrapper.c index 93e78fdfe..21af16fba 100644 --- a/scd/pcsc-wrapper.c +++ b/scd/pcsc-wrapper.c @@ -390,9 +390,9 @@ handle_open (unsigned char *argbuf, size_t arglen) unsigned char atr[33]; /* Make sure there is only the port string */ - if (arglen != strlen (argbuf)) + if (arglen != strlen ((char*)argbuf)) bad_request ("OPEN"); - portstr = argbuf; + portstr = (char*)argbuf; if (driver_is_open) { diff --git a/sm/ChangeLog b/sm/ChangeLog index ffb61a294..d9f295e1d 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,35 @@ +2005-06-15 Werner Koch + + * delete.c (delete_one): Changed FPR to unsigned. + * encrypt.c (encrypt_dek): Made ENCVAL unsigned. + (gpgsm_encrypt): Ditto. + * sign.c (gpgsm_sign): Made SIGVAL unsigned. + * base64.c (base64_reader_cb): Need to use some casting to get + around signed/unsigned char* warnings. + * certcheck.c (gpgsm_check_cms_signature): Ditto. + (gpgsm_create_cms_signature): Changed arg R_SIGVAL to unsigned char*. + (do_encode_md): Made NFRAME a size_t. + * certdump.c (gpgsm_print_serial): Fixed signed/unsigned warning. + (gpgsm_dump_serial): Ditto. + (gpgsm_format_serial): Ditto. + (gpgsm_dump_string): Ditto. + (gpgsm_dump_cert): Ditto. + (parse_dn_part): Ditto. + (gpgsm_print_name2): Ditto. + * keylist.c (email_kludge): Ditto. + * certreqgen.c (proc_parameters, create_request): Ditto. + (create_request): Ditto. + * call-agent.c (gpgsm_agent_pksign): Made arg R_BUF unsigned. + (struct cipher_parm_s): Made CIPHERTEXT unsigned. + (struct genkey_parm_s): Ditto. + * server.c (strcpy_escaped_plus): Made arg S signed char*. + * fingerprint.c (gpgsm_get_fingerprint): Made ARRAY unsigned. + (gpgsm_get_keygrip): Ditto. + * keydb.c (keydb_insert_cert): Made DIGEST unsigned. + (keydb_update_cert): Ditto. + (classify_user_id): Apply cast to signed/unsigned assignment. + (hextobyte): Ditto. + 2005-06-01 Werner Koch * misc.c: Include setenv.h. diff --git a/sm/base64.c b/sm/base64.c index 4cc6ffa27..62c2c9ad9 100644 --- a/sm/base64.c +++ b/sm/base64.c @@ -95,7 +95,7 @@ struct base64_context_s { /* The base-64 character list */ -static unsigned char bintoasc[64] = +static char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; @@ -202,8 +202,9 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) { /* wait for the header line */ parm->linelen = parm->readpos = 0; - if (!parm->have_lf || strncmp (parm->line, "-----BEGIN ", 11) - || !strncmp (parm->line+11, "PGP ", 4)) + if (!parm->have_lf + || strncmp ((char*)parm->line, "-----BEGIN ", 11) + || !strncmp ((char*)parm->line+11, "PGP ", 4)) goto next; parm->is_pem = 1; } @@ -220,8 +221,9 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) /* the very first byte does pretty much look like a SEQUENCE tag*/ parm->is_pem = 0; } - else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11) - && strncmp (parm->line+11, "PGP ", 4) ) + else if ( parm->have_lf + && !strncmp ((char*)parm->line, "-----BEGIN ", 11) + && strncmp ((char *)parm->line+11, "PGP ", 4) ) { /* Fixme: we must only compare if the line really starts at the beginning */ @@ -268,7 +270,7 @@ base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread) if (parm->is_pem || parm->is_base64) { if (parm->is_pem && parm->have_lf - && !strncmp (parm->line, "-----END ", 9)) + && !strncmp ((char*)parm->line, "-----END ", 9)) { parm->identified = 0; parm->linelen = parm->readpos = 0; diff --git a/sm/call-agent.c b/sm/call-agent.c index 885abf421..92a29928c 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -39,24 +39,27 @@ #include "../common/membuf.h" -static ASSUAN_CONTEXT agent_ctx = NULL; +static assuan_context_t agent_ctx = NULL; static int force_pipe_server = 0; -struct cipher_parm_s { - ASSUAN_CONTEXT ctx; - const char *ciphertext; +struct cipher_parm_s +{ + assuan_context_t ctx; + const unsigned char *ciphertext; size_t ciphertextlen; }; -struct genkey_parm_s { - ASSUAN_CONTEXT ctx; - const char *sexp; +struct genkey_parm_s +{ + assuan_context_t ctx; + const unsigned char *sexp; size_t sexplen; }; -struct learn_parm_s { +struct learn_parm_s +{ int error; - ASSUAN_CONTEXT ctx; + assuan_context_t ctx; membuf_t *data; }; @@ -204,7 +207,7 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length) int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen ) + unsigned char **r_buf, size_t *r_buflen ) { int rc, i; char *p, line[ASSUAN_LINELENGTH]; @@ -392,7 +395,7 @@ gpgsm_agent_genkey (ctrl_t ctrl, struct genkey_parm_s gk_parm; membuf_t data; size_t len; - char *buf; + unsigned char *buf; *r_pubkey = NULL; rc = start_agent (ctrl); diff --git a/sm/certcheck.c b/sm/certcheck.c index 611d3219c..84dfdb9ab 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -39,7 +39,8 @@ static int do_encode_md (gcry_md_hd_t md, int algo, int pkalgo, unsigned int nbits, gcry_mpi_t *r_val) { - int n, nframe; + int n; + size_t nframe; unsigned char *frame; if (pkalgo == GCRY_PK_DSA) @@ -205,7 +206,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) log_printf ("\n"); } - rc = gcry_sexp_sscan ( &s_sig, NULL, p, n); + rc = gcry_sexp_sscan ( &s_sig, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -224,7 +225,7 @@ gpgsm_check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) gcry_sexp_release (s_sig); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -278,7 +279,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, log_error ("libksba did not return a proper S-Exp\n"); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan (&s_sig, NULL, sigval, n); + rc = gcry_sexp_sscan (&s_sig, NULL, (char*)sigval, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); @@ -297,7 +298,7 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, if (DBG_CRYPTO) log_printhex ("public key: ", p, n); - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); ksba_free (p); if (rc) { @@ -333,7 +334,8 @@ gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, int gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, - gcry_md_hd_t md, int mdalgo, char **r_sigval) + gcry_md_hd_t md, int mdalgo, + unsigned char **r_sigval) { int rc; char *grip, *desc; diff --git a/sm/certdump.c b/sm/certdump.c index 26510c70d..98f019c4a 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -50,8 +50,9 @@ struct dn_array_s { /* print the first element of an S-Expression */ void -gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) +gpgsm_print_serial (FILE *fp, ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; @@ -77,8 +78,9 @@ gpgsm_print_serial (FILE *fp, ksba_const_sexp_t p) /* Dump the serial number or any other simple S-expression. */ void -gpgsm_dump_serial (ksba_const_sexp_t p) +gpgsm_dump_serial (ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; @@ -103,8 +105,9 @@ gpgsm_dump_serial (ksba_const_sexp_t p) char * -gpgsm_format_serial (ksba_const_sexp_t p) +gpgsm_format_serial (ksba_const_sexp_t sn) { + const char *p = (const char *)sn; unsigned long n; char *endp; char *buffer; @@ -168,7 +171,7 @@ gpgsm_dump_string (const char *string) { const unsigned char *s; - for (s=string; *s; s++) + for (s=(const unsigned char*)string; *s; s++) { if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) break; @@ -190,7 +193,7 @@ void gpgsm_dump_cert (const char *text, ksba_cert_t cert) { ksba_sexp_t sexp; - unsigned char *p; + char *p; char *dn; ksba_isotime_t t; @@ -260,7 +263,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) }; const unsigned char *s, *s1; size_t n; - unsigned char *p; + char *p; int i; /* Parse attributeType */ @@ -306,7 +309,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) return NULL; for (s1=string; n; s1 += 2, n--, p++) { - *p = xtoi_2 (s1); + *(unsigned char *)p = xtoi_2 (s1); if (!*p) *p = 0x01; /* Better print a wrong value than truncating the string. */ @@ -351,7 +354,7 @@ parse_dn_part (struct dn_array_s *array, const unsigned char *string) s++; if (hexdigitp (s)) { - *p++ = xtoi_2 (s); + *(unsigned char *)p++ = xtoi_2 (s); s++; } else @@ -485,23 +488,22 @@ print_dn_parts (FILE *fp, struct dn_array_s *dn, int translate) void gpgsm_print_name2 (FILE *fp, const char *name, int translate) { - const unsigned char *s; + const unsigned char *s = (const unsigned char *)name; int i; - s = name; if (!s) { fputs (_("[Error - No name]"), fp); } else if (*s == '<') { - const unsigned char *s2 = strchr (s+1, '>'); + const char *s2 = strchr ( (char*)s+1, '>'); if (s2) { if (translate) - print_sanitized_utf8_buffer (fp, s + 1, s2 - s - 1, 0); + print_sanitized_utf8_buffer (fp, s + 1, s2 - (char*)s - 1, 0); else - print_sanitized_buffer (fp, s + 1, s2 - s - 1, 0); + print_sanitized_buffer (fp, s + 1, s2 - (char*)s - 1, 0); } } else if (*s == '(') diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 7b29a5b8d..2b920da7e 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -492,7 +492,7 @@ proc_parameters (ctrl_t ctrl, } sprintf (numbuf, "%u", nbits); - snprintf (keyparms, DIM (keyparms)-1, + snprintf ((char*)keyparms, DIM (keyparms)-1, "(6:genkey(3:rsa(5:nbits%d:%s)))", (int)strlen (numbuf), numbuf); rc = gpgsm_agent_genkey (ctrl, keyparms, &public); if (rc) @@ -627,8 +627,9 @@ create_request (ctrl_t ctrl, { gcry_sexp_t s_pkey; size_t n; - unsigned char grip[20], hexgrip[41]; - char *sigval; + unsigned char grip[20]; + char hexgrip[41]; + unsigned char *sigval; size_t siglen; n = gcry_sexp_canon_len (public, 0, NULL, NULL); @@ -638,7 +639,7 @@ create_request (ctrl_t ctrl, err = gpg_error (GPG_ERR_BUG); goto leave; } - rc = gcry_sexp_sscan (&s_pkey, NULL, public, n); + rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); diff --git a/sm/delete.c b/sm/delete.c index 11a0a5476..8e06b9489 100644 --- a/sm/delete.c +++ b/sm/delete.c @@ -67,7 +67,7 @@ delete_one (CTRL ctrl, const char *username) rc = keydb_get_cert (kh, &cert); if (!rc) { - char fpr[20]; + unsigned char fpr[20]; gpgsm_get_fingerprint (cert, 0, fpr, NULL); @@ -78,7 +78,7 @@ delete_one (CTRL ctrl, const char *username) else if (!rc) { ksba_cert_t cert2 = NULL; - char fpr2[20]; + unsigned char fpr2[20]; /* We ignore all duplicated certificates which might have been inserted due to program bugs. */ diff --git a/sm/encrypt.c b/sm/encrypt.c index 50da92c32..e4c0d5437 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -164,10 +164,10 @@ encode_session_key (DEK dek, gcry_sexp_t * r_data) } -/* encrypt the DEK under the key contained in CERT and return it as a - canonical S-Exp in encval */ +/* Encrypt the DEK under the key contained in CERT and return it as a + canonical S-Exp in encval. */ static int -encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) +encrypt_dek (const DEK dek, ksba_cert_t cert, unsigned char **encval) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; @@ -189,7 +189,7 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) log_error ("libksba did not return a proper S-Exp\n"); return gpg_error (GPG_ERR_BUG); } - rc = gcry_sexp_sscan (&s_pkey, NULL, buf, len); + rc = gcry_sexp_sscan (&s_pkey, NULL, (char*)buf, len); xfree (buf); buf = NULL; if (rc) { @@ -220,7 +220,7 @@ encrypt_dek (const DEK dek, ksba_cert_t cert, char **encval) gcry_sexp_release (s_ciph); return tmperr; } - len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, buf, len); + len = gcry_sexp_sprint (s_ciph, GCRYSEXP_FMT_CANON, (char*)buf, len); assert (len); *encval = buf; @@ -437,7 +437,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp) each and store them in the CMS object */ for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next) { - char *encval; + unsigned char *encval; rc = encrypt_dek (dek, cl->cert, &encval); if (rc) diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 7fe619c18..9c3ab85db 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -42,8 +42,9 @@ If there is a problem , the function does never return NULL but a digest of all 0xff. */ -char * -gpgsm_get_fingerprint (ksba_cert_t cert, int algo, char *array, int *r_len) +unsigned char * +gpgsm_get_fingerprint (ksba_cert_t cert, int algo, + unsigned char *array, int *r_len) { gcry_md_hd_t md; int rc, len; @@ -140,8 +141,8 @@ gpgsm_get_short_fingerprint (ksba_cert_t cert) key parameters expressed as an canoncial encoded S-Exp. array must be 20 bytes long. returns the array or a newly allocated one if the passed one was NULL */ -char * -gpgsm_get_keygrip (ksba_cert_t cert, char *array) +unsigned char * +gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array) { gcry_sexp_t s_pkey; int rc; @@ -160,7 +161,7 @@ gpgsm_get_keygrip (ksba_cert_t cert, char *array) log_error ("libksba did not return a proper S-Exp\n"); return NULL; } - rc = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + rc = gcry_sexp_sscan ( &s_pkey, NULL, (char*)p, n); xfree (p); if (rc) { @@ -223,7 +224,7 @@ gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits) xfree (p); return 0; } - rc = gcry_sexp_sscan (&s_pkey, NULL, p, n); + rc = gcry_sexp_sscan (&s_pkey, NULL, (char *)p, n); xfree (p); if (rc) return 0; @@ -272,7 +273,7 @@ char * gpgsm_get_certid (ksba_cert_t cert) { ksba_sexp_t serial; - unsigned char *p; + char *p; char *endp; unsigned char hash[20]; unsigned long n; @@ -288,7 +289,7 @@ gpgsm_get_certid (ksba_cert_t cert) serial = ksba_cert_get_serial (cert); if (!serial) return NULL; /* oops: no serial number */ - p = serial; + p = (char *)serial; if (*p != '(') { log_error ("Ooops: invalid serial number\n"); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 1068e9d5e..2f3e83485 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -181,12 +181,12 @@ gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, gpg_err_code_t ec); /*-- fingerprint --*/ -char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, - char *array, int *r_len); +unsigned char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, + unsigned char *array, int *r_len); char *gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo); char *gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo); unsigned long gpgsm_get_short_fingerprint (ksba_cert_t cert); -char *gpgsm_get_keygrip (ksba_cert_t cert, char *array); +unsigned char *gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array); char *gpgsm_get_keygrip_hexstring (ksba_cert_t cert); int gpgsm_get_key_algo_info (ksba_cert_t cert, unsigned int *nbits); char *gpgsm_get_certid (ksba_cert_t cert); @@ -229,7 +229,7 @@ int gpgsm_check_cms_signature (ksba_cert_t cert, ksba_const_sexp_t sigval, /* fixme: move create functions to another file */ int gpgsm_create_cms_signature (ctrl_t ctrl, ksba_cert_t cert, gcry_md_hd_t md, int mdalgo, - char **r_sigval); + unsigned char **r_sigval); /*-- certchain.c --*/ @@ -293,7 +293,7 @@ int gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc, unsigned char *digest, size_t digestlen, int digestalgo, - char **r_buf, size_t *r_buflen); + unsigned char **r_buf, size_t *r_buflen); int gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, ksba_const_sexp_t ciphertext, char **r_buf, size_t *r_buflen); diff --git a/sm/keydb.c b/sm/keydb.c index 293e5233d..17f04fe4b 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -681,7 +681,7 @@ keydb_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert) { int rc = -1; int idx; - char digest[20]; + unsigned char digest[20]; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -723,7 +723,7 @@ int keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert) { int rc = 0; - char digest[20]; + unsigned char digest[20]; if (!hd) return gpg_error (GPG_ERR_INV_VALUE); @@ -1010,8 +1010,9 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) static int -hextobyte (const unsigned char *s) +hextobyte (const char *string) { + const unsigned char *s = (const unsigned char *)string; int c; if( *s >= '0' && *s <= '9' ) @@ -1122,7 +1123,7 @@ classify_user_id (const char *name, if (!strchr("01234567890abcdefABCDEF", *si)) return 0; /* invalid digit in serial number*/ } - desc->sn = s; + desc->sn = (const unsigned char*)s; desc->snlen = -1; if (!*si) mode = KEYDB_SEARCH_MODE_SN; diff --git a/sm/keylist.c b/sm/keylist.c index 8e1233341..a0ac73fb3 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -256,7 +256,7 @@ print_time (gnupg_isotime_t t, FILE *fp) static char * email_kludge (const char *name) { - const unsigned char *p; + const char *p; unsigned char *buf; int n; @@ -278,7 +278,7 @@ email_kludge (const char *name) buf[n] = xtoi_2 (p); buf[n++] = '>'; buf[n] = 0; - return buf; + return (char*)buf; } diff --git a/sm/server.c b/sm/server.c index 7bfd3fc20..b3816d3d9 100644 --- a/sm/server.c +++ b/sm/server.c @@ -53,14 +53,14 @@ struct server_local_s { /* Note that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1; */ static void -strcpy_escaped_plus (char *d, const unsigned char *s) +strcpy_escaped_plus (char *d, const char *s) { while (*s) { if (*s == '%' && s[1] && s[2]) { s++; - *d++ = xtoi_2 ( s); + *d++ = xtoi_2 (s); s += 2; } else if (*s == '+') diff --git a/sm/sign.c b/sm/sign.c index 5deef6088..3230a0e98 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -575,7 +575,7 @@ gpgsm_sign (CTRL ctrl, CERTLIST signerlist, ksba_cms_set_hash_function (cms, HASH_FNC, md); for (cl=signerlist,signer=0; cl; cl = cl->next, signer++) { - char *sigval = NULL; + unsigned char *sigval = NULL; char *buf, *fpr; if (signer) diff --git a/tools/ChangeLog b/tools/ChangeLog index 39f17e2ce..5965b2871 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,8 @@ +2005-06-16 Werner Koch + + * gpg-connect-agent.c (read_and_print_response): Made LINELEN a + size_t. + 2005-06-04 Marcus Brinkmann * symcryptrun.c (main): Allow any number of arguments, don't use diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index bb05030ee..c9a324fa8 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -458,7 +458,7 @@ static int read_and_print_response (assuan_context_t ctx) { char *line; - int linelen; + size_t linelen; assuan_error_t rc; int i, j; diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index c49d1dcbb..e8d9ca27e 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2316,7 +2316,7 @@ gc_component_change_options (int component, FILE *in) char *linep; unsigned long flags = 0; char *new_value = ""; - unsigned long new_value_nr; + unsigned long new_value_nr = 0; /* Strip newline and carriage return, if present. */ while (length > 0 diff --git a/tools/gpgkey2ssh.c b/tools/gpgkey2ssh.c index 75b18b29b..e874ab22e 100644 --- a/tools/gpgkey2ssh.c +++ b/tools/gpgkey2ssh.c @@ -249,6 +249,9 @@ main (int argc, char **argv) pkdbuf = NULL; pkdbuf_n = 0; + algorithm_id = 0; /* (avoid cc warning) */ + identifier = NULL; /* (avoid cc warning) */ + assert (argc == 2); keyid = argv[1]; diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 25ca8c413..6cb570fbc 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -223,7 +223,7 @@ main (int argc, char **argv) int force = 0; struct sockaddr_un srvr_addr; - int addrlen; + socklen_t addrlen; int server; int flags; client_t client_list = NULL; -- cgit From 6a13cf2c3dbacb9f3afd3f64e5d0c78b9c0e77e9 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 28 Nov 2005 11:52:25 +0000 Subject: Preparing an interim release --- ChangeLog | 16 +++++ NEWS | 7 ++ TODO | 1 - agent/ChangeLog | 17 +++++ agent/agent.h | 7 +- agent/call-scd.c | 51 +++++++++----- agent/command.c | 9 ++- agent/divert-scd.c | 19 ++++- agent/minip12.c | 21 ++++-- agent/query.c | 196 +++++++++++++++++++++++++++++++++++++++++++-------- agent/t-protect.c | 3 +- am/cmacros.am | 3 +- configure.ac | 11 +-- kbx/keybox-blob.c | 2 +- po/POTFILES.in | 1 + po/de.po | 16 +++-- scd/ChangeLog | 55 +++++++++++++++ scd/apdu.c | 176 +++++++++++++++++++++++++++++++++++---------- scd/apdu.h | 9 ++- scd/app-dinsig.c | 41 +++++++++-- scd/app-nks.c | 11 +-- scd/app-openpgp.c | 9 ++- scd/app-p15.c | 13 ++-- scd/ccid-driver.c | 64 ++++++++++++++--- scd/ccid-driver.h | 7 +- scd/iso7816.c | 115 +++++++++++++++++++++++++----- scd/iso7816.h | 35 ++++++++- scd/scdaemon.c | 6 +- scd/scdaemon.h | 17 ++--- tools/ChangeLog | 8 +++ tools/gpgconf-comp.c | 7 +- tools/rfc822parse.c | 1 + 32 files changed, 784 insertions(+), 170 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/ChangeLog b/ChangeLog index f63a035cc..46d66ed47 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2005-11-28 Werner Koch + + * configure.ac: Append the revision to the version string. + +2005-11-13 Werner Koch + + * am/cmacros.am (-DGNUPG_SYSCONFDIR): Define it. + +2005-11-11 Werner Koch + + * configure.ac (NEED_KSBA_VERSION: Require 0.9.13. + +2005-09-12 Werner Koch + + Released 1.9.19. + 2005-08-01 Werner Koch Released 1.9.18. diff --git a/NEWS b/NEWS index 1e1148748..edf29885d 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,10 @@ +Noteworthy changes in version 1.9.20 +------------------------------------------------- + + * [scdaemon] Support for keypads of some readers. Tested only with + SPR532. New option --disable-keypad. + + Noteworthy changes in version 1.9.19 (2005-09-12) ------------------------------------------------- diff --git a/TODO b/TODO index 32b728588..50f58cee9 100644 --- a/TODO +++ b/TODO @@ -26,7 +26,6 @@ might want to have an agent context for each service request * sm/gpgsm.c ** Support --output for all commands ** mark all unimplemented commands and options. -** Print a hint when MD2 is the cause for a problem. ** Implement --default-key ** support the anyPolicy semantic ** Check that we are really following the verification procedures in rfc3280. diff --git a/agent/ChangeLog b/agent/ChangeLog index 975484007..105178730 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,20 @@ +2005-11-24 Werner Koch + + * minip12.c (p12_parse): Fixed for case that the key object comes + prior to the certificate. + +2005-10-19 Werner Koch + + * divert-scd.c (getpin_cb): Hack to use it for a keypad message. + + * call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO. + + * query.c (start_pinentry): Keep track of the owner. + (popup_message_thread, agent_popup_message_start) + (agent_popup_message_stop, agent_reset_query): New. + * command.c (start_command_handler): Make sure a popup window gets + closed. + 2005-10-08 Marcus Brinkmann * Makefile.am (gpg_protect_tool_LDADD): Add ../gl/libgnu.a. diff --git a/agent/agent.h b/agent/agent.h index 7a646a85f..0918395ce 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -133,7 +133,7 @@ struct server_control_s int have_keygrip; int use_auth_call; /* Hack to send the PKAUTH command instead of the - PKSIGN command tro scdaemon. */ + PKSIGN command to the scdaemon. */ }; typedef struct server_control_s *CTRL; typedef struct server_control_s *ctrl_t; @@ -200,6 +200,7 @@ int agent_key_available (const unsigned char *grip); /*-- query.c --*/ void initialize_module_query (void); void agent_query_dump_state (void); +void agent_reset_query (ctrl_t ctrl); int agent_askpin (ctrl_t ctrl, const char *desc_text, const char *prompt_text, const char *inital_errtext, @@ -209,6 +210,10 @@ int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *errtext); int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, const char *cancel); +int agent_popup_message_start (ctrl_t ctrl, const char *desc, + const char *ok_btn, const char *cancel_btn); +void agent_popup_message_stop (ctrl_t ctrl); + /*-- cache.c --*/ void agent_flush_cache (void); diff --git a/agent/call-scd.c b/agent/call-scd.c index 7a623fda4..a883f2733 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -633,26 +633,43 @@ inq_needpin (void *opaque, const char *line) size_t pinlen; int rc; - if (!(!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))) + if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7])) { - log_error ("unsupported inquiry `%s'\n", line); - return ASSUAN_Inquire_Unknown; - } - line += 7; - while (*line == ' ') - line++; + line += 7; + while (*line == ' ') + line++; + + pinlen = 90; + pin = gcry_malloc_secure (pinlen); + if (!pin) + return ASSUAN_Out_Of_Core; - pinlen = 90; - pin = gcry_malloc_secure (pinlen); - if (!pin) - return ASSUAN_Out_Of_Core; + rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); + if (rc) + rc = ASSUAN_Canceled; + if (!rc) + rc = assuan_send_data (parm->ctx, pin, pinlen); + xfree (pin); + } + else if (!strncmp (line, "KEYPADINFO", 10) && (line[10] == ' ' || !line[10])) + { + size_t code; + char *endp; - rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen); - if (rc) - rc = ASSUAN_Canceled; - if (!rc) - rc = assuan_send_data (parm->ctx, pin, pinlen); - xfree (pin); + code = strtoul (line+10, &endp, 10); + line = endp; + while (*line == ' ') + line++; + + rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, code); + if (rc) + rc = ASSUAN_Canceled; + } + else + { + log_error ("unsupported inquiry `%s'\n", line); + rc = ASSUAN_Inquire_Unknown; + } return rc; } diff --git a/agent/command.c b/agent/command.c index c39bcc6ab..daf9b8698 100644 --- a/agent/command.c +++ b/agent/command.c @@ -316,11 +316,11 @@ cmd_sigkey (ASSUAN_CONTEXT ctx, char *line) this command is not used a default text will be used. Note, that this description implictly selects the label used for the entry box; if the string contains the string PIN (which in general will - not be translated), "PIN" is used, other wiese the translation of + not be translated), "PIN" is used, otherwise the translation of 'passphrase" is used. The description string should not contain blanks unless they are percent or '+' escaped. - The descrition is only valid for the next PKSIGN or PKDECRYPT + The description is only valid for the next PKSIGN or PKDECRYPT operation. */ static int @@ -399,7 +399,7 @@ cmd_sethash (ASSUAN_CONTEXT ctx, char *line) /* PKSIGN Perform the actual sign operation. Neither input nor output are - sensitive to eavesdropping */ + sensitive to eavesdropping. */ static int cmd_pksign (ASSUAN_CONTEXT ctx, char *line) { @@ -1085,6 +1085,9 @@ start_command_handler (int listen_fd, int fd) /* Reset the SCD if needed. */ agent_reset_scd (&ctrl); + /* Reset the pinentry (in case of popup messages). */ + agent_reset_query (&ctrl); + assuan_deinit_server (ctx); if (ctrl.display) free (ctrl.display); diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 9d2fa446c..926df2622 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -204,7 +204,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) const char *again_text = NULL; const char *prompt = "PIN"; - if (maxbuf < 2) + if (buf && maxbuf < 2) return gpg_error (GPG_ERR_INV_VALUE); /* Parse the flags. */ @@ -223,6 +223,23 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) else if (info && *info == '|') log_debug ("pin_cb called without proper PIN info hack\n"); + /* If BUF has been passed as NULL, we are in keypad mode: The + callback opens the popup and immediatley returns. */ + if (!buf) + { + if (maxbuf == 0) /* Close the pinentry. */ + { + agent_popup_message_stop (ctrl); + rc = 0; + } + else if (maxbuf == 1) /* Open the pinentry. */ + { + rc = agent_popup_message_start (ctrl, info, NULL, NULL); + } + else + rc = gpg_error (GPG_ERR_INV_VALUE); + return rc; + } /* FIXME: keep PI and TRIES in OPAQUE. Frankly this is a whole mess because we should call the card's verify function from the diff --git a/agent/minip12.c b/agent/minip12.c index 91eef63f4..55f3946bf 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -511,7 +511,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, goto bailout; } - /* Loop over all certificates inside the bab. */ + /* Loop over all certificates inside the bag. */ while (n) { int isbag = 0; @@ -860,6 +860,7 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, size_t n = length; const char *where; int bagseqlength, len; + gcry_mpi_t *result = NULL; where = "pfx"; if (parse_tag (&p, &n, &ti)) @@ -936,10 +937,17 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, else if (ti.tag == TAG_OBJECT_ID && ti.length == DIM(oid_data) && !memcmp (p, oid_data, DIM(oid_data))) { - p += DIM(oid_data); - n -= DIM(oid_data); - len -= DIM(oid_data); - return parse_bag_data (p, n, (p-buffer), pw); + if (result) + log_info ("already got an data object, skipping next one\n"); + else + { + p += DIM(oid_data); + n -= DIM(oid_data); + len -= DIM(oid_data); + result = parse_bag_data (p, n, (p-buffer), pw); + if (!result) + goto bailout; + } } else log_info ( "unknown bag type - skipped\n"); @@ -950,9 +958,10 @@ p12_parse (const unsigned char *buffer, size_t length, const char *pw, n -= len; } - return NULL; + return result; bailout: log_error ("error at \"%s\", offset %u\n", where, (p - buffer)); + /* fixme: need to release RESULT. */ return NULL; } diff --git a/agent/query.c b/agent/query.c index b231f6fc3..a5a3d0153 100644 --- a/agent/query.c +++ b/agent/query.c @@ -27,9 +27,10 @@ #include #include #include -#ifdef USE_GNU_PTH -# include +#ifndef HAVE_W32_SYSTEM +#include #endif +#include #include "agent.h" #include "i18n.h" @@ -48,14 +49,30 @@ time. */ #define LOCK_TIMEOUT (1*60) +/* The assuan context of the current pinentry. */ +static assuan_context_t entry_ctx; -static assuan_context_t entry_ctx = NULL; -#ifdef USE_GNU_PTH +/* The control variable of the connection owning the current pinentry. + This is only valid if ENTRY_CTX is not NULL. Note, that we care + only about the value of the pointer and that it should never be + dereferenced. */ +static ctrl_t entry_owner; + +/* A mutex used to serialize access to the pinentry. */ static pth_mutex_t entry_lock; -#endif -/* data to be passed to our callbacks */ -struct entry_parm_s { +/* The thread ID of the popup working thread. */ +static pth_t popup_tid; + +/* A flag used in communication between the popup working thread and + its stop function. */ +static int popup_finished; + + + +/* Data to be passed to our callbacks, */ +struct entry_parm_s +{ int lines; size_t size; unsigned char *buffer; @@ -67,17 +84,17 @@ struct entry_parm_s { /* This function must be called once to initialize this module. This has to be done before a second thread is spawned. We can't do the static initialization because Pth emulation code might not be able - to do a static init; in particualr, it is not possible for W32. */ + to do a static init; in particular, it is not possible for W32. */ void initialize_module_query (void) { -#ifdef USE_GNU_PTH static int initialized; if (!initialized) - if (pth_mutex_init (&entry_lock)) - initialized = 1; -#endif /*USE_GNU_PTH*/ + { + if (pth_mutex_init (&entry_lock)) + initialized = 1; + } } @@ -102,8 +119,19 @@ agent_query_dump_state (void) log_info ("agent_query_dump_state: entry_lock="); dump_mutex_state (&entry_lock); log_printf ("\n"); - log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld\n", - entry_ctx, (long)assuan_get_pid (entry_ctx)); + log_info ("agent_query_dump_state: entry_ctx=%p pid=%ld popup_tid=%p\n", + entry_ctx, (long)assuan_get_pid (entry_ctx), popup_tid); +} + +/* Called to make sure that a popup window owned by the current + connection gets closed. */ +void +agent_reset_query (ctrl_t ctrl) +{ + if (entry_ctx && popup_tid && entry_owner == ctrl) + { + agent_popup_message_stop (ctrl); + } } @@ -117,14 +145,12 @@ unlock_pinentry (int rc) assuan_context_t ctx = entry_ctx; entry_ctx = NULL; -#ifdef USE_GNU_PTH if (!pth_mutex_release (&entry_lock)) { log_error ("failed to release the entry lock\n"); if (!rc) rc = gpg_error (GPG_ERR_INTERNAL); } -#endif assuan_disconnect (ctx); return rc; } @@ -145,7 +171,7 @@ atfork_cb (void *opaque, int where) pinentry - we will serialize _all_ pinentry calls. */ static int -start_pinentry (CTRL ctrl) +start_pinentry (ctrl_t ctrl) { int rc; const char *pgmname; @@ -153,13 +179,10 @@ start_pinentry (CTRL ctrl) const char *argv[5]; int no_close_list[3]; int i; + pth_event_t evt; -#ifdef USE_GNU_PTH - { - pth_event_t evt; - - evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); - if (!pth_mutex_acquire (&entry_lock, 0, evt)) + evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); + if (!pth_mutex_acquire (&entry_lock, 0, evt)) { if (pth_event_occurred (evt)) rc = gpg_error (GPG_ERR_TIMEOUT); @@ -170,9 +193,9 @@ start_pinentry (CTRL ctrl) gpg_strerror (rc)); return rc; } - pth_event_free (evt, PTH_FREE_THIS); - } -#endif + pth_event_free (evt, PTH_FREE_THIS); + + entry_owner = ctrl; if (entry_ctx) return 0; @@ -436,7 +459,7 @@ agent_askpin (ctrl_t ctrl, passphrase is returned in RETPASS as an hex encoded string to be freed by the caller */ int -agent_get_passphrase (CTRL ctrl, +agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, const char *errtext) { @@ -517,11 +540,11 @@ agent_get_passphrase (CTRL ctrl, /* Pop up the PIN-entry, display the text and the prompt and ask the - user to confirm this. We return 0 for success, ie. the used + user to confirm this. We return 0 for success, ie. the user confirmed it, GPG_ERR_NOT_CONFIRMED for what the text says or an other error. */ int -agent_get_confirmation (CTRL ctrl, +agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok, const char *cancel) { int rc; @@ -562,4 +585,119 @@ agent_get_confirmation (CTRL ctrl, } +/* The thread running the popup message. */ +static void * +popup_message_thread (void *arg) +{ + assuan_transact (entry_ctx, "CONFIRM", NULL, NULL, NULL, NULL, NULL, NULL); + popup_finished = 1; + return NULL; +} + + +/* Pop up a message window similar to the confirm one but keep it open + until agent_popup_message_stop has been called. It is crucial for + the caller to make sure that the stop function gets called as soon + as the message is not anymore required becuase the message is + system modal and all other attempts to use the pinentry will fail + (after a timeout). */ +int +agent_popup_message_start (ctrl_t ctrl, const char *desc, + const char *ok_btn, const char *cancel_btn) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + pth_attr_t tattr; + + rc = start_pinentry (ctrl); + if (rc) + return rc; + + if (desc) + snprintf (line, DIM(line)-1, "SETDESC %s", desc); + else + snprintf (line, DIM(line)-1, "RESET"); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return unlock_pinentry (map_assuan_err (rc)); + + if (ok_btn) + { + snprintf (line, DIM(line)-1, "SETOK %s", ok_btn); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL); + if (rc) + return unlock_pinentry (map_assuan_err (rc)); + } + if (cancel_btn) + { + snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel_btn); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL,NULL,NULL,NULL,NULL,NULL); + if (rc) + return unlock_pinentry (map_assuan_err (rc)); + } + + tattr = pth_attr_new(); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); + pth_attr_set (tattr, PTH_ATTR_NAME, "popup-message"); + + popup_finished = 0; + popup_tid = pth_spawn (tattr, popup_message_thread, NULL); + if (!popup_tid) + { + rc = gpg_error_from_errno (errno); + log_error ("error spawning popup message handler: %s\n", + strerror (errno) ); + pth_attr_destroy (tattr); + return unlock_pinentry (rc); + } + pth_attr_destroy (tattr); + + return 0; +} + +/* Close a popup window. */ +void +agent_popup_message_stop (ctrl_t ctrl) +{ + int rc; + pid_t pid; + + if (!popup_tid || !entry_ctx) + { + log_debug ("agent_popup_message_stop called with no active popup\n"); + return; + } + + pid = assuan_get_pid (entry_ctx); + if (pid == (pid_t)(-1)) + ; /* No pid available can't send a kill. */ + else if (popup_finished) + ; /* Already finished and ready for joining. */ + else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) + { /* The daemon already died. No need to send a kill. However + because we already waited for the process, we need to tell + assuan that it should not wait again (done by + unlock_pinentry). */ + if (rc == pid) + assuan_set_flag (entry_ctx, ASSUAN_NO_WAITPID, 1); + } + else + kill (pid, SIGINT); + + /* Now wait for the thread to terminate. */ + rc = pth_join (popup_tid, NULL); + if (!rc) + log_debug ("agent_popup_message_stop: pth_join failed: %s\n", + strerror (errno)); + popup_tid = NULL; + entry_owner = NULL; + + /* Now we can close the connection. */ + unlock_pinentry (0); +} + diff --git a/agent/t-protect.c b/agent/t-protect.c index 5187cf8f7..fee3c561d 100644 --- a/agent/t-protect.c +++ b/agent/t-protect.c @@ -173,7 +173,8 @@ test_agent_protect (void) for (i = 0; i < DIM (specs); i++) { - ret = agent_protect (specs[i].key, specs[i].passphrase, + ret = agent_protect ((const unsigned char*)specs[i].key, + specs[i].passphrase, &specs[i].result, &specs[i].resultlen); if (gpg_err_code (ret) != specs[i].ret_expected) { diff --git a/am/cmacros.am b/am/cmacros.am index 0f7a09fe0..de68b6f31 100644 --- a/am/cmacros.am +++ b/am/cmacros.am @@ -25,7 +25,8 @@ if ! HAVE_DOSISH_SYSTEM AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ - -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" + -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \ + -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" endif if GNUPG_AGENT_PGM diff --git a/configure.ac b/configure.ac index 30b183046..6ba66968d 100644 --- a/configure.ac +++ b/configure.ac @@ -22,9 +22,12 @@ AC_PREREQ(2.52) min_automake_version="1.9.3" -# Version number: Remember to change it immediately *after* a release. -# Add a "-cvs" prefix for non-released code. -AC_INIT(gnupg, 1.9.19, gnupg-devel@gnupg.org) +# Remember to change the version number immediately *after* a release. +# Uncomment the my_iscvs macro for non-released code. +m4_define(my_version, [1.9.20]) +m4_define(my_iscvs, yes) +AC_INIT([gnupg], my_version[]m4_ifdef([my_iscvs], [-cvs[]m4_translit( + [$Revision$],[Ra-z $:])]), [gnupg-devel@gnupg.org]) # Set development_version to yes if the minor number is odd or you # feel that the default check for a development version is not # sufficient. @@ -36,7 +39,7 @@ NEED_LIBGCRYPT_VERSION=1.1.94 NEED_LIBASSUAN_VERSION=0.6.10 -NEED_KSBA_VERSION=0.9.12 +NEED_KSBA_VERSION=0.9.13 PACKAGE=$PACKAGE_NAME diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index 67c74b777..eacc0014a 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -61,7 +61,7 @@ X.509 specific are noted like [X.509: xxx] u32 offset to the n-th key's keyID (a keyID is always 8 byte) or 0 if not known which is the case only for X509. u16 special key flags - bit 0 = + bit 0 = qualified signature (not yet implemented} u16 reserved u16 size of serialnumber(may be zero) n u16 (see above) bytes of serial number diff --git a/po/POTFILES.in b/po/POTFILES.in index 8fff858db..eb5711ddb 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -17,6 +17,7 @@ kbx/kbxutil.c scd/scdaemon.c scd/app-openpgp.c +scd/app-nks.c sm/base64.c sm/call-agent.c diff --git a/po/de.po b/po/de.po index 6b28544cb..2201c0429 100644 --- a/po/de.po +++ b/po/de.po @@ -10,8 +10,8 @@ msgid "" msgstr "" "Project-Id-Version: gnupg2 1.9.18\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2005-11-23 13:00+0100\n" -"PO-Revision-Date: 2005-11-23 13:02+0100\n" +"POT-Creation-Date: 2005-11-28 12:14+0100\n" +"PO-Revision-Date: 2005-11-28 12:16+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -766,6 +766,10 @@ msgstr "" msgid "can't access %s - invalid OpenPGP card?\n" msgstr "Zugriff auf %s nicht möglich - ungültige OpenPGP Karte?\n" +#: scd/app-nks.c:344 +msgid "the NullPIN has not yet been changed\n" +msgstr "Die Nullpin wurde noch nicht geändert\n" + #: sm/base64.c:317 #, c-format msgid "invalid radix64 character %02x skipped\n" @@ -1369,7 +1373,7 @@ msgstr "Signieren mit `%s' nicht möglich: %s\n" #: sm/gpgsm.c:1475 msgid "this command has not yet been implemented\n" -msgstr "Diee Kommando wurde noch nicht implementiert\n" +msgstr "Dieses Kommando wurde noch nicht implementiert\n" #: sm/gpgsm.c:1705 sm/gpgsm.c:1742 sm/qualified.c:73 #, c-format @@ -1548,10 +1552,10 @@ msgid "" msgstr "" "Sie sind dabei, eine Signatur mit dem Zertifikat:\n" "\"%s\"\n" -"zu erzeugen. Dies wird einen qualifizierte Signatur erzeugen, \n" -"die gesetzlich einer handgeschriebene gleichgestellt ist.\n" +"zu erzeugen. Dies wird eine qualifizierte Signatur erzeugen, \n" +"die gesetzlich einer handgeschriebenen gleichgestellt ist.\n" "\n" -"%s%sSind Sie wirklich sicher, da Sie dies möchten?" +"%s%sSind Sie wirklich sicher, daß Sie dies möchten?" #: sm/qualified.c:224 msgid "" diff --git a/scd/ChangeLog b/scd/ChangeLog index ccea117dd..008d84080 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,8 +1,63 @@ +2005-11-23 Werner Koch + + * app-nks.c (verify_pin): Give a special error message for a Nullpin. + +2005-10-29 Werner Koch + + * ccid-driver.c (send_escape_cmd): New args RESULT, RESULTLEN and + RESULTMAX. Changed all callers. + (ccid_transceive_escape): New. + +2005-10-27 Werner Koch + + * apdu.c [__CYGWIN__]: Make cygwin environment similar to _WIN32. + Suggested by John P. Clizbe. + * scdaemon.c [__CYGWIN__]: Set default PC/SC driver to winscard.dll. + +2005-10-19 Werner Koch + + * ccid-driver.h (CCID_DRIVER_ERR_NO_KEYPAD): New. + * apdu.h (SW_HOST_NO_KEYPAD): New. + * iso7816.h (struct iso7816_pininfo_s): New. + * iso7816.c (map_sw): Support new code. + (iso7816_check_keypad): New. + (iso7816_verify_kp, iso7816_change_reference_data_kp) + (iso7816_reset_retry_counter_kp): New. Extended versions of the + original functions. + * apdu.c (host_sw_string): Support new code. + (reader_table_s): New field CHECK_KEYPAD. + (new_reader_slot, open_ct_reader, open_pcsc_reader) + (open_ccid_reader, open_rapdu_reader): Initialize it. + (check_ccid_keypad): New. + (apdu_check_keypad): New. + (apdu_send_le): Factored all code out to ... + (send_le): .. new. Takes an additional arg; changed all callers + of the orginal function to use this one with a NULL for the new + arg. + (apdu_send_simple_kp): New. + (ct_send_apdu, pcsc_send_apdu, my_rapdu_send_apdu) + (send_apdu_ccid): New arg PININFO. + (send_apdu_ccid): Use the new arg. + + * scdaemon.c: New option --disable-keypad. + 2005-10-08 Marcus Brinkmann * Makefile.am (scdaemon_LDADD): Add ../gl/libgnu.a after ../common/libcommon.a. +2005-09-20 Werner Koch + + * app-dinsig.c (verify_pin): Try ISO 9564 BCD encoding. + + * iso7816.c (iso7816_select_application): Add arg FLAGS. Changed + all callers to pass 0. + * app-openpgp.c (app_select_openpgp): But this one requires a + special flag. + + * app-p15.c (app_select_p15): Don't use select application for the + BELPIC. + 2005-09-09 Werner Koch * pcsc-wrapper.c (main): Removed bogus free. diff --git a/scd/apdu.c b/scd/apdu.c index 678ea12d3..f59d832d4 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -66,10 +66,10 @@ #include "ccid-driver.h" -/* To to conflicting use of threading libraries we usually can't link +/* Due to conflicting use of threading libraries we usually can't link against libpcsclite. Instead we use a wrapper program. */ #ifdef USE_GNU_PTH -#ifndef HAVE_W32_SYSTEM +#if !defined(HAVE_W32_SYSTEM) && !defined(__CYGWIN__) #define NEED_PCSC_WRAPPER 1 #endif #endif @@ -78,7 +78,7 @@ #define MAX_READER 4 /* Number of readers we support concurrently. */ -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) #define DLSTDCALL __stdcall #else #define DLSTDCALL @@ -90,6 +90,14 @@ #define MAX_OPEN_FDS 20 #endif +/* Helper to pass patrameters related to keypad based operations. */ +struct pininfo_s +{ + int mode; + int minlen; + int maxlen; + int padlen; +}; /* A structure to collect information pertaining to one reader slot. */ @@ -103,7 +111,8 @@ struct reader_table_s { int (*reset_reader)(int); int (*get_status_reader)(int, unsigned int *); int (*send_apdu_reader)(int,unsigned char *,size_t, - unsigned char *, size_t *); + unsigned char *, size_t *, struct pininfo_s *); + int (*check_keypad)(int, int, int, int, int, int); void (*dump_status_reader)(int); struct { @@ -320,6 +329,7 @@ new_reader_slot (void) reader_table[reader].reset_reader = NULL; reader_table[reader].get_status_reader = NULL; reader_table[reader].send_apdu_reader = NULL; + reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = NULL; reader_table[reader].used = 1; @@ -372,6 +382,7 @@ host_sw_string (long err) case SW_HOST_GENERAL_ERROR: return "general error"; case SW_HOST_NO_READER: return "no reader"; case SW_HOST_ABORTED: return "aborted"; + case SW_HOST_NO_KEYPAD: return "no keypad"; default: return "unknown host status error"; } } @@ -533,7 +544,7 @@ ct_get_status (int slot, unsigned int *status) set to BUFLEN. Returns: CT API error code. */ static int ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) + unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) { int rc; unsigned char dad[1], sad[1]; @@ -596,6 +607,7 @@ open_ct_reader (int port) reader_table[reader].reset_reader = reset_ct_reader; reader_table[reader].get_status_reader = ct_get_status; reader_table[reader].send_apdu_reader = ct_send_apdu; + reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = ct_dump_reader_status; dump_reader_status (reader); @@ -1082,7 +1094,8 @@ pcsc_get_status (int slot, unsigned int *status) set to BUFLEN. Returns: CT API error code. */ static int pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) { #ifdef NEED_PCSC_WRAPPER long err; @@ -1479,6 +1492,7 @@ open_pcsc_reader (const char *portstr) reader_table[slot].reset_reader = reset_pcsc_reader; reader_table[slot].get_status_reader = pcsc_get_status; reader_table[slot].send_apdu_reader = pcsc_send_apdu; + reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = dump_pcsc_reader_status; /* Read the status so that IS_T0 will be set. */ @@ -1625,6 +1639,7 @@ open_pcsc_reader (const char *portstr) reader_table[slot].reset_reader = reset_pcsc_reader; reader_table[slot].get_status_reader = pcsc_get_status; reader_table[slot].send_apdu_reader = pcsc_send_apdu; + reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = dump_pcsc_reader_status; /* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */ @@ -1713,7 +1728,8 @@ get_status_ccid (int slot, unsigned int *status) set to BUFLEN. Returns: Internal CCID driver error code. */ static int send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) { long err; size_t maxbuflen; @@ -1727,9 +1743,18 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, log_printhex (" APDU_data:", apdu, apdulen); maxbuflen = *buflen; - err = ccid_transceive (reader_table[slot].ccid.handle, - apdu, apdulen, - buffer, maxbuflen, buflen); + if (pininfo) + err = ccid_transceive_secure (reader_table[slot].ccid.handle, + apdu, apdulen, + pininfo->mode, + pininfo->minlen, + pininfo->maxlen, + pininfo->padlen, + buffer, maxbuflen, buflen); + else + err = ccid_transceive (reader_table[slot].ccid.handle, + apdu, apdulen, + buffer, maxbuflen, buflen); if (err) log_error ("ccid_transceive failed: (0x%lx)\n", err); @@ -1737,6 +1762,24 @@ send_apdu_ccid (int slot, unsigned char *apdu, size_t apdulen, return err; } + +/* Check whether the CCID reader supports the ISO command code COMMAND + on the keypad. Return 0 on success. For a description of the pin + parameters, see ccid-driver.c */ +static int +check_ccid_keypad (int slot, int command, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + unsigned char apdu[] = { 0, 0, 0, 0x81 }; + + apdu[1] = command; + return ccid_transceive_secure (reader_table[slot].ccid.handle, + apdu, sizeof apdu, + pin_mode, pinlen_min, pinlen_max, pin_padlen, + NULL, 0, NULL); +} + + /* Open the reader and try to read an ATR. */ static int open_ccid_reader (const char *portstr) @@ -1776,6 +1819,7 @@ open_ccid_reader (const char *portstr) reader_table[slot].reset_reader = reset_ccid_reader; reader_table[slot].get_status_reader = get_status_ccid; reader_table[slot].send_apdu_reader = send_apdu_ccid; + reader_table[slot].check_keypad = check_ccid_keypad; reader_table[slot].dump_status_reader = dump_ccid_reader_status; dump_reader_status (slot); @@ -1932,7 +1976,8 @@ my_rapdu_get_status (int slot, unsigned int *status) set to BUFLEN. Returns: APDU error code. */ static int my_rapdu_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) { int err; reader_table_t slotp; @@ -2063,6 +2108,7 @@ open_rapdu_reader (int portno, reader_table[slot].reset_reader = reset_rapdu_reader; reader_table[slot].get_status_reader = my_rapdu_get_status; reader_table[slot].send_apdu_reader = my_rapdu_send_apdu; + reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = NULL; dump_reader_status (slot); @@ -2198,28 +2244,28 @@ apdu_open_reader (const char *portstr) pcsc_establish_context = dlsym (handle, "SCardEstablishContext"); pcsc_release_context = dlsym (handle, "SCardReleaseContext"); pcsc_list_readers = dlsym (handle, "SCardListReaders"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) if (!pcsc_list_readers) pcsc_list_readers = dlsym (handle, "SCardListReadersA"); #endif pcsc_get_status_change = dlsym (handle, "SCardGetStatusChange"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) if (!pcsc_get_status_change) pcsc_get_status_change = dlsym (handle, "SCardGetStatusChangeA"); #endif pcsc_connect = dlsym (handle, "SCardConnect"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) if (!pcsc_connect) pcsc_connect = dlsym (handle, "SCardConnectA"); #endif pcsc_reconnect = dlsym (handle, "SCardReconnect"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) if (!pcsc_reconnect) pcsc_reconnect = dlsym (handle, "SCardReconnectA"); #endif pcsc_disconnect = dlsym (handle, "SCardDisconnect"); pcsc_status = dlsym (handle, "SCardStatus"); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) if (!pcsc_status) pcsc_status = dlsym (handle, "SCardStatusA"); #endif @@ -2492,11 +2538,30 @@ apdu_get_status (int slot, int hang, } +/* Check whether the reader supports the ISO command code COMMAND on + the keypad. Return 0 on success. For a description of the pin + parameters, see ccid-driver.c */ +int +apdu_check_keypad (int slot, int command, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) + return SW_HOST_NO_DRIVER; + + if (reader_table[slot].check_keypad) + return reader_table[slot].check_keypad (slot, command, + pin_mode, pinlen_min, pinlen_max, + pin_padlen); + else + return SW_HOST_NOT_SUPPORTED; +} + + /* Dispatcher for the actual send_apdu function. Note, that this function should be called in locked state. */ static int send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen) + unsigned char *buffer, size_t *buflen, struct pininfo_s *pininfo) { if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; @@ -2504,24 +2569,20 @@ send_apdu (int slot, unsigned char *apdu, size_t apdulen, if (reader_table[slot].send_apdu_reader) return reader_table[slot].send_apdu_reader (slot, apdu, apdulen, - buffer, buflen); + buffer, buflen, pininfo); else return SW_HOST_NOT_SUPPORTED; } -/* Send an APDU to the card in SLOT. The APDU is created from all - given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1 - for LC won't sent this field and the data field; in this case DATA - must also be passed as NULL. The return value is the status word - or -1 for an invalid SLOT or other non card related error. If - RETBUF is not NULL, it will receive an allocated buffer with the - returned data. The length of that data will be put into - *RETBUFLEN. The caller is reponsible for releasing the buffer even - in case of errors. */ -int -apdu_send_le(int slot, int class, int ins, int p0, int p1, - int lc, const char *data, int le, - unsigned char **retbuf, size_t *retbuflen) + +/* Core APDU trabceiver function. Parameters are described at + apdu_send_le with the exception of PININFO which indicates keypad + related operations if not NULL. */ +static int +send_le (int slot, int class, int ins, int p0, int p1, + int lc, const char *data, int le, + unsigned char **retbuf, size_t *retbuflen, + struct pininfo_s *pininfo) { #define RESULTLEN 256 unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in @@ -2570,7 +2631,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, /* As safeguard don't pass any garbage from the stack to the driver. */ memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); + rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); if (rc || resultlen < 2) { log_error ("apdu_send_simple(%d) failed: %s\n", @@ -2638,7 +2699,7 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, apdu[apdulen++] = len; memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); + rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); if (rc || resultlen < 2) { log_error ("apdu_send_simple(%d) for get response failed: %s\n", @@ -2703,6 +2764,27 @@ apdu_send_le(int slot, int class, int ins, int p0, int p1, #undef RESULTLEN } +/* Send an APDU to the card in SLOT. The APDU is created from all + given parameters: CLASS, INS, P0, P1, LC, DATA, LE. A value of -1 + for LC won't sent this field and the data field; in this case DATA + must also be passed as NULL. The return value is the status word + or -1 for an invalid SLOT or other non card related error. If + RETBUF is not NULL, it will receive an allocated buffer with the + returned data. The length of that data will be put into + *RETBUFLEN. The caller is reponsible for releasing the buffer even + in case of errors. */ +int +apdu_send_le(int slot, int class, int ins, int p0, int p1, + int lc, const char *data, int le, + unsigned char **retbuf, size_t *retbuflen) +{ + return send_le (slot, class, ins, p0, p1, + lc, data, le, + retbuf, retbuflen, + NULL); +} + + /* Send an APDU to the card in SLOT. The APDU is created from all given parameters: CLASS, INS, P0, P1, LC, DATA. A value of -1 for LC won't sent this field and the data field; in this case DATA must @@ -2716,8 +2798,8 @@ int apdu_send (int slot, int class, int ins, int p0, int p1, int lc, const char *data, unsigned char **retbuf, size_t *retbuflen) { - return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256, - retbuf, retbuflen); + return send_le (slot, class, ins, p0, p1, lc, data, 256, + retbuf, retbuflen, NULL); } /* Send an APDU to the card in SLOT. The APDU is created from all @@ -2730,7 +2812,25 @@ int apdu_send_simple (int slot, int class, int ins, int p0, int p1, int lc, const char *data) { - return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL); + return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL); +} + + +/* Same as apdu_send_simple but uses the keypad of the reader. */ +int +apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1, + int lc, const char *data, + int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen) +{ + struct pininfo_s pininfo; + + pininfo.mode = pin_mode; + pininfo.minlen = pinlen_min; + pininfo.maxlen = pinlen_max; + pininfo.padlen = pin_padlen; + return send_le (slot, class, ins, p0, p1, lc, data, -1, + NULL, NULL, &pininfo); } @@ -2771,7 +2871,7 @@ apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen, class = apdulen? *apdu : 0; resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); + rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); if (rc || resultlen < 2) { log_error ("apdu_send_direct(%d) failed: %s\n", @@ -2825,7 +2925,7 @@ apdu_send_direct (int slot, const unsigned char *apdudata, size_t apdudatalen, apdu[apdulen++] = len; memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen); + rc = send_apdu (slot, apdu, apdulen, result, &resultlen, NULL); if (rc || resultlen < 2) { log_error ("apdu_send_direct(%d) for get response failed: %s\n", diff --git a/scd/apdu.h b/scd/apdu.h index 45388fdd1..c3af82506 100644 --- a/scd/apdu.h +++ b/scd/apdu.h @@ -63,7 +63,8 @@ enum { SW_HOST_CARD_IO_ERROR = 0x1000a, SW_HOST_GENERAL_ERROR = 0x1000b, SW_HOST_NO_READER = 0x1000c, - SW_HOST_ABORTED = 0x1000d + SW_HOST_ABORTED = 0x1000d, + SW_HOST_NO_KEYPAD = 0x1000e }; @@ -96,8 +97,14 @@ int apdu_activate (int slot); int apdu_reset (int slot); int apdu_get_status (int slot, int hang, unsigned int *status, unsigned int *changed); +int apdu_check_keypad (int slot, int command, int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen); int apdu_send_simple (int slot, int class, int ins, int p0, int p1, int lc, const char *data); +int apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1, + int lc, const char *data, + int pin_mode, + int pinlen_min, int pinlen_max, int pin_padlen); int apdu_send (int slot, int class, int ins, int p0, int p1, int lc, const char *data, unsigned char **retbuf, size_t *retbuflen); diff --git a/scd/app-dinsig.c b/scd/app-dinsig.c index 28b70c466..75cd12c59 100644 --- a/scd/app-dinsig.c +++ b/scd/app-dinsig.c @@ -1,5 +1,5 @@ /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application. - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -280,10 +280,11 @@ verify_pin (app_t app, { if (!app->did_chv1 || app->force_chv1 ) { + const char *s; char *pinvalue; int rc; - rc = pincb (pincb_arg, "PIN", &pinvalue); + rc = pincb (pincb_arg, "PIN", &pinvalue); if (rc) { log_info ("PIN callback returned error: %s\n", gpg_strerror (rc)); @@ -291,8 +292,16 @@ verify_pin (app_t app, } /* We require the PIN to be at least 6 and at max 8 bytes. - According to the specs, this should all be ASCII but we don't - check this. */ + According to the specs, this should all be ASCII. */ + for (s=pinvalue; digitp (s); s++) + ; + if (*s) + { + log_error ("Non-numeric digits found in PIN\n"); + xfree (pinvalue); + return gpg_error (GPG_ERR_BAD_PIN); + } + if (strlen (pinvalue) < 6) { log_error ("PIN is too short; minimum length is 6\n"); @@ -307,6 +316,28 @@ verify_pin (app_t app, } rc = iso7816_verify (app->slot, 0x81, pinvalue, strlen (pinvalue)); + if (gpg_err_code (rc) == GPG_ERR_INV_VALUE) + { + /* We assume that ISO 9564-1 encoding is used and we failed + because the first nibble we passed was 3 and not 2. DIN + says something about looking up such an encoding in the + SSD but I was not able to find any tag relevant to + this. */ + char paddedpin[8]; + int i, ndigits; + + for (ndigits=0, s=pinvalue; *s; ndigits++, s++) + ; + i = 0; + paddedpin[i++] = 0x20 | (ndigits & 0x0f); + for (s=pinvalue; i < sizeof paddedpin && *s && s[1]; s = s+2 ) + paddedpin[i++] = (((*s - '0') << 4) | ((s[1] - '0') & 0x0f)); + if (i < sizeof paddedpin && *s) + paddedpin[i++] = (((*s - '0') << 4) | 0x0f); + while (i < sizeof paddedpin) + paddedpin[i++] = 0xff; + rc = iso7816_verify (app->slot, 0x81, paddedpin, sizeof paddedpin); + } if (rc) { log_error ("verify PIN failed\n"); @@ -404,7 +435,7 @@ app_select_dinsig (APP app) int slot = app->slot; int rc; - rc = iso7816_select_application (slot, aid, sizeof aid); + rc = iso7816_select_application (slot, aid, sizeof aid, 0); if (!rc) { app->apptype = "DINSIG"; diff --git a/scd/app-nks.c b/scd/app-nks.c index b6a3037ed..73ec8ea01 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -27,7 +27,7 @@ #include #include "scdaemon.h" - +#include "i18n.h" #include "iso7816.h" #include "app-common.h" #include "tlv.h" @@ -320,7 +320,7 @@ verify_pin (app_t app, return rc; } - /* The follwoing limits are due to TCOS but also defined in the + /* The following limits are due to TCOS but also defined in the NKS specs. */ if (strlen (pinvalue) < 6) { @@ -340,7 +340,10 @@ verify_pin (app_t app, rc = iso7816_verify (app->slot, 0, pinvalue, strlen (pinvalue)); if (rc) { - log_error ("verify PIN failed\n"); + if ( gpg_error (rc) == GPG_ERR_USE_CONDITIONS ) + log_error (_("the NullPIN has not yet been changed\n")); + else + log_error ("verify PIN failed\n"); xfree (pinvalue); return rc; } @@ -492,7 +495,7 @@ app_select_nks (APP app) int slot = app->slot; int rc; - rc = iso7816_select_application (slot, aid, sizeof aid); + rc = iso7816_select_application (slot, aid, sizeof aid, 0); if (!rc) { app->apptype = "NKS"; diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5625c729b..3d04be0be 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -1284,6 +1284,11 @@ verify_chv2 (app_t app, if (!app->did_chv2) { char *pinvalue; + iso7816_pininfo_t pininfo; + + memset (&pininfo, 0, sizeof pininfo); + pininfo.mode = 1; + pininfo.minlen = 6; rc = pincb (pincb_arg, "PIN", &pinvalue); if (rc) @@ -2455,7 +2460,9 @@ app_select_openpgp (app_t app) size_t buflen; void *relptr; - rc = iso7816_select_application (slot, aid, sizeof aid); + /* Note that the card can't cope with P2=0xCO, thus we need to pass a + special flag value. */ + rc = iso7816_select_application (slot, aid, sizeof aid, 0x0001); if (!rc) { unsigned int manufacturer; diff --git a/scd/app-p15.c b/scd/app-p15.c index 739a9ef95..8bb94cfcd 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -3268,18 +3268,15 @@ app_select_p15 (app_t app) int direct = 0; int is_belpic = 0; - rc = iso7816_select_application (slot, pkcs15_aid, sizeof pkcs15_aid); - if (rc) - { - rc = iso7816_select_application (slot, pkcs15be_aid,sizeof pkcs15be_aid); - if (!rc) - is_belpic = 1; - } + rc = iso7816_select_application (slot, pkcs15_aid, sizeof pkcs15_aid, 0); if (rc) { /* Not found: Try to locate it from 2F00. We use direct path selection here because it seems that the Belgian eID card does only allow for that. Many other cards supports this - selection method too. */ + selection method too. Note, that we don't use + select_application above for the Belgian card - the call + works but it seems that it did not switch to the correct DF. + Using the 2f02 just works. */ unsigned short path[1] = { 0x2f00 }; rc = iso7816_select_path (app->slot, path, 1, NULL, NULL); diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index f82d93b00..fee733358 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1240,7 +1240,9 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, if (CCID_COMMAND_FAILED (buffer)) print_command_failed (buffer); - /* Check whether a card is at all available. */ + /* Check whether a card is at all available. Note: If you add new + error codes here, check whether they need to be ignored in + send_escape_cmd. */ switch ((buffer[7] & 0x03)) { case 0: /* no error */ break; @@ -1253,16 +1255,23 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, /* Note that this function won't return the error codes NO_CARD or - CARD_INACTIVE */ + CARD_INACTIVE. IF RESULT is not NULL, the result from the + operation will get returned in RESULT and its length in RESULTLEN. + If the response is larger than RESULTMAX, an error is returned and + the required buffer length returned in RESULTLEN. */ static int send_escape_cmd (ccid_driver_t handle, - const unsigned char *data, size_t datalen) + const unsigned char *data, size_t datalen, + unsigned char *result, size_t resultmax, size_t *resultlen) { int i, rc; unsigned char msg[100]; size_t msglen; unsigned char seqno; + if (resultlen) + *resultlen = 0; + if (datalen > sizeof msg - 10) return CCID_DRIVER_ERR_INV_VALUE; /* Escape data too large. */ @@ -1285,11 +1294,42 @@ send_escape_cmd (ccid_driver_t handle, return rc; rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Escape, seqno, 5000, 0); - + if (result) + switch (rc) + { + /* We need to ignore certain errorcode here. */ + case 0: + case CCID_DRIVER_ERR_CARD_INACTIVE: + case CCID_DRIVER_ERR_NO_CARD: + { + if (msglen > resultmax) + rc = CCID_DRIVER_ERR_INV_VALUE; /* Response too large. */ + else + { + memcpy (result, msg, msglen); + *resultlen = msglen; + } + rc = 0; + } + break; + default: + break; + } + return rc; } +int +ccid_transceive_escape (ccid_driver_t handle, + const unsigned char *data, size_t datalen, + unsigned char *resp, size_t maxresplen, size_t *nresp) +{ + return send_escape_cmd (handle, data, datalen, resp, maxresplen, nresp); +} + + + /* experimental */ int ccid_poll (ccid_driver_t handle) @@ -1445,7 +1485,8 @@ ccid_get_atr (ccid_driver_t handle, { tried_iso = 1; /* Try switching to ISO mode. */ - if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2)) + if (!send_escape_cmd (handle, (const unsigned char*)"\xF1\x01", 2, + NULL, 0, NULL)) goto again; } else if (CCID_COMMAND_FAILED (msg)) @@ -1957,14 +1998,16 @@ ccid_transceive (ccid_driver_t handle, } -/* Send the CCID Secure command to the reader. APDU_BUF should contain the APDU template. PIN_MODE defines now the pin gets formatted: +/* Send the CCID Secure command to the reader. APDU_BUF should + contain the APDU template. PIN_MODE defines how the pin gets + formatted: 1 := The PIN is ASCII encoded and of variable length. The length of the PIN entered will be put into Lc by the reader. The APDU should me made up of 4 bytes without Lc. PINLEN_MIN and PINLEN_MAX define the limits for the pin length. 0 - may be used t enable usbale defaults. PIN_PADLEN should be 0 + may be used t enable reasonable defaults. PIN_PADLEN should be 0. When called with RESP and NRESP set to NULL, the function will merely check whether the reader supports the secure command for the @@ -1996,7 +2039,7 @@ ccid_transceive_secure (ccid_driver_t handle, else if (apdu_buflen >= 4 && apdu_buf[1] == 0x24 && (handle->has_pinpad & 2)) return CCID_DRIVER_ERR_NOT_SUPPORTED; /* Not yet by our code. */ else - return CCID_DRIVER_ERR_NOT_SUPPORTED; + return CCID_DRIVER_ERR_NO_KEYPAD; if (pin_mode != 1) return CCID_DRIVER_ERR_NOT_SUPPORTED; @@ -2027,7 +2070,8 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_vendor == VENDOR_SCM) { DEBUGOUT ("sending escape sequence to switch to a case 1 APDU\n"); - rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3); + rc = send_escape_cmd (handle, (const unsigned char*)"\x80\x02\x00", 3, + NULL, 0, NULL); if (rc) return rc; } @@ -2044,7 +2088,7 @@ ccid_transceive_secure (ccid_driver_t handle, if (handle->id_vendor == VENDOR_SCM) { /* For the SPR532 the next 2 bytes need to be zero. We do this - for all SCM product. Kudos to to Martin Paljak for this + for all SCM product. Kudos to Martin Paljak for this hint. */ msg[13] = msg[14] = 0; } diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h index 1b9ac2f85..6f6527108 100644 --- a/scd/ccid-driver.h +++ b/scd/ccid-driver.h @@ -58,7 +58,7 @@ #ifndef CCID_DRIVER_H #define CCID_DRIVER_H -/* The CID driver returns the same error codes as the statsu words +/* The CID driver returns the same error codes as the status words used by GnuPG's apdu.h. For ease of maintenance they should always match. */ #define CCID_DRIVER_ERR_OUT_OF_CORE 0x10001 @@ -74,6 +74,7 @@ #define CCID_DRIVER_ERR_GENERAL_ERROR 0x1000b #define CCID_DRIVER_ERR_NO_READER 0x1000c #define CCID_DRIVER_ERR_ABORTED 0x1000d +#define CCID_DRIVER_ERR_NO_KEYPAD 0x1000e struct ccid_driver_s; typedef struct ccid_driver_s *ccid_driver_t; @@ -94,6 +95,10 @@ int ccid_transceive_secure (ccid_driver_t handle, int pin_mode, int pinlen_min, int pinlen_max, int pin_padlen, unsigned char *resp, size_t maxresplen, size_t *nresp); +int ccid_transceive_escape (ccid_driver_t handle, + const unsigned char *data, size_t datalen, + unsigned char *resp, size_t maxresplen, + size_t *nresp); diff --git a/scd/iso7816.c b/scd/iso7816.c index 5b985324f..5c62e1371 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -47,9 +47,9 @@ #define CMD_SELECT_FILE 0xA4 -#define CMD_VERIFY 0x20 -#define CMD_CHANGE_REFERENCE_DATA 0x24 -#define CMD_RESET_RETRY_COUNTER 0x2C +#define CMD_VERIFY ISO7816_VERIFY +#define CMD_CHANGE_REFERENCE_DATA ISO7816_CHANGE_REFERENCE_DATA +#define CMD_RESET_RETRY_COUNTER ISO7816_RESET_RETRY_COUNTER #define CMD_GET_DATA 0xCA #define CMD_PUT_DATA 0xDA #define CMD_MSE 0x22 @@ -95,6 +95,7 @@ map_sw (int sw) case SW_HOST_GENERAL_ERROR: ec = GPG_ERR_GENERAL; break; case SW_HOST_NO_READER: ec = GPG_ERR_ENODEV; break; case SW_HOST_ABORTED: ec = GPG_ERR_CANCELED; break; + case SW_HOST_NO_KEYPAD: ec = GPG_ERR_NOT_SUPPORTED; break; default: if ((sw & 0x010000)) @@ -124,12 +125,15 @@ iso7816_map_sw (int sw) requested application ID. The function can't be used to enumerate AIDs and won't return the AID on success. The return value is 0 for okay or a GPG error code. Note that ISO error codes are - internally mapped. */ + internally mapped. Bit 0 of FLAGS should be set if the card does + not understand P2=0xC0. */ gpg_error_t -iso7816_select_application (int slot, const char *aid, size_t aidlen) +iso7816_select_application (int slot, const char *aid, size_t aidlen, + unsigned int flags) { int sw; - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, 0, aidlen, aid); + sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, + (flags&1)? 0 :0x0c, aidlen, aid); return map_sw (sw); } @@ -221,27 +225,59 @@ iso7816_list_directory (int slot, int list_dirs, } +/* Check whether the reader supports the ISO command code COMMAND on + the keypad. Returns 0 on success. */ +gpg_error_t +iso7816_check_keypad (int slot, int command, iso7816_pininfo_t *pininfo) +{ + int sw; + + sw = apdu_check_keypad (slot, command, + pininfo->mode, pininfo->minlen, pininfo->maxlen, + pininfo->padlen); + return map_sw (sw); +} + /* Perform a VERIFY command on SLOT using the card holder verification - vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */ + vector CHVNO with a CHV of lenght CHVLEN. With PININFO non-NULL + the keypad of the reader will be used. Returns 0 on success. */ gpg_error_t -iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) +iso7816_verify_kp (int slot, int chvno, const char *chv, size_t chvlen, + iso7816_pininfo_t *pininfo) { int sw; - sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); + if (pininfo && pininfo->mode) + sw = apdu_send_simple_kp (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv, + pininfo->mode, + pininfo->minlen, + pininfo->maxlen, + pininfo->padlen); + else + sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); return map_sw (sw); } +/* Perform a VERIFY command on SLOT using the card holder verification + vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */ +gpg_error_t +iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen) +{ + return iso7816_verify_kp (slot, chvno, chv, chvlen, NULL); +} + /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN 0), a "change reference data" is done, otherwise an "exchange reference data". The new reference data is expected in NEWCHV of - length NEWCHVLEN. */ + length NEWCHVLEN. With PININFO non-NULL the keypad of the reader + will be used. */ gpg_error_t -iso7816_change_reference_data (int slot, int chvno, - const char *oldchv, size_t oldchvlen, - const char *newchv, size_t newchvlen) +iso7816_change_reference_data_kp (int slot, int chvno, + const char *oldchv, size_t oldchvlen, + const char *newchv, size_t newchvlen, + iso7816_pininfo_t *pininfo) { int sw; char *buf; @@ -258,28 +294,69 @@ iso7816_change_reference_data (int slot, int chvno, memcpy (buf, oldchv, oldchvlen); memcpy (buf+oldchvlen, newchv, newchvlen); - sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, - oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); + if (pininfo && pininfo->mode) + sw = apdu_send_simple_kp (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, + oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf, + pininfo->mode, + pininfo->minlen, + pininfo->maxlen, + pininfo->padlen); + else + sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, + oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); xfree (buf); return map_sw (sw); } +/* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder + verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN + 0), a "change reference data" is done, otherwise an "exchange + reference data". The new reference data is expected in NEWCHV of + length NEWCHVLEN. */ +gpg_error_t +iso7816_change_reference_data (int slot, int chvno, + const char *oldchv, size_t oldchvlen, + const char *newchv, size_t newchvlen) +{ + return iso7816_change_reference_data_kp (slot, chvno, oldchv, oldchvlen, + newchv, newchvlen, NULL); +} + + gpg_error_t -iso7816_reset_retry_counter (int slot, int chvno, - const char *newchv, size_t newchvlen) +iso7816_reset_retry_counter_kp (int slot, int chvno, + const char *newchv, size_t newchvlen, + iso7816_pininfo_t *pininfo) { int sw; if (!newchv || !newchvlen ) return gpg_error (GPG_ERR_INV_VALUE); - sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER, - 2, chvno, newchvlen, newchv); + if (pininfo && pininfo->mode) + sw = apdu_send_simple_kp (slot, 0x00, CMD_RESET_RETRY_COUNTER, + 2, chvno, newchvlen, newchv, + pininfo->mode, + pininfo->minlen, + pininfo->maxlen, + pininfo->padlen); + else + sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER, + 2, chvno, newchvlen, newchv); return map_sw (sw); } +gpg_error_t +iso7816_reset_retry_counter (int slot, int chvno, + const char *newchv, size_t newchvlen) +{ + return iso7816_reset_retry_counter_kp (slot, chvno, newchv, newchvlen, NULL); +} + + + /* Perform a GET DATA command requesting TAG and storing the result in a newly allocated buffer at the address passed by RESULT. Return the length of this data at the address of RESULTLEN. */ diff --git a/scd/iso7816.h b/scd/iso7816.h index 04c7ae63e..8f7907405 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -28,10 +28,30 @@ #include "cardglue.h" #endif +/* Command codes used by iso7816_check_keypad. */ +#define ISO7816_VERIFY 0x20 +#define ISO7816_CHANGE_REFERENCE_DATA 0x24 +#define ISO7816_RESET_RETRY_COUNTER 0x2C + + +/* Information to be passed to keypad equipped readers. See + ccid-driver.c for details. */ +struct iso7816_pininfo_s +{ + int mode; /* A mode of 0 means: Do not use the keypad. */ + int minlen; + int maxlen; + int padlen; + int padchar; +}; +typedef struct iso7816_pininfo_s iso7816_pininfo_t; + + gpg_error_t iso7816_map_sw (int sw); gpg_error_t iso7816_select_application (int slot, - const char *aid, size_t aidlen); + const char *aid, size_t aidlen, + unsigned int flags); gpg_error_t iso7816_select_file (int slot, int tag, int is_dir, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_select_path (int slot, @@ -39,13 +59,26 @@ gpg_error_t iso7816_select_path (int slot, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_list_directory (int slot, int list_dirs, unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_check_keypad (int slot, int command, + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen); +gpg_error_t iso7816_verify_kp (int slot, + int chvno, const char *chv, size_t chvlen, + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_change_reference_data (int slot, int chvno, const char *oldchv, size_t oldchvlen, const char *newchv, size_t newchvlen); +gpg_error_t iso7816_change_reference_data_kp (int slot, int chvno, + const char *oldchv, size_t oldchvlen, + const char *newchv, size_t newchvlen, + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen); +gpg_error_t iso7816_reset_retry_counter_kp (int slot, int chvno, + const char *newchv, + size_t newchvlen, + iso7816_pininfo_t *pininfo); gpg_error_t iso7816_get_data (int slot, int tag, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_put_data (int slot, int tag, diff --git a/scd/scdaemon.c b/scd/scdaemon.c index c6995abcc..56c0d7600 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -84,6 +84,7 @@ enum cmd_and_opt_values opcscDriver, oDisableCCID, oDisableOpenSC, + oDisableKeypad, oAllowAdmin, oDenyAdmin, oDisableApplication, @@ -126,6 +127,7 @@ static ARGPARSE_OPTS opts[] = { "@" #endif /* end --disable-ccid */}, + { oDisableKeypad, "disable-keypad", 0, N_("do not use a reader's keypad")}, { oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")}, { oDenyAdmin, "deny-admin", 0, "@" }, { oDisableApplication, "disable-application", 2, "@"}, @@ -135,7 +137,7 @@ static ARGPARSE_OPTS opts[] = { /* The card dirver we use by default for PC/SC. */ -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__) #define DEFAULT_PCSC_DRIVER "winscard.dll" #else #define DEFAULT_PCSC_DRIVER "libpcsclite.so" @@ -489,6 +491,8 @@ main (int argc, char **argv ) case oDisableCCID: opt.disable_ccid = 1; break; case oDisableOpenSC: break; + case oDisableKeypad: opt.disable_keypad = 1; break; + case oAllowAdmin: opt.allow_admin = 1; break; case oDenyAdmin: opt.allow_admin = 0; break; diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 54566b6ad..abe9730a7 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -39,21 +39,22 @@ #define MAX_DIGEST_LEN 24 -/* A large struct name "opt" to keep global flags */ +/* A large struct name "opt" to keep global flags. */ struct { - unsigned int debug; /* debug flags (DBG_foo_VALUE) */ - int verbose; /* verbosity level */ - int quiet; /* be as quiet as possible */ - int dry_run; /* don't change any persistent data */ - int batch; /* batch mode */ - const char *homedir; /* configuration directory name */ + unsigned int debug; /* Debug flags (DBG_foo_VALUE). */ + int verbose; /* Verbosity level. */ + int quiet; /* Be as quiet as possible. */ + int dry_run; /* Don't change any persistent data. */ + int batch; /* Batch mode. */ + const char *homedir; /* Configuration directory name. */ const char *ctapi_driver; /* Library to access the ctAPI. */ const char *pcsc_driver; /* Library to access the PC/SC system. */ const char *reader_port; /* NULL or reder port to use. */ int disable_ccid; /* Disable the use of the internal CCID driver. */ + int disable_keypad; /* Do not use a keypad. */ int allow_admin; /* Allow the use of admin commands for certain cards. */ - strlist_t disabled_applications; /* card applications we do not + strlist_t disabled_applications; /* Card applications we do not want to use. */ } opt; diff --git a/tools/ChangeLog b/tools/ChangeLog index ba4f0ec27..a57a0bccf 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,11 @@ +2005-10-19 Werner Koch + + * gpgconf-comp.c (gc_options_scdaemon): New option --disable-keypad. + +2005-09-22 Werner Koch + + * rfc822parse.c (parse_field): Tread Content-Disposition special. + 2005-10-08 Marcus Brinkmann * Makefile.am (watchgnupg_LDADD): New variable. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index e8d9ca27e..497707532 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -528,7 +528,9 @@ static gc_option_t gc_options_scdaemon[] = { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "do not use the internal CCID driver", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - + { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "do not use a reader's keypad", + GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, @@ -2447,7 +2449,8 @@ gc_component_change_options (int component, FILE *in) { #ifdef HAVE_W32_SYSTEM /* FIXME: Won't work becuase W32 doesn't silently - overwrite. */ + overwrite. Fix it by creating a backup copy and + deliting the orginal file first. */ err = rename (src_pathname[i], dest_pathname[i]); #else /*!HAVE_W32_SYSTEM*/ /* This is a bit safer than rename() because we diff --git a/tools/rfc822parse.c b/tools/rfc822parse.c index 61377e7e6..df3b2e7a4 100644 --- a/tools/rfc822parse.c +++ b/tools/rfc822parse.c @@ -766,6 +766,7 @@ parse_field (HDR_LINE hdr) } tspecial_header[] = { { "Content-Type", 12}, { "Content-Transfer-Encoding", 25}, + { "Content-Disposition", 19}, { NULL, 0} }; const char *delimiters; -- cgit From ee3f99f4e4901d216fc85f52316a83e554ae5db4 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 6 Feb 2006 18:31:27 +0000 Subject: . --- NEWS | 2 ++ scd/ccid-driver.c | 2 +- tools/ChangeLog | 4 ++++ tools/gpgconf-comp.c | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) (limited to 'tools/gpgconf-comp.c') diff --git a/NEWS b/NEWS index 963b4f2f2..b3b8d05ce 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ Noteworthy changes in version 1.9.21 * [scdaemon] Support for keypads of some readers. Tested only with SPR532. New option --disable-keypad. + * Support for CardMan 4040 PCMCIA reader. + Noteworthy changes in version 1.9.20 (2005-12-20) ------------------------------------------------- diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index e884c6624..1b04a0a85 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -1,5 +1,5 @@ /* ccid-driver.c - USB ChipCardInterfaceDevices driver - * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. * Written by Werner Koch. * * This file is part of GnuPG. diff --git a/tools/ChangeLog b/tools/ChangeLog index b0b7499eb..67dcbd860 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2005-12-20 Werner Koch + + * gpgconf-comp.c (gc_options_gpg): Add allow-pka-lookup. + 2005-12-14 Werner Koch * Makefile.am (bin_PROGRAMS): Build gpgparsemail. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 497707532..a27da3941 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -600,6 +600,9 @@ static gc_option_t gc_options_gpg[] = { "keyserver", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "gnupg", "|URL|use keyserver at URL", GC_ARG_TYPE_STRING, GC_BACKEND_GPG }, + { "allow-pka-lookup", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "gnupg", N_("allow PKA lookups (DNS requests)"), + GC_ARG_TYPE_NONE, GC_BACKEND_GPG }, GC_OPTION_NULL -- cgit From fbe4ac37f6d3e7870e26caffb0d21c3c77198297 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 May 2006 16:19:43 +0000 Subject: g10/ does build again. --- ChangeLog | 9 ++ TODO | 9 +- common/ChangeLog | 27 ++++++ common/Makefile.am | 4 +- common/gettime.c | 28 +++++- common/iobuf.h | 2 + common/miscellaneous.c | 24 ++++- common/pka.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++ common/pka.h | 27 ++++++ common/ttyio.c | 49 +++++++++- common/ttyio.h | 16 +++ common/util.h | 3 + common/yesno.c | 142 +++++++++++++++++---------- configure.ac | 57 ++++++++++- g10/ChangeLog | 40 ++++++++ g10/Makefile.am | 2 +- g10/armor.c | 2 +- g10/call-agent.c | 24 +++-- g10/call-agent.h | 17 +++- g10/card-util.c | 18 ++-- g10/gpg.c | 27 ++++-- g10/gpgv.c | 20 ---- g10/import.c | 6 +- g10/keydb.h | 1 + g10/keygen.c | 7 +- g10/keyserver.c | 9 +- g10/main.h | 1 + g10/mainproc.c | 1 + g10/misc.c | 19 +++- g10/options.h | 1 - g10/passphrase.c | 4 +- g10/pkclist.c | 8 +- g10/plaintext.c | 18 ++-- g10/pubkey-enc.c | 6 +- g10/sign.c | 2 +- g10/skclist.c | 13 +++ jnlib/ChangeLog | 19 ++++ jnlib/dotlock.c | 83 ++++++++++++---- jnlib/dotlock.h | 1 + jnlib/libjnlib-config.h | 26 ++--- jnlib/stringhelp.c | 99 ++++++++++++++++--- jnlib/stringhelp.h | 6 ++ jnlib/strlist.c | 24 ++--- jnlib/strlist.h | 4 +- scd/app-p15.c | 10 ++ sm/ChangeLog | 10 ++ sm/Makefile.am | 2 +- sm/keydb.c | 27 ------ sm/keylist.c | 4 +- tools/ChangeLog | 8 ++ tools/gpgconf-comp.c | 28 ------ tools/gpgparsemail.c | 6 +- 52 files changed, 990 insertions(+), 262 deletions(-) create mode 100644 common/pka.c create mode 100644 common/pka.h (limited to 'tools/gpgconf-comp.c') diff --git a/ChangeLog b/ChangeLog index 6e5228817..711cd4751 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-05-23 Werner Koch + + * configure.ac (ZLIBS): New for zlib link commands. Add bzip2 + support. + +2006-05-22 Werner Koch + + * configure.ac (EXEEXT): New. + 2006-04-18 Werner Koch * configure.ac (PK_UID_CACHE_SIZE): New. diff --git a/TODO b/TODO index af3a42605..7958ed18e 100644 --- a/TODO +++ b/TODO @@ -110,4 +110,11 @@ might want to have an agent context for each service request We can't do that right now because it is only defined by newer versions of libgcrypt. Changes this if we require libgcrypt 1.3 anyway. - +** skclist.c:random_is_faked + Remove the whole stuff? + +* common/ +** ttyio + Add completion support. +** yesno + Update to gpg 1.4.3 version \ No newline at end of file diff --git a/common/ChangeLog b/common/ChangeLog index f1b11fc57..36a733a7f 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,30 @@ +2006-05-23 Werner Koch + + * gettime.c (isotimestamp): New. + + * ttyio.c (tty_get_ttyname): Posixly correct usage of ctermid. + + * dns-cert.c: New. Taken from 1.4.3's util/cert.c. + * dns-cert.h: New. + +2006-05-22 Werner Koch + + * pka.c: New. Taked from 1.4.3. + * pka.h: New. + * Makefile.am: Added pka. + +2006-05-19 Werner Koch + + * yesno.c (answer_is_yes_no_default, answer_is_yes_no_quit): + Updated from 1.4.3. + (answer_is_okay_cancel): new. From 1.4.3. + + * miscellaneous.c (match_multistr): New. Taken from 1.4.3. + + * ttyio.c (tty_enable_completion, tty_disable_completion): New + dummy functions. + * ttyio.h: Add prototypes and stubs. + 2006-04-19 Werner Koch * iobuf.c (iobuf_get_fd): New. Taken from 1.4.3. diff --git a/common/Makefile.am b/common/Makefile.am index 3056be6bc..34819e93f 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -49,7 +49,9 @@ libcommon_a_SOURCES = \ w32reg.c \ signal.c \ dynload.h \ - estream.c estream.h + estream.c estream.h \ + dns-cert.c dns-cert.h \ + pka.c pka.h libsimple_pwquery_a_SOURCES = \ diff --git a/common/gettime.c b/common/gettime.c index 93e4ba113..ecdc7df95 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -201,7 +201,7 @@ strtimevalue( u32 value ) } -/**************** +/* * Note: this function returns GMT */ const char * @@ -222,6 +222,32 @@ strtimestamp( u32 stamp ) return buffer; } + +/* + * Note: this function returns GMT + */ +const char * +isotimestamp (u32 stamp) +{ + static char buffer[25+5]; + struct tm *tp; + time_t atime = stamp; + + if (atime < 0) + { + strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??"); + } + else + { + tp = gmtime ( &atime ); + sprintf (buffer,"%04d-%02d-%02d %02d:%02d:%02d", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + } + return buffer; +} + + /**************** * Note: this function returns local time */ diff --git a/common/iobuf.h b/common/iobuf.h index 431d573a1..3b8f4b572 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -145,6 +145,8 @@ void iobuf_set_partial_block_mode (iobuf_t a, size_t len); int iobuf_translate_file_handle (int fd, int for_write); +void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); + /* get a byte form the iobuf; must check for eof prior to this function * this function returns values in the range 0 .. 255 or -1 to indicate EOF diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 14d6f020d..e9f8ed27f 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -1,5 +1,5 @@ /* miscellaneous.c - Stuff not fitting elsewhere - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -47,6 +47,7 @@ print_fname_stdin (const char *s) return s; } +/* fixme: Globally replace it by print_sanitized_buffer. */ void print_string( FILE *fp, const byte *p, size_t n, int delim ) { @@ -125,4 +126,25 @@ leave: } +/* Try match against each substring of multistr, delimited by | */ +int +match_multistr (const char *multistr,const char *match) +{ + do + { + size_t seglen = strcspn (multistr,"|"); + if (!seglen) + break; + /* Using the localized strncasecmp! */ + if (strncasecmp(multistr,match,seglen)==0) + return 1; + multistr += seglen; + if (*multistr == '|') + multistr++; + } + while (*multistr); + + return 0; +} + diff --git a/common/pka.c b/common/pka.c new file mode 100644 index 000000000..3d442d16a --- /dev/null +++ b/common/pka.c @@ -0,0 +1,252 @@ +/* pka.c - DNS Public Key Association RR access + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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. + */ + +#include + +#include +#include +#include + +#ifdef USE_DNS_PKA +#include +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif +#endif /* USE_DNS_PKA */ + +#include "util.h" +#include "pka.h" + +#ifdef USE_DNS_PKA +/* Parse the TXT resource record. Format is: + + v=pka1;fpr=a4d94e92b0986ab5ee9dcd755de249965b0358a2;uri=string + + For simplicity white spaces are not allowed. Because we expect to + use a new RRTYPE for this in the future we define the TXT really + strict for simplicity: No white spaces, case sensitivity of the + names, order must be as given above. Only URI is optional. + + This function modifies BUFFER. On success 0 is returned, the 20 + byte fingerprint stored at FPR and BUFFER contains the URI or an + empty string. +*/ +static int +parse_txt_record (char *buffer, unsigned char *fpr) +{ + char *p, *pend; + int i; + + p = buffer; + pend = strchr (p, ';'); + if (!pend) + return -1; + *pend++ = 0; + if (strcmp (p, "v=pka1")) + return -1; /* Wrong or missing version. */ + + p = pend; + pend = strchr (p, ';'); + if (pend) + *pend++ = 0; + if (strncmp (p, "fpr=", 4)) + return -1; /* Missing fingerprint part. */ + p += 4; + for (i=0; i < 20 && hexdigitp (p) && hexdigitp (p+1); i++, p += 2) + fpr[i] = xtoi_2 (p); + if (i != 20) + return -1; /* Fingerprint consists not of exactly 40 hexbytes. */ + + p = pend; + if (!p || !*p) + { + *buffer = 0; + return 0; /* Success (no URI given). */ + } + if (strncmp (p, "uri=", 4)) + return -1; /* Unknown part. */ + p += 4; + /* There is an URI, copy it to the start of the buffer. */ + while (*p) + *buffer++ = *p++; + *buffer = 0; + return 0; +} + + +/* For the given email ADDRESS lookup the PKA information in the DNS. + + On success the 20 byte SHA-1 fingerprint is stored at FPR and the + URI will be returned in an allocated buffer. Note that the URI + might be an zero length string as this information is optiobnal. + Caller must xfree the returned string. + + On error NULL is returned and the 20 bytes at FPR are not + defined. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ + unsigned char answer[PACKETSZ]; + int anslen; + int qdcount, ancount, nscount, arcount; + int rc; + unsigned char *p, *pend; + const char *domain; + char *name; + + + domain = strrchr (address, '@'); + if (!domain || domain == address || !domain[1]) + return NULL; /* invalid mail address given. */ + + name = malloc (strlen (address) + 5 + 1); + memcpy (name, address, domain - address); + strcpy (stpcpy (name + (domain-address), "._pka."), domain+1); + + anslen = res_query (name, C_IN, T_TXT, answer, PACKETSZ); + xfree (name); + if (anslen < sizeof(HEADER)) + return NULL; /* DNS resolver returned a too short answer. */ + if ( (rc=((HEADER*)answer)->rcode) != NOERROR ) + return NULL; /* DNS resolver returned an error. */ + + /* We assume that PACKETSZ is large enough and don't do dynmically + expansion of the buffer. */ + if (anslen > PACKETSZ) + return NULL; /* DNS resolver returned a too long answer */ + + qdcount = ntohs (((HEADER*)answer)->qdcount); + ancount = ntohs (((HEADER*)answer)->ancount); + nscount = ntohs (((HEADER*)answer)->nscount); + arcount = ntohs (((HEADER*)answer)->arcount); + + if (!ancount) + return NULL; /* Got no answer. */ + + p = answer + sizeof (HEADER); + pend = answer + anslen; /* Actually points directly behind the buffer. */ + + while (qdcount-- && p < pend) + { + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc + QFIXEDSZ; + } + + if (ancount > 1) + return NULL; /* more than one possible gpg trustdns record - none used. */ + + while (ancount-- && p <= pend) + { + unsigned int type, class, txtlen, n; + char *buffer, *bufp; + + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc; + if (p >= pend - 10) + return NULL; /* RR too short. */ + + type = *p++ << 8; + type |= *p++; + class = *p++ << 8; + class |= *p++; + p += 4; + txtlen = *p++ << 8; + txtlen |= *p++; + if (type != T_TXT || class != C_IN) + return NULL; /* Answer does not match the query. */ + + buffer = bufp = xmalloc (txtlen + 1); + while (txtlen && p < pend) + { + for (n = *p++, txtlen--; txtlen && n && p < pend; txtlen--, n--) + *bufp++ = *p++; + } + *bufp = 0; + if (parse_txt_record (buffer, fpr)) + { + xfree (buffer); + return NULL; /* Not a valid gpg trustdns RR. */ + } + return buffer; + } + + return NULL; +} +#else /* !USE_DNS_PKA */ + +/* Dummy version of the function if we can't use the resolver + functions. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ + return NULL; +} +#endif /* !USE_DNS_PKA */ + + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + unsigned char fpr[20]; + char *uri; + int i; + + if (argc < 2) + { + fprintf (stderr, "usage: pka mail-addresses\n"); + return 1; + } + argc--; + argv++; + + for (; argc; argc--, argv++) + { + uri = get_pka_info ( *argv, fpr ); + printf ("%s", *argv); + if (uri) + { + putchar (' '); + for (i=0; i < 20; i++) + printf ("%02X", fpr[i]); + if (*uri) + printf (" %s", uri); + xfree (uri); + } + putchar ('\n'); + } + return 0; +} +#endif /* TEST */ + +/* +Local Variables: +compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv libutil.a" +End: +*/ diff --git a/common/pka.h b/common/pka.h new file mode 100644 index 000000000..d0b977d0f --- /dev/null +++ b/common/pka.h @@ -0,0 +1,27 @@ +/* pka.h - DNS Public Key Association RR access definitions + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU 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. + */ +#ifndef GNUPG_COMMON_PKA_H +#define GNUPG_COMMON_PKA_H + +char *get_pka_info (const char *address, unsigned char *fpr); + + +#endif /*GNUPG_COMMON_PKA_H*/ diff --git a/common/ttyio.c b/common/ttyio.c index 5749c59fe..c9f41c626 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -1,5 +1,6 @@ /* ttyio.c - tty i/O functions - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. + * Copyright (C) 1998,1999,2000,2001,2002,2003, + * 2004, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -45,6 +46,12 @@ #endif #include #include +#ifdef HAVE_LIBREADLINE +#include +#include +#endif + + #include "util.h" #include "memory.h" #include "ttyio.h" @@ -93,13 +100,21 @@ tty_get_ttyname (void) if (!got_name) { const char *s; + /* Note that despite our checks for these macros the function is + not necessarily thread save. We mainly do this for + portability reasons, in case L_ctermid is not defined. */ +# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_TRHEADS) + char buffer[L_ctermid]; + s = ctermid (buffer); +# else s = ctermid (NULL); +# endif if (s) name = strdup (s); got_name = 1; } -#endif - /* Assume the staandrd tty on memory error or when tehre is no +#endif /*HAVE_CTERMID*/ + /* Assume the standard tty on memory error or when tehre is no certmid. */ return name? name : "/dev/tty"; } @@ -165,6 +180,34 @@ init_ttyfp(void) } +#ifdef HAVE_LIBREADLINE +void +tty_enable_completion(rl_completion_func_t *completer) +{ +/* if( no_terminal ) */ +/* return; */ + +/* if( !initialized ) */ +/* init_ttyfp(); */ + +/* rl_attempted_completion_function=completer; */ +/* rl_inhibit_completion=0; */ +} + +void +tty_disable_completion(void) +{ +/* if( no_terminal ) */ +/* return; */ + +/* if( !initialized ) */ +/* init_ttyfp(); */ + +/* rl_inhibit_completion=1; */ +} +#endif /*HAVE_LIBREADLINE*/ + + int tty_batchmode( int onoff ) { diff --git a/common/ttyio.h b/common/ttyio.h index 6fa7400a9..6148d644a 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -20,6 +20,11 @@ #ifndef GNUPG_COMMON_TTYIO_H #define GNUPG_COMMON_TTYIO_H +#ifdef HAVE_LIBREADLINE +#include +#include +#endif + const char *tty_get_ttyname (void); int tty_batchmode (int onoff); #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) @@ -40,5 +45,16 @@ void tty_kill_prompt (void); int tty_get_answer_is_yes (const char *prompt); int tty_no_terminal (int onoff); +#ifdef HAVE_LIBREADLINE +void tty_enable_completion(rl_completion_func_t *completer); +void tty_disable_completion(void); +#else +/* Use a macro to stub out these functions since a macro has no need + to typedef a "rl_completion_func_t" which would be undefined + without readline. */ +#define tty_enable_completion(x) +#define tty_disable_completion() +#endif + #endif /*GNUPG_COMMON_TTYIO_H*/ diff --git a/common/util.h b/common/util.h index 68f5222b5..295d785c5 100644 --- a/common/util.h +++ b/common/util.h @@ -84,6 +84,7 @@ u32 scan_isodatestr (const char *string); u32 add_days_to_timestamp (u32 stamp, u16 days); const char *strtimevalue (u32 stamp); const char *strtimestamp (u32 stamp); /* GMT */ +const char *isotimestamp (u32 stamp); /* GMT */ const char *asctimestamp (u32 stamp); /* localized */ @@ -108,6 +109,7 @@ void gnupg_unblock_all_signals (void); int answer_is_yes (const char *s); int answer_is_yes_no_default (const char *s, int def_answer); int answer_is_yes_no_quit (const char *s); +int answer_is_okay_cancel (const char *s, int def_answer); /*-- xreadline.c --*/ ssize_t read_line (FILE *fp, @@ -161,6 +163,7 @@ char *make_printable_string (const void *p, size_t n, int delim); int is_file_compressed (const char *s, int *ret_rc); +int match_multistr (const char *multistr,const char *match); /*-- Simple replacement functions. */ diff --git a/common/yesno.c b/common/yesno.c index 2a96b4e5d..737071691 100644 --- a/common/yesno.c +++ b/common/yesno.c @@ -28,31 +28,33 @@ int answer_is_yes_no_default( const char *s, int def_answer ) { - const char *long_yes = _("yes"); - const char *short_yes = _("yY"); - const char *long_no = _("no"); - const char *short_no = _("nN"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + const char *short_yes = _("yY"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + const char *short_no = _("nN"); - /* Note: we have to use the local dependent strcasecmp here */ - if( !strcasecmp(s, long_yes ) ) - return 1; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - /* test for no strings to catch ambiguities for the next test */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - /* test for the english version (for those who are used to type yes) */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - return def_answer; + /* Note: we have to use the local dependent compare here. */ + if ( match_multistr(long_yes,s) ) + return 1; + if ( *s && strchr( short_yes, *s ) && !s[1] ) + return 1; + /* Test for "no" strings to catch ambiguities for the next test. */ + if ( match_multistr(long_no,s) ) + return 0; + if ( *s && strchr( short_no, *s ) && !s[1] ) + return 0; + /* Test for the english version (for those who are used to type yes). */ + if ( !ascii_strcasecmp(s, "yes" ) ) + return 1; + if ( *s && strchr( "yY", *s ) && !s[1] ) + return 1; + return def_answer; } int -answer_is_yes( const char *s ) +answer_is_yes ( const char *s ) { return answer_is_yes_no_default(s,0); } @@ -61,36 +63,76 @@ answer_is_yes( const char *s ) * Return 1 for yes, -1 for quit, or 0 for no */ int -answer_is_yes_no_quit( const char *s ) +answer_is_yes_no_quit ( const char *s ) { - const char *long_yes = _("yes"); - const char *long_no = _("no"); - const char *long_quit = _("quit"); - const char *short_yes = _("yY"); - const char *short_no = _("nN"); - const char *short_quit = _("qQ"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_quit = _("quit"); + const char *short_yes = _("yY"); + const char *short_no = _("nN"); + const char *short_quit = _("qQ"); - /* Note: We have to use the locale dependent strcasecmp */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( !strcasecmp(s, long_yes ) ) - return 1; - if( !strcasecmp(s, long_quit ) ) - return -1; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - if( *s && strchr( short_quit, *s ) && !s[1] ) - return -1; - /* but not here */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( !ascii_strcasecmp(s, "quit" ) ) - return -1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - if( *s && strchr( "qQ", *s ) && !s[1] ) - return -1; + /* Note: we have to use a local dependent compare here. */ + if ( match_multistr(long_no,s) ) return 0; + if ( match_multistr(long_yes,s) ) + return 1; + if ( match_multistr(long_quit,s) ) + return -1; + if ( *s && strchr( short_no, *s ) && !s[1] ) + return 0; + if ( *s && strchr( short_yes, *s ) && !s[1] ) + return 1; + if ( *s && strchr( short_quit, *s ) && !s[1] ) + return -1; + /* but not here. */ + if ( !ascii_strcasecmp(s, "yes" ) ) + return 1; + if ( !ascii_strcasecmp(s, "quit" ) ) + return -1; + if ( *s && strchr( "yY", *s ) && !s[1] ) + return 1; + if ( *s && strchr( "qQ", *s ) && !s[1] ) + return -1; + return 0; } + +/* + Return 1 for okay, 0 for for cancel or DEF_ANSWER for default. + */ +int +answer_is_okay_cancel (const char *s, int def_answer) +{ + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_okay = _("okay|okay"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_cancel = _("cancel|cancel"); + const char *short_okay = _("oO"); + const char *short_cancel = _("cC"); + + /* Note: We have to use the locale dependent compare. */ + if ( match_multistr(long_okay,s) ) + return 1; + if ( match_multistr(long_cancel,s) ) + return 0; + if ( *s && strchr( short_okay, *s ) && !s[1] ) + return 1; + if ( *s && strchr( short_cancel, *s ) && !s[1] ) + return 0; + /* Always test for the English values (not locale here). */ + if ( !ascii_strcasecmp(s, "okay" ) ) + return 1; + if ( !ascii_strcasecmp(s, "ok" ) ) + return 1; + if ( !ascii_strcasecmp(s, "cancel" ) ) + return 0; + if ( *s && strchr( "oO", *s ) && !s[1] ) + return 1; + if ( *s && strchr( "cC", *s ) && !s[1] ) + return 0; + return def_answer; +} + diff --git a/configure.ac b/configure.ac index 53cbc38fc..05882c2c9 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,16 @@ AC_ARG_ENABLE(agent-only, build_agent_only=$enableval) +# Allow disabling of bzib2 support. +# It is defined only after we confirm the library is available later +use_bzip2=yes +AC_MSG_CHECKING([whether to enable the BZIP2 compression algorithm]) +AC_ARG_ENABLE(bzip2, + AC_HELP_STRING([--disable-bzip2],[disable the BZIP2 compression algorithm]), + use_bzip2=$enableval) +AC_MSG_RESULT($use_bzip2) + + # Configure option to allow or disallow execution of external # programs, like a photo viewer. AC_MSG_CHECKING([whether to enable external program execution]) @@ -462,6 +472,8 @@ if test "$have_w32_system" = yes; then fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) +# These need to go after AC_PROG_CC so that $EXEEXT is defined +AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any]) # @@ -969,11 +981,13 @@ else AC_DEFINE(DISABLE_REGEX,1,[ Define to disable regular expression support ]) fi -dnl Do we have zlib? Must do it here because Solaris failed -dnl when compiling a conftest (due to the "-lz" from LIBS). +# +# Do we have zlib? Must do it here because Solaris failed +# when compiling a conftest (due to the "-lz" from LIBS). +# Note that we combine zlib and bzlib2 in ZLIBS. +# _cppflags="${CPPFLAGS}" _ldflags="${LDFLAGS}" - AC_ARG_WITH(zlib, [ --with-zlib=DIR use libz in DIR],[ if test -d "$withval"; then @@ -984,10 +998,43 @@ AC_ARG_WITH(zlib, AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, deflateInit2_, - LIBS="$LIBS -lz", + ZLIBS="-lz", CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) - + +# +# Check whether we can support bzip2 +# +if test "$use_bzip2" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + AC_ARG_WITH(bzip2, + AC_HELP_STRING([--with-bzip2=DIR],[look for bzip2 in DIR]), + [ + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + ],withval="") + + # Checking alongside stdio.h as an early version of bzip2 (1.0) + # required stdio.h to be included before bzlib.h, and Solaris 9 is + # woefully out of date. + if test "$withval" != no ; then + AC_CHECK_HEADER(bzlib.h, + AC_CHECK_LIB(bz2,BZ2_bzCompressInit, + [ + have_bz2=yes + ZLIBS="$ZLIBS -lbz2" + AC_DEFINE(HAVE_BZIP2,1, + [Defined if the bz2 compression library is available]) + ], + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags},[#include ]) + fi +fi +AM_CONDITIONAL(ENABLE_BZIP2_SUPPORT,test x"$have_bz2" = "xyes") +AC_SUBST(ZLIBS) # See wether we want to run the long test suite. diff --git a/g10/ChangeLog b/g10/ChangeLog index b8f789e8b..6018bbe13 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,43 @@ +2006-05-23 Werner Koch + + * card-util.c (generate_card_keys): Removed temporary kludge for + generate_keypair. + + * call-agent.c (agent_scd_setattr): Add arg SERIALNO. + (agent_scd_genkey): Ditto. + (agent_scd_change_pin): Ditto. + + * call-agent.h (struct agent_card_info_s): Updated to match the + one of 1.4.3. + + * Makefile.am (LDADD): Include ZLIBS. + + * gpgv.c: Removed stubs not anymore useful due to libgcrypt. + +2006-05-22 Werner Koch + + * keyserver.c (keyidlist): Replaced mpi_get_keyid by v3_keyid. + * keydb.h (v3_keyid): Added. + + * import.c (import): Better initialize KEYBLOCK as to quiet + compiler warning. + + * skclist.c (random_is_faked): New. + + * mainproc.c: Include pka.h. + +2006-05-19 Werner Koch + + * misc.c (openpgp_pk_test_algo2): Need to use gcry_pk_algo_info + directly. + (string_count_chr): New. + + * armor.c (parse_header_line): Use renamed function + length_sans_trailing_ws. + + * options.h, gpg.c: Option --strict is not used thus removed code + but kept option. + 2006-04-28 David Shaw (wk) * keyserver.c (direct_uri_map): New. diff --git a/g10/Makefile.am b/g10/Makefile.am index 1deacb9f8..aeb24d7b3 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -107,7 +107,7 @@ gpgv2_SOURCES = gpgv.c \ # ks-db.h \ # $(common_source) -LDADD = $(needed_libs) @LIBINTL@ @CAPLIBS@ @W32LIBS@ +LDADD = $(needed_libs) $(ZLIBS) @LIBINTL@ @CAPLIBS@ @W32LIBS@ gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error diff --git a/g10/armor.c b/g10/armor.c index e02591372..2336ff6f9 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -336,7 +336,7 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len ) int hashes=0; unsigned int len2; - len2 = check_trailing_ws( line, len ); + len2 = length_sans_trailing_ws ( line, len ); if( !len2 ) { afx->buffer_pos = len2; /* (it is not the fine way to do it here) */ return 0; /* WS only: same as empty line */ diff --git a/g10/call-agent.c b/g10/call-agent.c index 31c43cf13..55fc62569 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -626,10 +626,13 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info) } -/* Send an setattr command to the SCdaemon. */ +/* Send an setattr command to the SCdaemon. SERIALNO is not actually + used here but required by gpg 1.4's implementation of this code in + cardglue.c. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen) + const unsigned char *value, size_t valuelen, + const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -719,9 +722,11 @@ scd_genkey_cb (void *opaque, const char *line) return 0; } -/* Send a GENKEY command to the SCdaemon. */ +/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in + this implementation. */ int -agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) +agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -865,9 +870,10 @@ agent_scd_pkdecrypt (const char *serialno, 3: Change the admin PIN 101: Set a new PIN and reset the retry counter 102: Same as 101 + SERIALNO is not used. */ int -agent_scd_change_pin (int chvno) +agent_scd_change_pin (int chvno, const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -890,7 +896,7 @@ agent_scd_change_pin (int chvno) /* Perform a CHECKPIN operation. SERIALNO should be the serial - number of the card - optioanlly followed by the fingerprint; + number of the card - optionally followed by the fingerprint; however the fingerprint is ignored here. */ int agent_scd_checkpin (const char *serialno) @@ -910,3 +916,9 @@ agent_scd_checkpin (const char *serialno) } +/* Dummy function, only used by the gpg 1.4 implementation. */ +void +agent_clear_pin_cache (const char *sn) +{ + +} diff --git a/g10/call-agent.h b/g10/call-agent.h index 3d9f4f9bf..71044e38b 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -21,7 +21,8 @@ #define GNUPG_G10_CALL_AGENT_H -struct agent_card_info_s { +struct agent_card_info_s +{ int error; /* private. */ char *serialno; /* malloced hex string. */ char *disp_name; /* malloced. */ @@ -29,6 +30,7 @@ struct agent_card_info_s { int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ char *pubkey_url; /* malloced. */ char *login_data; /* malloced. */ + char *private_do[4]; /* malloced. */ char cafpr1valid; char cafpr2valid; char cafpr3valid; @@ -41,6 +43,9 @@ struct agent_card_info_s { char fpr1[20]; char fpr2[20]; char fpr3[20]; + u32 fpr1time; + u32 fpr2time; + u32 fpr3time; unsigned long sig_counter; int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache @@ -73,10 +78,12 @@ int agent_havekey (const char *hexkeygrip); /* Send a SETATTR command to the SCdaemon. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen); + const unsigned char *value, size_t valuelen, + const char *serialno); /* Send a GENKEY command to the SCdaemon. */ -int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); +int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno); /* Send a PKSIGN command to the SCdaemon. */ int agent_scd_pksign (const char *keyid, int hashalgo, @@ -89,11 +96,13 @@ int agent_scd_pkdecrypt (const char *serialno, char **r_buf, size_t *r_buflen); /* Change the PIN of an OpenPGP card or reset the retry counter. */ -int agent_scd_change_pin (int chvno); +int agent_scd_change_pin (int chvno, const char *serialno); /* Send the CHECKPIN command to the SCdaemon. */ int agent_scd_checkpin (const char *serialno); +/* Dummy function, only implemented by gpg 1.4. */ +void agent_clear_pin_cache (const char *sn); #endif /*GNUPG_G10_CALL_AGENT_H*/ diff --git a/g10/card-util.c b/g10/card-util.c index 0c8365405..b5a036e54 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -27,7 +27,7 @@ #include #if GNUPG_MAJOR_VERSION != 1 -#include "gpg.h" +# include "gpg.h" #endif /*GNUPG_MAJOR_VERSION != 1*/ #include "util.h" #include "i18n.h" @@ -37,13 +37,13 @@ #include "main.h" #include "keyserver-internal.h" #if GNUPG_MAJOR_VERSION == 1 -#ifdef HAVE_LIBREADLINE -#include -#include -#endif /*HAVE_LIBREADLINE*/ -#include "cardglue.h" +# ifdef HAVE_LIBREADLINE +# include +# include +# endif /*HAVE_LIBREADLINE*/ +# include "cardglue.h" #else /*GNUPG_MAJOR_VERSION!=1*/ -#include "call-agent.h" +# include "call-agent.h" #endif /*GNUPG_MAJOR_VERSION!=1*/ #define CONTROL_D ('D' - 'A' + 1) @@ -1091,12 +1091,8 @@ generate_card_keys (const char *serialno) if (check_pin_for_key_operation (&info, &forced_chv1)) goto leave; -#if GNUPG_MAJOR_VERSION == 1 generate_keypair (NULL, info.serialno, want_backup? opt.homedir:NULL); -#else - generate_keypair (NULL, info.serialno); -#endif leave: agent_release_card_info (&info); diff --git a/g10/gpg.c b/g10/gpg.c index 25b55b705..cc00ff3b5 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1376,7 +1376,7 @@ list_config(char *items) for(sl=iter->values;sl;sl=sl->next) { - print_string2(stdout,sl->d,strlen(sl->d),':',';'); + print_sanitized_string2 (stdout, sl->d, ':',';'); if(sl->next) printf(";"); } @@ -1782,13 +1782,11 @@ main (int argc, char **argv ) opt.no_perm_warn=1; else if (pargs.r_opt == oStrict ) { - opt.strict=1; - log_set_strict(1); + /* Not used */ } else if (pargs.r_opt == oNoStrict ) { - opt.strict=0; - log_set_strict(0); + /* Not used */ } } @@ -2360,8 +2358,14 @@ main (int argc, char **argv ) compress_algo_string = xstrdup(pargs.r.ret_str); } break; - case oCertDigestAlgo: cert_digest_string = xstrdup(pargs.r.ret_str); break; - case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; + case oCertDigestAlgo: + cert_digest_string = xstrdup(pargs.r.ret_str); + break; + + case oNoSecmemWarn: + gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); + break; + case oRequireSecmem: require_secmem=1; break; case oNoRequireSecmem: require_secmem=0; break; case oNoPermissionWarn: opt.no_perm_warn=1; break; @@ -2604,8 +2608,12 @@ main (int argc, char **argv ) xfree(iter); } break; - case oStrict: opt.strict=1; log_set_strict(1); break; - case oNoStrict: opt.strict=0; log_set_strict(0); break; + + case oStrict: + case oNoStrict: + /* Not used */ + break; + case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break; case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break; case oEnableProgressFilter: opt.enable_progress_filter = 1; break; @@ -3035,7 +3043,6 @@ main (int argc, char **argv ) /* Set the random seed file. */ if( use_random_seed ) { char *p = make_filename(opt.homedir, "random_seed", NULL ); - set_random_seed_file(p); gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); if (!access (p, F_OK)) register_secured_file (p); diff --git a/g10/gpgv.c b/g10/gpgv.c index 9b17b8ad3..579e58a29 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -387,26 +387,6 @@ void cipher_decrypt( gcry_cipher_hd_t c, byte *outbuf, byte *inbuf, unsigned nbytes ) {} void cipher_sync( gcry_cipher_hd_t c ) {} -/* Stubs to avoid linking to ../cipher/random.c */ -void random_dump_stats(void) {} -int quick_random_gen( int onoff ) { return -1;} -void randomize_buffer( byte *buffer, size_t length, int level ) {} -int random_is_faked() { return -1;} -byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;} -void set_random_seed_file( const char *name ) {} -void update_random_seed_file() {} -void fast_random_poll() {} - -/* Stubs to avoid linking of ../cipher/primegen.c */ -void register_primegen_progress ( void (*cb)( void *, int), void *cb_data ) {} -MPI generate_secret_prime( unsigned nbits ) { return NULL;} -MPI generate_public_prime( unsigned nbits ) { return NULL;} -MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, - gcry_mpi_t g, gcry_mpi_t **ret_factors ) { return NULL;} - -/* Do not link to ../cipher/rndlinux.c */ -void rndlinux_constructor(void) {} - /* Stubs to avoid linking to ../util/ttyio.c */ int tty_batchmode( int onoff ) { return 0; } diff --git a/g10/import.c b/g10/import.c index ee4ea95da..4526d84d7 100644 --- a/g10/import.c +++ b/g10/import.c @@ -243,7 +243,9 @@ import( IOBUF inp, const char* fname,struct stats_s *stats, unsigned char **fpr,size_t *fpr_len,unsigned int options ) { PACKET *pending_pkt = NULL; - KBNODE keyblock; + KBNODE keyblock = NULL; /* Need to initialize because gcc can't + grasp the return semantics of + read_block. */ int rc = 0; getkey_disable_caches(); @@ -596,7 +598,7 @@ check_prefs(KBNODE keyblock) if(prefs->type==PREFTYPE_SYM) { - if (openpgp_cipher_algo_test (prefs->value)) + if (openpgp_cipher_test_algo (prefs->value)) { const char *algo = gcry_cipher_algo_name (prefs->value); if(!problem) diff --git a/g10/keydb.h b/g10/keydb.h index 4923a842c..f8be6efb9 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -254,6 +254,7 @@ int parse_auto_key_locate(char *options); /*-- keyid.c --*/ int pubkey_letter( int algo ); +u32 v3_keyid (gcry_mpi_t a, u32 *ki); void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ); size_t keystrlen(void); const char *keystr(u32 *keyid); diff --git a/g10/keygen.c b/g10/keygen.c index c7a97a0fc..9c2fd6fb8 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1911,8 +1911,9 @@ ask_user_id( int mode ) /* append a warning if we do not have dev/random * or it is switched into quick testmode */ - if( quick_random_gen(-1) ) - strcpy(p, " (INSECURE!)" ); + /* FIXME: see skclist.c:random_is_faked */ + /* if( quick_random_gen(-1) ) */ + /* strcpy(p, " (INSECURE!)" ); */ /* print a note in case that UTF8 mapping has to be done */ for(p=uid; *p; p++ ) { @@ -2648,7 +2649,7 @@ read_parameter_file( const char *fname ) /* * Generate a keypair (fname is only used in batch mode) If - * CARD_SERIALNO is not NULL the fucntion will create the keys on an + * CARD_SERIALNO is not NULL the function will create the keys on an * OpenPGP Card. If BACKUP_ENCRYPTION_DIR has been set and * CARD_SERIALNO is NOT NULL, the encryption key for the card gets * generate in software, imported to the card and a backup file diff --git a/g10/keyserver.c b/g10/keyserver.c index 3127a4795..bf1bf6cdc 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -42,6 +42,9 @@ #include "trustdb.h" #include "keyserver-internal.h" #include "util.h" +#include "dns-cert.h" +#include "pka.h" + struct keyrec { @@ -1730,8 +1733,8 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) node->pkt->pkt.public_key->version>=4) { (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - mpi_get_keyid(node->pkt->pkt.public_key->pkey[0], - (*klist)[*count].u.kid); + v3_keyid (node->pkt->pkt.public_key->pkey[0], + (*klist)[*count].u.kid); (*count)++; if(*count==num) @@ -1982,7 +1985,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) if(domain) *domain='.'; - type=get_cert(look,max_cert_size,&key,fpr,fpr_len,&url); + type=get_dns_cert(look,max_cert_size,&key,fpr,fpr_len,&url); if(type==1) { int armor_status=opt.no_armor; diff --git a/g10/main.h b/g10/main.h index cd6926b69..18d11b567 100644 --- a/g10/main.h +++ b/g10/main.h @@ -84,6 +84,7 @@ u32 buffer_to_u32( const byte *buffer ); const byte *get_session_marker( size_t *rlen ); int openpgp_cipher_test_algo( int algo ); int openpgp_pk_test_algo( int algo ); +int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_algo_usage ( int algo ); int openpgp_md_test_algo( int algo ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 1f91c8ca6..67ac784dc 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -41,6 +41,7 @@ #include "trustdb.h" #include "keyserver-internal.h" #include "photoid.h" +#include "pka.h" struct kidlist_item { diff --git a/g10/misc.c b/g10/misc.c index a26aa740d..12aa6c689 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -67,6 +67,18 @@ #include "i18n.h" +static int +string_count_chr (const char *string, int c) +{ + int count; + + for (count=0; *string; string++ ) + if ( *string == c ) + count++; + return count; +} + + #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as @@ -416,12 +428,17 @@ openpgp_pk_test_algo( int algo ) int openpgp_pk_test_algo2( int algo, unsigned int use ) { + int use_buf = use; + size_t sizeof_use_buf = sizeof (use_buf); + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - return gcry_pk_test_algo2 (algo, use); + + return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, + &use_buf, &sizeof_use_buf); } int diff --git a/g10/options.h b/g10/options.h index de5fa7920..b97b2f3f9 100644 --- a/g10/options.h +++ b/g10/options.h @@ -193,7 +193,6 @@ struct int preserve_permissions; int no_homedir_creation; struct groupitem *grouplist; - int strict; int mangle_dos_filenames; int enable_progress_filter; unsigned int screen_columns; diff --git a/g10/passphrase.c b/g10/passphrase.c index c1cdf12ae..1c5cf3b27 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -1017,7 +1017,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) int pwlen = strlen(pw); assert( s2k->hash_algo ); - dek->keylen = gcry_cipher_algo_get_keylen (dek->algo ); + dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) BUG(); @@ -1065,7 +1065,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) i = gcry_md_get_algo_dlen ( s2k->hash_algo ); if( i > dek->keylen - used ) i = dek->keylen - used; - memcpy( dek->key+used, md_read(md, s2k->hash_algo), i ); + memcpy (dek->key+used, gcry_md_read (md, s2k->hash_algo), i); used += i; } gcry_md_close(md); diff --git a/g10/pkclist.c b/g10/pkclist.c index 4a12083d3..4516f6769 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -363,7 +363,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, int edit_ownertrust (PKT_public_key *pk, int mode ) { - unsigned int trust; + unsigned int trust = 0; int no_help = 0; for(;;) @@ -897,7 +897,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) else if (backlog) { /* This is part of our trick to expand and display groups. */ - answer = pop_strlist (&backlog); + answer = strlist_pop (&backlog); } else { @@ -1032,7 +1032,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname (pk, def_rec, NULL, NULL, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) ) { /* Mark any_recipients here since the default recipient would have been used if it wasn't already there. It @@ -1079,7 +1079,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) -1); goto fail; } - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) ) { /* Key found and usable. Check validity. */ int trustlevel; diff --git a/g10/plaintext.c b/g10/plaintext.c index c0a6c3e11..8032f15f0 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -282,7 +282,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, rc = gpg_error_from_errno (errno); else rc = gpg_error (GPG_ERR_EOF); - log_error("Error writing to `%s': %s\n", + log_error("error writing to `%s': %s\n", fname, strerror(errno) ); goto leave; } @@ -310,7 +310,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, { if(opt.max_output && (count+=len)>opt.max_output) { - log_error("Error writing to `%s': %s\n", + log_error("error writing to `%s': %s\n", fname,"exceeded --max-output limit\n"); rc = gpg_error (GPG_ERR_TOO_LARGE); xfree( buffer ); @@ -319,7 +319,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, else if( fwrite( buffer, 1, len, fp ) != len ) { rc = (errno? gpg_error_from_errno (errno) : gpg_error (GPG_ERR_INTERNAL)); - log_error("Error writing to `%s': %s\n", + log_error ("error writing to `%s': %s\n", fname, strerror(errno) ); xfree( buffer ); goto leave; @@ -338,16 +338,17 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, { if(opt.max_output && (++count)>opt.max_output) { - log_error("Error writing to `%s': %s\n", + log_error ("error writing to `%s': %s\n", fname,"exceeded --max-output limit\n"); rc = gpg_error (GPG_ERR_TOO_LARGE); goto leave; } else if( putc( c, fp ) == EOF ) { - log_error("Error writing to `%s': %s\n", + rc = (errno? gpg_error_from_errno (errno) + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error writing to `%s': %s\n", fname, strerror(errno) ); - rc = G10ERR_WRITE_FILE; goto leave; } } @@ -384,9 +385,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, } if( fp && fp != stdout && fclose(fp) ) { - log_error("Error closing `%s': %s\n", fname, strerror(errno) ); + rc = (errno? gpg_error_from_errno (errno) + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error closing `%s': %s\n", fname, strerror(errno) ); fp = NULL; - rc = G10ERR_WRITE_FILE; goto leave; } fp = NULL; diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 5af0d5f1d..dc0124bd4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -214,8 +214,8 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) * DEK is the encryption key (session key) with length k * CSUM */ - if( DBG_CIPHER ) - log_hexdump("DEK frame:", frame, nframe ); + if (DBG_CIPHER) + log_printhex ("DEK frame:", frame, nframe ); n=0; if (!card) { @@ -267,7 +267,7 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) goto leave; } if( DBG_CIPHER ) - log_hexdump("DEK is:", dek->key, dek->keylen ); + log_printhex ("DEK is:", dek->key, dek->keylen ); /* check that the algo is in the preferences and whether it has expired */ { PKT_public_key *pk = NULL; diff --git a/g10/sign.c b/g10/sign.c index fa3796758..3e1d7bc53 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -458,7 +458,7 @@ hash_for(PKT_secret_key *sk) else { for (prefs=opt.personal_digest_prefs; prefs->type; prefs++) - if (gcry_md-get_algo_dlen (prefs->value) == qbytes) + if (gcry_md_get_algo_dlen (prefs->value) == qbytes) return prefs->value; } } diff --git a/g10/skclist.c b/g10/skclist.c index afaa73814..d8f3b2dc1 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -36,6 +36,19 @@ #include "cipher.h" +/* There is currently no way to get the status of the quick random + generator flag from libgcrypt and it is not clear whether this + faked RNG is really a good idea. Thus for now we use this stub + function but we should consider to entirely remove this fake RNG + stuff. */ +static int +random_is_faked (void) +{ + return 0; +} + + + void release_sk_list( SK_LIST sk_list ) { diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index f3074c6af..61d12d580 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,22 @@ +2006-05-23 Werner Koch + + * libjnlib-config.h (JNLIB_NEED_UTF8CONV): Fixed typo in name. + + * dotlock.c (release_dotlock): Don't act if we don't have any + locks at all. + (destroy_dotlock): New. From 1.4.3. + (dotlock_remove_lockfiles): Make use of destroy function. + +2006-05-19 Werner Koch + + * strlist.c (append_to_strlist2): Enabled. + + * stringhelp.c (print_sanitized_buffer2): New. Changed the rules + to match the behaviour of print_string2 from gnupg 1.4.3. + (print_sanitized_buffer): Use the new function. + (print_sanitized_string2): New. + (hextobyte): New. Taken from gpg 1.4.3. + 2006-04-28 Werner Koch * stringhelp.c (print_sanitized_buffer): Fix bug where the count diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c index a50a0ee99..b7f892717 100644 --- a/jnlib/dotlock.c +++ b/jnlib/dotlock.c @@ -1,5 +1,6 @@ /* dotlock.c - dotfile locking - * Copyright (C) 1998,2000,2001,2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 2000, 2001, 2003, 2004, + * 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -149,9 +150,9 @@ create_dotlock( const char *file_to_lock ) dirpart = file_to_lock; } - #ifdef _REENTRANT +#ifdef _REENTRANT /* fixme: aquire mutex on all_lockfiles */ - #endif +#endif h->next = all_lockfiles; all_lockfiles = h; @@ -202,15 +203,54 @@ create_dotlock( const char *file_to_lock ) return NULL; } - #ifdef _REENTRANT +# ifdef _REENTRANT /* release mutex */ - #endif +# endif #endif /* !HAVE_DOSISH_SYSTEM */ h->lockname = jnlib_xmalloc( strlen(file_to_lock) + 6 ); strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); return h; } + +void +destroy_dotlock ( DOTLOCK h ) +{ +#if !defined (HAVE_DOSISH_SYSTEM) + if ( h ) + { + DOTLOCK hprev, htmp; + + /* First remove the handle from our global list of all locks. */ + for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) + if (htmp == h) + { + if (hprev) + hprev->next = htmp->next; + else + all_lockfiles = htmp->next; + h->next = NULL; + break; + } + + /* Second destroy the lock. */ + if (!h->disable) + { + if (h->locked && h->lockname) + unlink (h->lockname); + if (h->tname) + unlink (h->tname); + jnlib_free (h->tname); + jnlib_free (h->lockname); + } + jnlib_free(h); + + } +#endif +} + + + static int maybe_deadlock( DOTLOCK h ) { @@ -331,6 +371,13 @@ release_dotlock( DOTLOCK h ) #else int pid; + /* To avoid atexit race conditions we first check whether there + are any locks left. It might happen that another atexit + handler tries to release the lock while the atexit handler of + this module already ran and thus H is undefined. */ + if(!all_lockfiles) + return 0; + if( h->disable ) { return 0; } @@ -414,22 +461,16 @@ void dotlock_remove_lockfiles() { #ifndef HAVE_DOSISH_SYSTEM - DOTLOCK h, h2; - - h = all_lockfiles; - all_lockfiles = NULL; - - while( h ) { - h2 = h->next; - if (!h->disable ) { - if( h->locked ) - unlink( h->lockname ); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h->lockname); - } - jnlib_free(h); - h = h2; + DOTLOCK h, h2; + + h = all_lockfiles; + all_lockfiles = NULL; + + while ( h ) + { + h2 = h->next; + destroy_dotlock (h); + h = h2; } #endif } diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h index 9235687df..2cb39008a 100644 --- a/jnlib/dotlock.h +++ b/jnlib/dotlock.h @@ -26,6 +26,7 @@ typedef struct dotlock_handle *DOTLOCK; void disable_dotlock (void); DOTLOCK create_dotlock(const char *file_to_lock); +void destroy_dotlock ( DOTLOCK h ); int make_dotlock (DOTLOCK h, long timeout); int release_dotlock (DOTLOCK h); void dotlock_remove_lockfiles (void); diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h index 8ae2a9ce9..da3991432 100644 --- a/jnlib/libjnlib-config.h +++ b/jnlib/libjnlib-config.h @@ -30,31 +30,31 @@ #include "logging.h" /* We require support for utf-8 conversion. */ -#define JNLIB_NEED_UTF8CONF 1 +#define JNLIB_NEED_UTF8CONV 1 #ifdef USE_SIMPLE_GETTEXT int set_gettext_file( const char *filename ); const char *gettext( const char *msgid ); - #define _(a) gettext (a) - #define N_(a) (a) +# define _(a) gettext (a) +# define N_(a) (a) #else #ifdef HAVE_LOCALE_H - #include +# include #endif #ifdef ENABLE_NLS - #include - #define _(a) gettext (a) - #ifdef gettext_noop - #define N_(a) gettext_noop (a) - #else - #define N_(a) (a) - #endif +# include +# define _(a) gettext (a) +# ifdef gettext_noop +# define N_(a) gettext_noop (a) +# else +# define N_(a) (a) +# endif #else - #define _(a) (a) - #define N_(a) (a) +# define _(a) (a) +# define N_(a) (a) #endif #endif /* !USE_SIMPLE_GETTEXT */ diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index d5a2c29b6..27b8a25e8 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -218,8 +218,8 @@ length_sans_trailing_chars (const unsigned char *line, size_t len, return len; } -/**************** - * remove trailing white spaces and return the length of the buffer +/* + * Return the length of line ignoring trailing white-space. */ size_t length_sans_trailing_ws (const unsigned char *line, size_t len) @@ -336,34 +336,86 @@ compare_filenames( const char *a, const char *b ) #endif } + +/* Convert 2 hex characters at S to a byte value. Return this value + or -1 if there is an error. */ +int +hextobyte (const char *s) +{ + int c; + + if ( *s >= '0' && *s <= '9' ) + c = 16 * (*s - '0'); + else if ( *s >= 'A' && *s <= 'F' ) + c = 16 * (10 + *s - 'A'); + else if ( *s >= 'a' && *s <= 'f' ) + c = 16 * (10 + *s - 'a'); + else + return -1; + s++; + if ( *s >= '0' && *s <= '9' ) + c += *s - '0'; + else if ( *s >= 'A' && *s <= 'F' ) + c += 10 + *s - 'A'; + else if ( *s >= 'a' && *s <= 'f' ) + c += 10 + *s - 'a'; + else + return -1; + return c; +} + + /* Print a BUFFER to stream FP while replacing all control characters - and the character DELIM with standard C escape sequences. Returns - the number of characters printed. */ + and the characters DELIM and DELIM2 with standard C escape + sequences. Returns the number of characters printed. */ size_t -print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim) +print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length, + int delim, int delim2) { const unsigned char *p = buffer; size_t count = 0; for (; length; length--, p++, count++) { - if (*p < 0x20 || *p == 0x7f || *p == delim) + /* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */ + if (*p < 0x20 + || (*p >= 0x7f && *p < 0xa0) + || *p == delim + || *p == delim2 + || ((delim || delim2) && *p=='\\')) { putc ('\\', fp); count++; if (*p == '\n') - putc ('n', fp); + { + putc ('n', fp); + count++; + } else if (*p == '\r') - putc ('r', fp); + { + putc ('r', fp); + count++; + } else if (*p == '\f') - putc ('f', fp); + { + putc ('f', fp); + count++; + } else if (*p == '\v') - putc ('v', fp); + { + putc ('v', fp); + count++; + } else if (*p == '\b') - putc ('b', fp); + { + putc ('b', fp); + count++; + } else if (!*p) - putc('0', fp); + { + putc('0', fp); + count++; + } else { fprintf (fp, "x%02x", *p); @@ -371,12 +423,24 @@ print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, } } else - putc (*p, fp); + { + putc (*p, fp); + count++; + } } return count; } +/* Same as print_sanitized_buffer2 but with just one delimiter. */ +size_t +print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, + int delim) +{ + return print_sanitized_buffer2 (fp, buffer, length, delim, 0); +} + + size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim) @@ -404,6 +468,13 @@ print_sanitized_utf8_buffer (FILE *fp, const void *buffer, } +size_t +print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2) +{ + return string? print_sanitized_buffer2 (fp, string, strlen (string), + delim, delim2):0; +} + size_t print_sanitized_string (FILE *fp, const char *string, int delim) { diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 4c9e66452..405d6dbc4 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -40,11 +40,17 @@ char *make_dirname(const char *filepath); char *make_filename( const char *first_part, ... ); int compare_filenames( const char *a, const char *b ); +int hextobyte (const char *s); + size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, int delim); +size_t print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length, + int delim, int delim2); size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim); size_t print_sanitized_string (FILE *fp, const char *string, int delim); +size_t print_sanitized_string2 (FILE *fp, const char *string, + int delim, int delim2); size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); char *sanitize_buffer (const void *p, size_t n, int delim); diff --git a/jnlib/strlist.c b/jnlib/strlist.c index d1924c102..52b4d5869 100644 --- a/jnlib/strlist.c +++ b/jnlib/strlist.c @@ -95,22 +95,24 @@ append_to_strlist( strlist_t *list, const char *string ) return sl; } -#if 0 + +#ifdef JNLIB_NEED_UTF8CONV strlist_t append_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) { - strlist_t sl; - - if( is_utf8 ) - sl = append_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = append_to_strlist( list, p ); - m_free( p ); + strlist_t sl; + + if( is_utf8 ) + sl = append_to_strlist( list, string ); + else + { + char *p = native_to_utf8 (string); + sl = append_to_strlist( list, p ); + jnlib_free( p ); } - return sl; + return sl; } -#endif +#endif /* JNLIB_NEED_UTF8CONV */ /* Return a copy of LIST. */ diff --git a/jnlib/strlist.h b/jnlib/strlist.h index 47ac5bd4e..3c1252a44 100644 --- a/jnlib/strlist.h +++ b/jnlib/strlist.h @@ -35,11 +35,11 @@ strlist_t add_to_strlist (strlist_t *list, const char *string); strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8); strlist_t append_to_strlist (strlist_t *list, const char *string); +strlist_t append_to_strlist2 (strlist_t *list, const char *string, + int is_utf8); strlist_t strlist_copy (strlist_t list); -/*strlist_t append_to_strlist2( strlist_t *list, const char *string, - int is_utf8);*/ strlist_t strlist_prev (strlist_t head, strlist_t node); strlist_t strlist_last (strlist_t node); char * strlist_pop (strlist_t *list); diff --git a/scd/app-p15.c b/scd/app-p15.c index 8bb94cfcd..4203a6840 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -18,6 +18,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +/* Information pertaining to the BELPIC developer card samples: + + Unblock PUK: "222222111111" + Reset PIN: "333333111111") + + e.g. the APDUs 00:20:00:02:08:2C:33:33:33:11:11:11:FF + and 00:24:01:01:08:24:12:34:FF:FF:FF:FF:FF + should change the PIN into 1234. +*/ + #include #include #include diff --git a/sm/ChangeLog b/sm/ChangeLog index f161d444c..48e8473fa 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,9 @@ +2006-05-23 Werner Koch + + * keydb.c (hextobyte): Deleted as it is now defined in jnlib. + + * Makefile.am (gpgsm_LDADD): Include ZLIBS. + 2006-05-19 Marcus Brinkmann * keydb.c (keydb_insert_cert): Do not lock here, but only check if @@ -9,6 +15,10 @@ * delete.c (delete_one): Add new argument to invocation of keydb_delete. +2006-05-15 Werner Koch + + * keylist.c (print_names_raw): Sanitize URI. + 2006-03-21 Werner Koch * certchain.c (get_regtp_ca_info): New. diff --git a/sm/Makefile.am b/sm/Makefile.am index aba2081f8..b5882ae1d 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -56,6 +56,6 @@ gpgsm_SOURCES = \ gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ ../common/libcommon.a ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) -lgpg-error \ - $(LIBINTL) $(PTH_LIBS) + $(LIBINTL) $(PTH_LIBS) $(ZLIBS) diff --git a/sm/keydb.c b/sm/keydb.c index 15f5dbdac..d5932135d 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -1009,33 +1009,6 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) } -static int -hextobyte (const char *string) -{ - const unsigned char *s = (const unsigned char *)string; - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if ( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if ( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if ( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if ( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if ( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - - static int classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, diff --git a/sm/keylist.c b/sm/keylist.c index 51a066dab..b744a157f 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -529,7 +529,9 @@ print_names_raw (FILE *fp, int indent, ksba_name_t name) for (idx=0; (s = ksba_name_enum (name, idx)); idx++) { char *p = ksba_name_get_uri (name, idx); - printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s); + printf ("%*s", idx||indent_all?indent:0, ""); + print_sanitized_string (fp, p?p:s, 0); + putc ('\n', fp); xfree (p); } } diff --git a/tools/ChangeLog b/tools/ChangeLog index 67dcbd860..4ac20ae0b 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,11 @@ +2006-05-23 Werner Koch + + * gpgparsemail.c: Include config.h if available + (stpcpy): Conditional include it. + + * gpgconf-comp.c (hextobyte): Removed as it is now availble in + jnlib. + 2005-12-20 Werner Koch * gpgconf-comp.c (gc_options_gpg): Add allow-pka-lookup. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index a27da3941..2da88bc49 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -998,34 +998,6 @@ percent_escape (const char *src) } -/* Convert two hexadecimal digits from STR to the value they - represent. Returns -1 if one of the characters is not a - hexadecimal digit. */ -static int -hextobyte (const char *str) -{ - int val = 0; - int i; - -#define NROFHEXDIGITS 2 - for (i = 0; i < NROFHEXDIGITS; i++) - { - if (*str >= '0' && *str <= '9') - val += *str - '0'; - else if (*str >= 'A' && *str <= 'F') - val += 10 + *str - 'A'; - else if (*str >= 'a' && *str <= 'f') - val += 10 + *str - 'a'; - else - return -1; - if (i < NROFHEXDIGITS - 1) - val *= 16; - str++; - } - return val; -} - - /* Percent-Deescape special characters. The string is valid until the next invocation of the function. */ diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index da56093c3..566f5747f 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -24,6 +24,9 @@ for the content of the line. Several options are available to scrutinize the message. S/MIME and OpenPGP support is included. */ +#ifdef HAVE_CONFIG_H +#include +#endif #include #include @@ -145,6 +148,7 @@ xstrdup (const char *string) return p; } +#ifndef HAVE_STPCPY static char * stpcpy (char *a,const char *b) { @@ -154,7 +158,7 @@ stpcpy (char *a,const char *b) return (char*)a; } - +#endif static int run_gnupg (int smime, int sig_fd, int data_fd, int *close_list) -- cgit From f98537733ac96fd7e786286944fd3c2696229c4f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 20 Jun 2006 17:21:37 +0000 Subject: Updated FSF's address. --- Makefile.am | 3 ++- NEWS | 3 +++ TODO | 5 ++--- agent/Makefile.am | 3 ++- agent/agent.h | 3 ++- agent/cache.c | 3 ++- agent/call-scd.c | 3 ++- agent/command-ssh.c | 4 ++-- agent/command.c | 3 ++- agent/divert-scd.c | 3 ++- agent/findkey.c | 3 ++- agent/genkey.c | 3 ++- agent/gpg-agent.c | 3 ++- agent/learncard.c | 3 ++- agent/minip12.c | 3 ++- agent/minip12.h | 3 ++- agent/pkdecrypt.c | 3 ++- agent/pksign.c | 3 ++- agent/preset-passphrase.c | 3 ++- agent/protect-tool.c | 3 ++- agent/protect.c | 3 ++- agent/query.c | 3 ++- agent/t-protect.c | 3 ++- agent/trans.c | 3 ++- agent/trustlist.c | 3 ++- am/cmacros.am | 3 ++- common/Makefile.am | 3 ++- common/asshelp.c | 3 ++- common/asshelp.h | 3 ++- common/b64enc.c | 3 ++- common/dynload.h | 3 ++- common/errors.h | 3 ++- common/estream.c | 37 +++++++++++++++++++------------------ common/estream.h | 37 +++++++++++++++++++------------------ common/exechelp.c | 3 ++- common/exechelp.h | 3 ++- common/gettime.c | 3 ++- common/homedir.c | 3 ++- common/i18n.h | 3 ++- common/iobuf.c | 3 ++- common/iobuf.h | 3 ++- common/isascii.c | 3 ++- common/maperror.c | 3 ++- common/membuf.c | 3 ++- common/membuf.h | 3 ++- common/miscellaneous.c | 3 ++- common/mkerrors | 3 ++- common/mkerrtok | 3 ++- common/sexp-parse.h | 3 ++- common/sexputil.c | 3 ++- common/signal.c | 3 ++- common/simple-gettext.c | 3 ++- common/simple-pwquery.c | 3 ++- common/simple-pwquery.h | 3 ++- common/sysutils.c | 3 ++- common/sysutils.h | 3 ++- common/ttyio.c | 3 ++- common/ttyio.h | 3 ++- common/util.h | 3 ++- common/vasprintf.c | 4 ++-- common/w32reg.c | 3 ++- common/xasprintf.c | 3 ++- common/xreadline.c | 3 ++- common/yesno.c | 3 ++- configure.ac | 3 ++- doc/Makefile.am | 3 ++- doc/gnupg-card-architecture.fig | 3 ++- g10/Makefile.am | 3 ++- g10/call-agent.c | 3 ++- g10/call-agent.h | 3 ++- g10/comment.c | 3 ++- g10/gpg.c | 9 +++++++++ g10/gpg.h | 3 ++- g10/pkglue.c | 3 ++- g10/pkglue.h | 3 ++- include/_regex.h | 4 ++-- include/errors.h | 3 ++- include/memory.h | 3 ++- include/mpi.h | 3 ++- include/util.h | 3 ++- jnlib/Makefile.am | 3 ++- jnlib/argparse.c | 30 ++++++++++++++++-------------- jnlib/argparse.h | 3 ++- jnlib/dotlock.c | 3 ++- jnlib/dotlock.h | 3 ++- jnlib/libjnlib-config.h | 3 ++- jnlib/logging.c | 3 ++- jnlib/logging.h | 3 ++- jnlib/mischelp.h | 3 ++- jnlib/stringhelp.c | 3 ++- jnlib/stringhelp.h | 3 ++- jnlib/strlist.c | 3 ++- jnlib/strlist.h | 3 ++- jnlib/types.h | 3 ++- jnlib/utf8conv.c | 3 ++- jnlib/utf8conv.h | 3 ++- jnlib/w32-afunix.c | 3 ++- jnlib/w32-afunix.h | 3 ++- jnlib/w32-pth.c | 3 ++- jnlib/w32-pth.h | 3 ++- jnlib/xmalloc.c | 3 ++- jnlib/xmalloc.h | 3 ++- kbx/Makefile.am | 3 ++- kbx/kbxutil.c | 3 ++- kbx/keybox-blob.c | 3 ++- kbx/keybox-defs.h | 3 ++- kbx/keybox-dump.c | 3 ++- kbx/keybox-file.c | 3 ++- kbx/keybox-init.c | 3 ++- kbx/keybox-openpgp.c | 3 ++- kbx/keybox-search-desc.h | 3 ++- kbx/keybox-search.c | 3 ++- kbx/keybox-update.c | 3 ++- kbx/keybox-util.c | 3 ++- kbx/keybox.h | 3 ++- kbx/mkerrors | 3 ++- scd/Makefile.am | 3 ++- scd/app-common.h | 3 ++- scd/app-dinsig.c | 3 ++- scd/app-help.c | 3 ++- scd/app-nks.c | 3 ++- scd/app-openpgp.c | 3 ++- scd/app-p15.c | 3 ++- scd/app.c | 3 ++- scd/atr.c | 3 ++- scd/atr.h | 3 ++- scd/card-common.h | 3 ++- scd/card-dinsig.c | 3 ++- scd/card-p15.c | 3 ++- scd/card.c | 3 ++- scd/command.c | 3 ++- scd/sc-copykeys.c | 3 ++- scd/scdaemon.c | 3 ++- scd/scdaemon.h | 3 ++- scd/tlv.c | 3 ++- scd/tlv.h | 3 ++- scripts/compile | 3 ++- scripts/config.guess | 3 ++- sm/ChangeLog | 7 +++++++ sm/Makefile.am | 3 ++- sm/base64.c | 3 ++- sm/call-agent.c | 3 ++- sm/call-dirmngr.c | 3 ++- sm/certchain.c | 3 ++- sm/certcheck.c | 3 ++- sm/certdump.c | 3 ++- sm/certlist.c | 3 ++- sm/certreqgen.c | 3 ++- sm/decrypt.c | 3 ++- sm/delete.c | 3 ++- sm/encrypt.c | 3 ++- sm/export.c | 3 ++- sm/fingerprint.c | 3 ++- sm/gpgsm.c | 16 ++++++++++++---- sm/gpgsm.h | 3 ++- sm/import.c | 3 ++- sm/keydb.c | 3 ++- sm/keydb.h | 3 ++- sm/keylist.c | 7 ++++++- sm/misc.c | 3 ++- sm/qualified.c | 3 ++- sm/server.c | 3 ++- sm/sign.c | 3 ++- sm/verify.c | 3 ++- tests/Makefile.am | 3 ++- tests/asschk.c | 3 ++- tests/pkits/Makefile.am | 3 ++- tests/pkits/common.sh | 3 ++- tests/pkits/import-all-certs | 3 ++- tests/pkits/validate-all-certs | 3 ++- tools/Makefile.am | 3 ++- tools/gpg-connect-agent.c | 3 ++- tools/gpgconf-comp.c | 36 +++++++++++++++++++----------------- tools/gpgconf.c | 3 ++- tools/gpgconf.h | 3 ++- tools/gpgkey2ssh.c | 37 +++++++++++++++++++------------------ tools/gpgparsemail.c | 3 ++- tools/no-libgcrypt.c | 3 ++- tools/symcryptrun.c | 3 ++- tools/watchgnupg.c | 3 ++- 180 files changed, 469 insertions(+), 265 deletions(-) (limited to 'tools/gpgconf-comp.c') diff --git a/Makefile.am b/Makefile.am index 9fafb1102..0c5fbe4c3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/NEWS b/NEWS index 6413242c6..679bf7d5b 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ Noteworthy changes in version 1.9.21 * [scdaemon] Added --hash=xxx option to the PKSIGN command. + * [gpg-protect-tool] Does now create a MAC for P12 files. This is for + better interoperability. + Noteworthy changes in version 1.9.20 (2005-12-20) ------------------------------------------------- diff --git a/TODO b/TODO index 7958ed18e..da3a76e06 100644 --- a/TODO +++ b/TODO @@ -21,7 +21,7 @@ might want to have an agent context for each service request ** When a certificate chain was sucessfully verified, make ephemeral certs used in this chain permanent. ** Try to keep certificate references somewhere This will help with some of our caching code. We also need to test - that cachining; in particular "regtp_ca_chainlen". + that caching; in particular "regtp_ca_chainlen". * sm/decrypt.c ** replace leading zero in integer hack by a cleaner solution @@ -101,7 +101,6 @@ might want to have an agent context for each service request * sm/ -** --include-certs is as of now still a dummy command line option ** check that we issue NO_SECKEY xxx if a -u key was not found * gpg/ @@ -117,4 +116,4 @@ might want to have an agent context for each service request ** ttyio Add completion support. ** yesno - Update to gpg 1.4.3 version \ No newline at end of file + Update to gpg 1.4.3 version diff --git a/agent/Makefile.am b/agent/Makefile.am index bc96531e0..961f0bb97 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/agent/agent.h b/agent/agent.h index 1542d6b9f..fdfe510fb 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef AGENT_H diff --git a/agent/cache.c b/agent/cache.c index 32b6ac0c7..2f468396d 100644 --- a/agent/cache.c +++ b/agent/cache.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/call-scd.c b/agent/call-scd.c index ff241ce41..d0d24f9d5 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 23f083c2f..18375a9ae 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -15,8 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* Only v2 of the ssh-agent protocol is implemented. */ diff --git a/agent/command.c b/agent/command.c index daf9b8698..12770dac8 100644 --- a/agent/command.c +++ b/agent/command.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* FIXME: we should not use the default assuan buffering but setup diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 926df2622..3dc7984e6 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/findkey.c b/agent/findkey.c index 73ffb530d..3f793e5dd 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/genkey.c b/agent/genkey.c index d0319f7b4..04ee865f4 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 22bd5589d..fc2a2001a 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/learncard.c b/agent/learncard.c index 72238507f..8ddf4ee54 100644 --- a/agent/learncard.c +++ b/agent/learncard.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/minip12.c b/agent/minip12.c index 6f99bf24d..912d387d8 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H diff --git a/agent/minip12.h b/agent/minip12.h index 2fbb490d7..6275f9ccb 100644 --- a/agent/minip12.h +++ b/agent/minip12.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef MINIP12_H diff --git a/agent/pkdecrypt.c b/agent/pkdecrypt.c index 1d64c1b15..f61f0f844 100644 --- a/agent/pkdecrypt.c +++ b/agent/pkdecrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/pksign.c b/agent/pksign.c index e9df19351..9863f9de0 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index 6a9f07a3e..013c9411d 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 5f59d5e06..bb14ca1e1 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/protect.c b/agent/protect.c index 45bdae496..19f6ccbc6 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/query.c b/agent/query.c index a5a3d0153..0516bec03 100644 --- a/agent/query.c +++ b/agent/query.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/t-protect.c b/agent/t-protect.c index fee3c561d..9ddd49414 100644 --- a/agent/t-protect.c +++ b/agent/t-protect.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/agent/trans.c b/agent/trans.c index 7fa5e3d6b..5eb7d25c0 100644 --- a/agent/trans.c +++ b/agent/trans.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* To avoid any problems with the gettext implementation (there used diff --git a/agent/trustlist.c b/agent/trustlist.c index edb00650d..d234af692 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/am/cmacros.am b/am/cmacros.am index de68b6f31..7b449e2c0 100644 --- a/am/cmacros.am +++ b/am/cmacros.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. localedir = $(datadir)/locale diff --git a/common/Makefile.am b/common/Makefile.am index 34819e93f..085440bb3 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/common/asshelp.c b/common/asshelp.c index 0edaeae0e..1da899522 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/asshelp.h b/common/asshelp.h index 2d6dc79e6..9f4b5806b 100644 --- a/common/asshelp.h +++ b/common/asshelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_ASSHELP_H diff --git a/common/b64enc.c b/common/b64enc.c index 5b7a42ab3..bfc49deb6 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/dynload.h b/common/dynload.h index 2c074141f..9b67fa9ed 100644 --- a/common/dynload.h +++ b/common/dynload.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_DYNLOAD_H diff --git a/common/errors.h b/common/errors.h index f34f3ba79..131891f65 100644 --- a/common/errors.h +++ b/common/errors.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_ERRORS_H diff --git a/common/estream.c b/common/estream.c index 70b3d9c6e..c2030371b 100644 --- a/common/estream.c +++ b/common/estream.c @@ -1,22 +1,23 @@ /* estream.c - Extended stream I/O/ Library - Copyright (C) 2004 g10 Code GmbH - - This file is part of Libestream. - - Libestream is free software; you can 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. - - Libestream is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Libestream; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream is free software; you can 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. + * + * Libestream is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Libestream; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #ifdef USE_ESTREAM_SUPPORT_H # include diff --git a/common/estream.h b/common/estream.h index ebe575926..a9b4847c8 100644 --- a/common/estream.h +++ b/common/estream.h @@ -1,22 +1,23 @@ /* estream.h - Extended stream I/O/ Library - Copyright (C) 2004 g10 Code GmbH - - This file is part of Libestream. - - Libestream is free software; you can 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. - - Libestream is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Libestream; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of Libestream. + * + * Libestream is free software; you can 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. + * + * Libestream is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Libestream; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #ifndef ESTREAM_H #define ESTREAM_H diff --git a/common/exechelp.c b/common/exechelp.c index dc0a6b0e1..e64b69022 100644 --- a/common/exechelp.c +++ b/common/exechelp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/exechelp.h b/common/exechelp.h index f00d18dd8..1df029b7e 100644 --- a/common/exechelp.h +++ b/common/exechelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_EXECHELP_H diff --git a/common/gettime.c b/common/gettime.c index ecdc7df95..c4ea3283a 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/homedir.c b/common/homedir.c index a118cbac1..39d6dce20 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/i18n.h b/common/i18n.h index 0e13dca4d..0187ba265 100644 --- a/common/i18n.h +++ b/common/i18n.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_I18N_H diff --git a/common/iobuf.c b/common/iobuf.c index bbb666f67..8f7374f8c 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/iobuf.h b/common/iobuf.h index 3b8f4b572..a3dd7f1c5 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_IOBUF_H diff --git a/common/isascii.c b/common/isascii.c index 565c71664..b71febe99 100644 --- a/common/isascii.c +++ b/common/isascii.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H diff --git a/common/maperror.c b/common/maperror.c index 9efd64338..06546b501 100644 --- a/common/maperror.c +++ b/common/maperror.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/membuf.c b/common/membuf.c index 75f6bdb2a..2d35fefab 100644 --- a/common/membuf.c +++ b/common/membuf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/membuf.h b/common/membuf.h index c199363cc..9033be61e 100644 --- a/common/membuf.h +++ b/common/membuf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_MEMBUF_H diff --git a/common/miscellaneous.c b/common/miscellaneous.c index e9f8ed27f..da74f65bc 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/mkerrors b/common/mkerrors index 5a1ef33da..994c61352 100755 --- a/common/mkerrors +++ b/common/mkerrors @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. cat < diff --git a/common/simple-gettext.c b/common/simple-gettext.c index b6b851c77..56a305fd8 100644 --- a/common/simple-gettext.c +++ b/common/simple-gettext.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simplified version of gettext written by Ulrich Drepper. diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index f156ca3f1..e405c1ec0 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This module is intended as a standalone client implementation to diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index e3270d6c5..5b941d06f 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SIMPLE_PWQUERY_H diff --git a/common/sysutils.c b/common/sysutils.c index a8f6f6f5d..3e52cdaa3 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/sysutils.h b/common/sysutils.h index 08198f685..c40dbfaa9 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_SYSUTILS_H diff --git a/common/ttyio.c b/common/ttyio.c index c9f41c626..38883afa5 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/ttyio.h b/common/ttyio.h index 6148d644a..32d159863 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_TTYIO_H #define GNUPG_COMMON_TTYIO_H diff --git a/common/util.h b/common/util.h index 295d785c5..29106bf9c 100644 --- a/common/util.h +++ b/common/util.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_COMMON_UTIL_H diff --git a/common/vasprintf.c b/common/vasprintf.c index 9efea33f2..4bed8de66 100644 --- a/common/vasprintf.c +++ b/common/vasprintf.c @@ -15,8 +15,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street, +Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include diff --git a/common/w32reg.c b/common/w32reg.c index a85ac7348..84308e916 100644 --- a/common/w32reg.c +++ b/common/w32reg.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/xasprintf.c b/common/xasprintf.c index 46740a2e6..75ae18072 100644 --- a/common/xasprintf.c +++ b/common/xasprintf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/xreadline.c b/common/xreadline.c index 23aa35269..8400df330 100644 --- a/common/xreadline.c +++ b/common/xreadline.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/common/yesno.c b/common/yesno.c index 737071691..9ca513740 100644 --- a/common/yesno.c +++ b/common/yesno.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/configure.ac b/configure.ac index f3066a0a9..d77093a63 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. # Process this file with autoconf to produce a configure script. AC_PREREQ(2.52) diff --git a/doc/Makefile.am b/doc/Makefile.am index 47dd36208..dae053ec2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/doc/gnupg-card-architecture.fig b/doc/gnupg-card-architecture.fig index e5772cd0f..49351c720 100644 --- a/doc/gnupg-card-architecture.fig +++ b/doc/gnupg-card-architecture.fig @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. Landscape Center Metric diff --git a/g10/Makefile.am b/g10/Makefile.am index aeb24d7b3..fb54dd9f0 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/g10/call-agent.c b/g10/call-agent.c index 55fc62569..e3bd7ed57 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #if 0 /* let Emacs display a red warning */ diff --git a/g10/call-agent.h b/g10/call-agent.h index 71044e38b..d09b87e3a 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_CALL_AGENT_H #define GNUPG_G10_CALL_AGENT_H diff --git a/g10/comment.c b/g10/comment.c index b52104cd7..193087107 100644 --- a/g10/comment.c +++ b/g10/comment.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/g10/gpg.c b/g10/gpg.c index 52ae553c1..4235f3f7a 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -356,6 +356,7 @@ enum cmd_and_opt_values oAllowMultisigVerification, oEnableDSA2, oDisableDSA2, + oDebugAllowRun, oNoop }; @@ -701,6 +702,8 @@ static ARGPARSE_OPTS opts[] = { { oNoRequireCrossCert, "no-require-cross-certification", 0, "@"}, { oAutoKeyLocate, "auto-key-locate", 2, "@"}, { oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"}, + + { oDebugAllowRun, "debug_allow_run", 0, "@"}, {0,NULL,0,NULL} }; @@ -1684,6 +1687,7 @@ main (int argc, char **argv ) int with_fpr = 0; /* make an option out of --fingerprint */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; + int allow_run = 0; #ifdef __riscos__ opt.lock_once = 1; @@ -2663,6 +2667,8 @@ main (int argc, char **argv ) case oEnableDSA2: opt.flags.dsa2=1; break; case oDisableDSA2: opt.flags.dsa2=0; break; + case oDebugAllowRun: allow_run = 1; break; + case oNoop: break; default : pargs.err = configfp? 1:2; break; @@ -2716,6 +2722,9 @@ main (int argc, char **argv ) } #endif + if (!allow_run) + log_fatal ("This version of gpg is not ready for use, use gpg 1.4.x\n"); + /* FIXME: We should use logging to a file only in server mode; however we have not yet implemetyed that. Thus we try to get away with --batch as indication for logging to file diff --git a/g10/gpg.h b/g10/gpg.h index 8ef46fdca..100a8e349 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_GPG_H #define GNUPG_G10_GPG_H diff --git a/g10/pkglue.c b/g10/pkglue.c index f062d8366..3f9669d27 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/g10/pkglue.h b/g10/pkglue.h index 43b82785b..866960bfd 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_G10_PKGLUE_H diff --git a/include/_regex.h b/include/_regex.h index fac441dc6..ddd002484 100644 --- a/include/_regex.h +++ b/include/_regex.h @@ -16,8 +16,8 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ #ifndef _REGEX_H #define _REGEX_H 1 diff --git a/include/errors.h b/include/errors.h index ed437fa99..f3269ce5b 100644 --- a/include/errors.h +++ b/include/errors.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_INCLUDE_ERRORS_H #define GNUPG_INCLUDE_ERRORS_H diff --git a/include/memory.h b/include/memory.h index 35719da62..2e2f8fdce 100644 --- a/include/memory.h +++ b/include/memory.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef G10_MEMORY_H diff --git a/include/mpi.h b/include/mpi.h index b732923a2..7402ef6d3 100644 --- a/include/mpi.h +++ b/include/mpi.h @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * Note: This code is heavily based on the GNU MP Library. * Actually it's the same code with only minor changes in the diff --git a/include/util.h b/include/util.h index c579c152e..1d6d01366 100644 --- a/include/util.h +++ b/include/util.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef G10_UTIL_H #define G10_UTIL_H diff --git a/jnlib/Makefile.am b/jnlib/Makefile.am index 69eac4bf7..5fd48495c 100644 --- a/jnlib/Makefile.am +++ b/jnlib/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/jnlib/argparse.c b/jnlib/argparse.c index 980d1186c..15a7c546e 100644 --- a/jnlib/argparse.c +++ b/jnlib/argparse.c @@ -1,21 +1,22 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * - * This file is part of GnuPG. + * This file is part of GnuPG. * - * GnuPG is free software; you can 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. + * GnuPG is free software; you can 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. * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * 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. */ #include @@ -904,7 +905,7 @@ strusage( int level ) switch( level ) { case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2005 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2006 Free Software Foundation, Inc."; break; case 15: p = "This program comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it\n" @@ -920,7 +921,8 @@ strusage( int level ) "GNU General Public License for more details.\n\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" -"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; +"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n" +"USA.\n"; break; case 40: /* short and long usage */ case 41: p = ""; break; diff --git a/jnlib/argparse.h b/jnlib/argparse.h index e8922faa4..531622ea5 100644 --- a/jnlib/argparse.h +++ b/jnlib/argparse.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_ARGPARSE_H diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c index b7f892717..89edb7b91 100644 --- a/jnlib/dotlock.c +++ b/jnlib/dotlock.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h index 2cb39008a..1c0f05cb2 100644 --- a/jnlib/dotlock.h +++ b/jnlib/dotlock.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_DOTLOCK_H diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h index da3991432..ded6e057b 100644 --- a/jnlib/libjnlib-config.h +++ b/jnlib/libjnlib-config.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /**************** diff --git a/jnlib/logging.c b/jnlib/logging.c index c944006a5..20ba02ccd 100644 --- a/jnlib/logging.c +++ b/jnlib/logging.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/jnlib/logging.h b/jnlib/logging.h index b5c0bd741..3ad43b4ec 100644 --- a/jnlib/logging.h +++ b/jnlib/logging.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_LOGGING_H diff --git a/jnlib/mischelp.h b/jnlib/mischelp.h index 54da4cc1f..8e7f9c346 100644 --- a/jnlib/mischelp.h +++ b/jnlib/mischelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_MISCHELP_H diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index 27b8a25e8..9df852754 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 405d6dbc4..b8f4dbec0 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_STRINGHELP_H diff --git a/jnlib/strlist.c b/jnlib/strlist.c index 52b4d5869..87e121705 100644 --- a/jnlib/strlist.c +++ b/jnlib/strlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/strlist.h b/jnlib/strlist.h index 3c1252a44..ee9f1fa60 100644 --- a/jnlib/strlist.h +++ b/jnlib/strlist.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_STRLIST_H diff --git a/jnlib/types.h b/jnlib/types.h index 934b7a6ee..89d245943 100644 --- a/jnlib/types.h +++ b/jnlib/types.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_TYPES_H diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c index 4df8b7b32..9fba1ed4f 100644 --- a/jnlib/utf8conv.c +++ b/jnlib/utf8conv.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/utf8conv.h b/jnlib/utf8conv.h index 6e2ce9944..344c47f92 100644 --- a/jnlib/utf8conv.h +++ b/jnlib/utf8conv.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_UTF8CONF_H diff --git a/jnlib/w32-afunix.c b/jnlib/w32-afunix.c index c93d389da..84d799f1f 100644 --- a/jnlib/w32-afunix.c +++ b/jnlib/w32-afunix.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef _WIN32 #include diff --git a/jnlib/w32-afunix.h b/jnlib/w32-afunix.h index 367832299..d0eb8cf7e 100644 --- a/jnlib/w32-afunix.h +++ b/jnlib/w32-afunix.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef _WIN32 #ifndef W32AFUNIX_DEFS_H diff --git a/jnlib/w32-pth.c b/jnlib/w32-pth.c index 2f041c490..4107c7cb3 100644 --- a/jnlib/w32-pth.c +++ b/jnlib/w32-pth.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive diff --git a/jnlib/w32-pth.h b/jnlib/w32-pth.h index 5ef0ab240..524010d92 100644 --- a/jnlib/w32-pth.h +++ b/jnlib/w32-pth.h @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * ------------------------------------------------------------------ * This code is based on Ralf Engelschall's GNU Pth, a non-preemptive diff --git a/jnlib/xmalloc.c b/jnlib/xmalloc.c index 1cfaab9f7..f5b92ba41 100644 --- a/jnlib/xmalloc.c +++ b/jnlib/xmalloc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/jnlib/xmalloc.h b/jnlib/xmalloc.h index 150ef3664..8bfa7df79 100644 --- a/jnlib/xmalloc.h +++ b/jnlib/xmalloc.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef LIBJNLIB_XMALLOC_H diff --git a/kbx/Makefile.am b/kbx/Makefile.am index f42e517bf..063dbb4c0 100644 --- a/kbx/Makefile.am +++ b/kbx/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index 0569b5a67..19d356007 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-blob.c b/kbx/keybox-blob.c index eacc0014a..f3fe31617 100644 --- a/kbx/keybox-blob.c +++ b/kbx/keybox-blob.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/kbx/keybox-defs.h b/kbx/keybox-defs.h index 7bbed8519..ad53c71a7 100644 --- a/kbx/keybox-defs.h +++ b/kbx/keybox-defs.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef KEYBOX_DEFS_H diff --git a/kbx/keybox-dump.c b/kbx/keybox-dump.c index 495fb249e..d28611377 100644 --- a/kbx/keybox-dump.c +++ b/kbx/keybox-dump.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-file.c b/kbx/keybox-file.c index 3883ce607..e68e96cf9 100644 --- a/kbx/keybox-file.c +++ b/kbx/keybox-file.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-init.c b/kbx/keybox-init.c index 46a29978a..6c01b4f3a 100644 --- a/kbx/keybox-init.c +++ b/kbx/keybox-init.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 7401949c9..8ac713979 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simple OpenPGP parser suitable for all OpenPGP key diff --git a/kbx/keybox-search-desc.h b/kbx/keybox-search-desc.h index 4be59c27d..f3a69d0f1 100644 --- a/kbx/keybox-search-desc.h +++ b/kbx/keybox-search-desc.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* diff --git a/kbx/keybox-search.c b/kbx/keybox-search.c index 2ce3c1923..f95e6eb06 100644 --- a/kbx/keybox-search.c +++ b/kbx/keybox-search.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-update.c b/kbx/keybox-update.c index a16c18e23..bb43d287b 100644 --- a/kbx/keybox-update.c +++ b/kbx/keybox-update.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox-util.c b/kbx/keybox-util.c index ed5d93de0..6eb85ba3f 100644 --- a/kbx/keybox-util.c +++ b/kbx/keybox-util.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/kbx/keybox.h b/kbx/keybox.h index af1fc4516..0f97fb7fc 100644 --- a/kbx/keybox.h +++ b/kbx/keybox.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef KEYBOX_H diff --git a/kbx/mkerrors b/kbx/mkerrors index 5adb7bfdf..d3d096c5d 100755 --- a/kbx/mkerrors +++ b/kbx/mkerrors @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. cat < diff --git a/scd/app-nks.c b/scd/app-nks.c index 73ec8ea01..1ca8d4187 100644 --- a/scd/app-nks.c +++ b/scd/app-nks.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c index 5e9281a38..842881f3a 100644 --- a/scd/app-openpgp.c +++ b/scd/app-openpgp.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. * * $Id$ */ diff --git a/scd/app-p15.c b/scd/app-p15.c index 4203a6840..8a7732c85 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* Information pertaining to the BELPIC developer card samples: diff --git a/scd/app.c b/scd/app.c index 363e386ce..e3d42054b 100644 --- a/scd/app.c +++ b/scd/app.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/atr.c b/scd/atr.c index 6475e83f8..bd5a22621 100644 --- a/scd/atr.c +++ b/scd/atr.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/atr.h b/scd/atr.h index 5fdd57457..c70089ca5 100644 --- a/scd/atr.h +++ b/scd/atr.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef ATR_H diff --git a/scd/card-common.h b/scd/card-common.h index cefaf120f..dd7529d5b 100644 --- a/scd/card-common.h +++ b/scd/card-common.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef CARD_COMMON_H diff --git a/scd/card-dinsig.c b/scd/card-dinsig.c index df09bfb57..d50d758f2 100644 --- a/scd/card-dinsig.c +++ b/scd/card-dinsig.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* The German signature law and its bylaw (SigG and SigV) is currently diff --git a/scd/card-p15.c b/scd/card-p15.c index ae3ef148f..63d537d5a 100644 --- a/scd/card-p15.c +++ b/scd/card-p15.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/card.c b/scd/card.c index 9ec2a52c5..7a41ab7bb 100644 --- a/scd/card.c +++ b/scd/card.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/command.c b/scd/command.c index 2ed685587..4629d9edf 100644 --- a/scd/command.c +++ b/scd/command.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c index 66b6894e0..395b4625a 100644 --- a/scd/sc-copykeys.c +++ b/scd/sc-copykeys.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/scdaemon.c b/scd/scdaemon.c index e24b42132..b11cc7a91 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/scdaemon.h b/scd/scdaemon.h index abe9730a7..f9689ee09 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SCDAEMON_H diff --git a/scd/tlv.c b/scd/tlv.c index b436d956a..6ddbeaf1f 100644 --- a/scd/tlv.c +++ b/scd/tlv.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/scd/tlv.h b/scd/tlv.h index f587dd9df..877573d25 100644 --- a/scd/tlv.h +++ b/scd/tlv.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef SCD_TLV_H diff --git a/scripts/compile b/scripts/compile index ac07cc541..b6e6dcb0f 100755 --- a/scripts/compile +++ b/scripts/compile @@ -17,7 +17,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA.. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/scripts/config.guess b/scripts/config.guess index 77c7cbab0..a4929a979 100755 --- a/scripts/config.guess +++ b/scripts/config.guess @@ -17,7 +17,8 @@ timestamp='2004-08-13' # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA.. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a diff --git a/sm/ChangeLog b/sm/ChangeLog index 48e8473fa..f191e7512 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,10 @@ +2006-06-20 Werner Koch + + * gpgsm.c (gpgsm_init_default_ctrl): Take care of the command line + option --include-certs. + + * keylist.c (list_cert_raw): Print the certid. + 2006-05-23 Werner Koch * keydb.c (hextobyte): Deleted as it is now defined in jnlib. diff --git a/sm/Makefile.am b/sm/Makefile.am index b5882ae1d..be53e8d25 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -14,7 +14,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/sm/base64.c b/sm/base64.c index 62c2c9ad9..59ab6f24b 100644 --- a/sm/base64.c +++ b/sm/base64.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/call-agent.c b/sm/call-agent.c index 9942672ae..85ec78c63 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 85467d4a2..0de09a9ba 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certchain.c b/sm/certchain.c index 44d72efd3..4a4ac49f6 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certcheck.c b/sm/certcheck.c index 5fb376712..732356149 100644 --- a/sm/certcheck.c +++ b/sm/certcheck.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certdump.c b/sm/certdump.c index 1f2ea7b18..0d5146abc 100644 --- a/sm/certdump.c +++ b/sm/certdump.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certlist.c b/sm/certlist.c index b036a85d7..cde2930ec 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/certreqgen.c b/sm/certreqgen.c index c523c992a..744969719 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* diff --git a/sm/decrypt.c b/sm/decrypt.c index 9e5518b0f..70d48c983 100644 --- a/sm/decrypt.c +++ b/sm/decrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/delete.c b/sm/delete.c index 7533f7291..0d2f1fd9d 100644 --- a/sm/delete.c +++ b/sm/delete.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/encrypt.c b/sm/encrypt.c index e4c0d5437..07c2ba8ce 100644 --- a/sm/encrypt.c +++ b/sm/encrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/export.c b/sm/export.c index f9d6dac62..b08a017d2 100644 --- a/sm/export.c +++ b/sm/export.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/fingerprint.c b/sm/fingerprint.c index 9441483bf..d6a3900f0 100644 --- a/sm/fingerprint.c +++ b/sm/fingerprint.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 7347bf575..5363b8ad6 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -1,5 +1,6 @@ /* gpgsm.c - GnuPG for S/MIME - * Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, + * 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -15,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include @@ -461,6 +463,10 @@ static unsigned int debug_value; /* Option --enable-special-filenames */ static int allow_special_filenames; +/* Default value for include-certs. */ +static int default_include_certs = 1; /* Only include the signer's cert. */ + + static char *build_list (const char *text, const char *(*mapf)(int), int (*chkf)(int)); @@ -998,7 +1004,9 @@ main ( int argc, char **argv) ctrl.use_ocsp = opt.enable_ocsp = 1; break; - case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break; + case oIncludeCerts: + ctrl.include_certs = default_include_certs = pargs.r.ret_int; + break; case oPolicyFile: xfree (opt.policy_file); @@ -1657,7 +1665,7 @@ gpgsm_exit (int rc) void gpgsm_init_default_ctrl (struct server_control_s *ctrl) { - ctrl->include_certs = 1; /* only include the signer's cert */ + ctrl->include_certs = default_include_certs; ctrl->use_ocsp = opt.enable_ocsp; } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 438252050..b49f34640 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GPGSM_H diff --git a/sm/import.c b/sm/import.c index 6d00e91ea..b56014a1a 100644 --- a/sm/import.c +++ b/sm/import.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/keydb.c b/sm/keydb.c index d5932135d..81936cf6a 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/keydb.h b/sm/keydb.h index fb4001b64..814ae9f1e 100644 --- a/sm/keydb.h +++ b/sm/keydb.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GNUPG_KEYDB_H diff --git a/sm/keylist.c b/sm/keylist.c index b744a157f..9baf065d0 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -16,7 +16,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include @@ -598,6 +599,10 @@ list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd, fprintf (fp, " md5_fpr: %s\n", dn?dn:"error"); xfree (dn); + dn = gpgsm_get_certid (cert); + fprintf (fp, " certid: %s\n", dn?dn:"error"); + xfree (dn); + dn = gpgsm_get_keygrip_hexstring (cert); fprintf (fp, " keygrip: %s\n", dn?dn:"error"); xfree (dn); diff --git a/sm/misc.c b/sm/misc.c index cd072ce6b..86cb506d6 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/qualified.c b/sm/qualified.c index 07abaadc4..474e1488d 100644 --- a/sm/qualified.c +++ b/sm/qualified.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/server.c b/sm/server.c index 87a06ee4e..57e5d8f38 100644 --- a/sm/server.c +++ b/sm/server.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/sign.c b/sm/sign.c index 74bfe41aa..d656825e8 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/sm/verify.c b/sm/verify.c index f37cf4a75..4e6574078 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tests/Makefile.am b/tests/Makefile.am index 5264b8859..38b64c6ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/tests/asschk.c b/tests/asschk.c index 6a05fe1a8..40b95ba7d 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ /* This is a simple stand-alone Assuan server test program. We don't diff --git a/tests/pkits/Makefile.am b/tests/pkits/Makefile.am index 41fdec497..d53d35a25 100644 --- a/tests/pkits/Makefile.am +++ b/tests/pkits/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. ## Process this file with automake to produce Makefile.in diff --git a/tests/pkits/common.sh b/tests/pkits/common.sh index 5e773ea5d..09fb62bc8 100644 --- a/tests/pkits/common.sh +++ b/tests/pkits/common.sh @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. # reset some environment variables because we do not want to test locals export LANG=C diff --git a/tests/pkits/import-all-certs b/tests/pkits/import-all-certs index d1af5fb03..2d70d06df 100755 --- a/tests/pkits/import-all-certs +++ b/tests/pkits/import-all-certs @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. . ${srcdir:-.}/common.sh || exit 2 diff --git a/tests/pkits/validate-all-certs b/tests/pkits/validate-all-certs index f482fdb51..08f72af71 100755 --- a/tests/pkits/validate-all-certs +++ b/tests/pkits/validate-all-certs @@ -16,7 +16,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. . ${srcdir:-.}/common.sh || exit 2 diff --git a/tools/Makefile.am b/tools/Makefile.am index d9ef8812a..6b4767a79 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -15,7 +15,8 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. EXTRA_DIST = Manifest watchgnupg.c \ addgnupghome gpgsm-gencert.sh diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index c9a324fa8..90e321000 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 2da88bc49..04a61a193 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -1,21 +1,23 @@ /* gpgconf-comp.c - Configuration utility for GnuPG. - Copyright (C) 2004 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can 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. - - GnuPG is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GnuPG; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GnuPG; if not, write to the Free Software Foundation, + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ #if HAVE_CONFIG_H #include diff --git a/tools/gpgconf.c b/tools/gpgconf.c index dd505e99d..87ba45ae1 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/gpgconf.h b/tools/gpgconf.h index 138380b6d..c083c26aa 100644 --- a/tools/gpgconf.h +++ b/tools/gpgconf.h @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifndef GPGCONF_H diff --git a/tools/gpgkey2ssh.c b/tools/gpgkey2ssh.c index e874ab22e..3dcb6516e 100644 --- a/tools/gpgkey2ssh.c +++ b/tools/gpgkey2ssh.c @@ -1,22 +1,23 @@ /* gpgkey2ssh.c - Converter ... - Copyright (C) 2005 Free Software Foundation, Inc. - - This file is part of GnuPG. - - GnuPG is free software; you can 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. - - GnuPG is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can 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. + * + * GnuPG is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 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. + */ #include diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index 566f5747f..30759f9a4 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index 82f6a8bb5..636df10c6 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 075e0b444..406cbb2a2 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ diff --git a/tools/watchgnupg.c b/tools/watchgnupg.c index 6cb570fbc..051ca50fe 100644 --- a/tools/watchgnupg.c +++ b/tools/watchgnupg.c @@ -15,7 +15,8 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #ifdef HAVE_CONFIG_H -- cgit

.*o#s7lTnqu.E.s8Drq +s8Vrns8Mfnp\fMZN0oipQB[^"PnB%FOcGipPB)oPs7uZos82irqu.Q7rVH@I,;J;/SuI8WR#1bBM"&e?a5EH?2MNRdY!qYU3irorhIrr*K,qYR.' +F+]rVZ]gp\t0irqcrE:6V<1OHuF$Pl[,4rKR>I&!C"gp\k-lq#(0hr;Zcks7uZoruV1< +qYds+NC`a@rVuoqrr2rtrqu]ns8;3WnFGT-s3LZLqZ$TUm.'Q +"g=i;p\OjcrrN-!huSJ>#L-5N1%W&`Pf^2p&+gnrqkjHrr2os +s8!8'AoWL6ko`+serr2rtrWrGF9Tbj)O-Z=5Q2d*)rjGa_8+uu]s8Dlprr;p)rr<#sjgDG![%b>2d/F=NrVuYlSt2IWJ,~> +%q/[h]>Mb4`l?!=aNVfJ`o5#=b5KBj`l#Aj<)n(H`Q6'<`l@qt1<%GY`6QmaK1hEHcHF5OaMu6@ +b0%fF_TBd9`5g';`6ZZJfZ_iN?\Xc,Q'dr-R@0D.m?J?HS<8i#QB5j3ak"AKa3_rJ`Q6."asP3R +`Q#pAd*G+/Uf:uD,-0MGa2cED]>MCse]YtTb/_WHceQt'nG`%Znc&"Wm;D:[o(2JPjhACB_ns=. +_7f1.na>o7naZ>Ke,Jk(n`\lNeTr\f[\Ns_SO.*_99g5ai=1us2kbka2lc,8:)l0bK7uNrQ#Gjc-4/A]pVkk +6;:*s^!b"%ap?52a1>VO7nm`K~> +$2*9dUt*=)]E!##D:&6NsoEcc>CF)cJIHZ3dc +('FI7rrahf=aGX`5tjR:<_-GGM2dd,<+rhqeC[5(#V9Y/GB8(iearb9qu$Hml0\BIrXA`)s8)Jd +MM6@DQWs:as7HdEu#rW`E#s8Dlqq>("4s8;iqqtm*uMdH>V +s8N&prr2rtrqu]ns82-UnF>K/s3glRs8N#os8V-HnaH1%~> +"gFl9p\XserrN-!huVbsI +rr)lqi5W[Qec#IGrW)oqrrLulrkg8'_8F41`Pf[5_8F+3]TJ#5Pa%;lO-#@2`5KR4_o0L1a2#a4 +aJk;^OHc(1Os5gI_T'*r>%1<+>uPR/WNNUUB4e?nce3/bNLn2-`PfX/o_e^mrqkjHrr2lr%fZA" +UkjSF5a>RLs8W&to`"jg$MeOkOI;`!PEhE!rg!MJmZm[8%[^[/Z1J"qrr;rsrr)lnrr;lp%f6/( +rqrBrLgC#Ws8N#or;Q]q#l`nmZa-p1_tha[$NL,*rVuShS=Q7UJ,~> +%q8^f]>Vk5`l?!=aNVfJ`o5#=b5KCI`l#Ak<)n%H`Q6'=aN2NHaN2E=`6-TYauOQJGg4LTaNhlH +`lQM@re]YtTb/_WHceQt'nFQ8Nnc/(Wm:Z"[p@J7L^pUnk_o0O4 +_7f1.na>o7naZ)@nbMhQftFr.^r+"+_RmeXpYjS.9dLPn&N4m&[C9U+1MCW@Ma;oseGnq%n`\Be +f?)(SaNDrE^<+I9`Q$9MdFF;*IW[`.6.=6*b0Tt+!6Y2[s2PAgf2cgBPb!a3P6R/5Q'[o,Qh-I_ +Q^O8.Q'7>mOH>K%8!VENccF8Ha2Gm>^r==5aN4A'+NqgGbK87q=*HjS`6-0E`lQ6@aNVfG^Uok5 +84-'EHbIkK$HpT9`lPVq91M]lJ,~> +$2J,~> +"gXu9p\b$frrN-!hu:Lo3SaKp5!<)\4&Ge_,?]Rt?`T?5!h`5'1\r;RW5qr[AGrr2rt +rq?BbCdN\u5+HGooDe[bnbrpjoMCL5OIMK"Q'Ra'Pld28Q2[*LPn'.CO+LMmq#(-_s8)Qkr;?Tn +rXSl+qZ$TeJo#aDq>^?hq#16lrr2p&jgDG$[%GG8df'URrVuirp8=FOT! +%qJgf]>_q6`Q#mo7rp`bSp@nC6^qIS%`PK:*_nj1SqruKo3&`lS/%s2bScaj/(QAn= +$2NK:s8W)qqYpKmr;ZfUrr;uurr2iprr^jLs*qt^9foUTN@B_;6&rVccrqYh6*rr;fo +p\jm_fM?dTPa7SuPEhK#Pj"A=Ocl&qPb(P=qu?Zos8N)squ?]q)u]U4p\12$VKlfh5FM->rVuls +qr#E1_peP^s8N!7s82T`_M^!a#QOaqA<<"FPNA).PRitBS!BLW7_ANsrVZ]qrV-*d+9269rq'WL7-saGs8N&m +r;?Qorr2ips7u$Tna>01s3glRs8Durs8V-JnF64'~> +#.128p\k*jr;Qfss53hUr;cirrsA]$n=6J]^%hL'q>UEo&Gu;'q!sq_HY<'Ms8Doqrr;oq(B+%- +s7u]ks8;fJ;0S.dQBd\uQ'[f$k`lID@tY*=66JZm2-:ImK1\A#Jf6?\-TaMPm5_8,^@rri>uk3r9Jrr"[BlFLq9f0JrVuiror"COT +%q\pd]>i"6`Q#m/]0#l&Q`R;oNI8t2Va3)ZMbK.]C +aNDZHaN_lOcGRfBbKA5A3G=83QC!o$Q'ISsrg!GKn!+*?PF%AgM_>"SrlG2`c2P^9aND`LaMu9< +dEL0pAXI@??nQfLc-+5LajA,>^Uh&-bJq]Ia2uKMgsXsHoCMMBr9s[UCAIi"]#);&_SF(-`PfU* +lh9l:nF#i@_Sj=,_8*q(])Vg!n)2HkJlsTtF,PJ\$NL6LDf(CbNOmmEmHaK4eaD,4 +`Q#mBRS`lQBH_nNgL<_,_T +8r14/a9fo/a2k\q9h%lsJ,~> +$2`W:s8W)qqu6Tnr;ZfUrr;uurr2iprr^p=lJMR?qYh!&rr;rsr;O;iP#2)Ts8Drsqu.E0s8Vfm +qt^0^C3ks8;lrr;6NorYth5q#BtRWi/7!ED?0+qu?]q +s81`m_o't$rVulr#ljesoYQB/F`[P*rHJQiG\UUs"TSW#!"T)> +#.C>8pAP!ir;Qfss53hUr;cirrsA]$n=HS^]D;@&q>M$*s8W&tqu+)bOAGiRs8Dusrr;oq(]==5 +pAb*frq0A_Mj]ltPa7Q!QBmf%Qg'bIQ^*u&R9Ic1r;HZqr;Q`prr2lp*<-!UBks7uX!qu$26G*A,QrfmJLlBV=4%[E9GO-booRT4"ApAXs_qu?Wo!<)os +$2a]kM(@T`s8)`ms8N#srs.PlZaR30eG7Mk$2so'rplnXS=d0=~> +%qo'd]#Mn5`l?!=aNVfJ`o5#=b5KBh`l#Gr;H7SA`6-0BrQ>/]$cL',a3`#WRk04HdJh;nc,doE +aND[)a;)nF`73)Xf$c]7I?Bb\QC=,+QB[Strg!GKn!+9HP*_/e6DhuJa3Dj-a=tNOaNDZLb/hTB +`Q6]_/tS^p?"5h@cc=/J`QQ]N\\,D`e]YtTb/_WHceQt'nFQ8Nnc/(XnSIgpq"h>,]u\73^r411 +`50+Pp@7S?mdp&>s7t`i^:hY0`PK@-^q[^ro_\L[p>t;]bclL`3*'^PO![M?F%^n]`nUIWlLjMo +mb,_$`P]^@]u&(>bf\#BcbmQF`AMmCAX6hFdaZ:Zb/hU%`<+'#aSa0laMc6I?"](XPa.MtOctuq +Qh$CYPED&oR@9Y9R[BG!Ob]!]85QA;f[%Rbao03YaT'C*a2uBB`7@#('"Z6+`5p'BaN2BBbf[i; +]ouJf852X8^ +$2r`9s8W)qr;Q]or;ZfUrr;uurr2iprr^s>lJ;F=qYh!)o)Jabs7C5/LdUh3rVlfrqu.E3rqcZm +pA1IJNgQ,kQ^!c$Pa.Q"Q'Ra#Pn'.FNgO1Jp&G'hrr;uoq>1-krYth9q=K2kWG>.M8B15ps8N&t +s8Clo_o't$rVulr'`\(*oYQB/F`VVHG^4U]H$*q5%gr78rrW)u%16!OEccSOH?aCD7h6",!!*-) +quA8R),kL*f+8u6>q +#.UG7p&4mhr;Qfss53hUr;cirrs8W#nXlb`\bZ-trY#8&s8Vloo5@H[6M:6Srr;uss8DrsrtbV1 +s8DZeTg+R)Q].8qQ^p`P]U0^r!t, +WdB8=GCPI2OH5TfNfoaE`kKF-_Sa4$^UT)8Dc9D!76WYDKoD+RR_uqX_o0@_qu7!"k3i3Hrr2rt +qu6U)nFhKY-E=+NP`q;qPaIc(Q^O.rP($6-q#(0f +rVccprX\u*s8W#a7=S>,s82ins8N#trr2rt#lW\hZa[<2g%j"o#ljl#m\6;BTXK@~> +%r,0c\]2e4a2Z*>aNVfJ`o5#=b5KBh`l#Jt;H7M?`666CrQ>/]$I$*&bf8/Q9gs@RrlHD/ccF,G +aNDZH`Q,j6cI((pM(O=@P)>NhQC4),Q]mPpPa.O4Qg^2&QB@&e9SCR3aMQ$Ebf%B:`lQ&6Y`koa5`l6-LaLJaf\^emCb0%cHb0Skkg[P46r:)*)p@n?f]",Jrb/D'5`5T[2 +]^,:]mdTZ9oCDV8\]2A"`Q?6=^AbrV_nbO-lgaB0nac#3h4f7>>$auq3@nTtVSC4&q!785jjW\O +ai26:`m297cHXSWb0e2H`m;`eIsruKSh.\&bKS,M`l5j5`Q$!Ab08#NaMuBOe4>@SR[9;'Octuq +Qh$CZPE(`iR@^+FSt)".Od2/gO`ERHg"+]oa2\+ts2b5_+NMLBaMl+\HT]`Q6-?aNVfE +^:TM-84cQIPJ5Db#g:3(X]J1b:NM$~> +&-(M@s8W)srVZTmr;6Eks5EtVrsA]&r;Q`rfBV\\rr;fn%f65*q>^6ipSqIoanl&5rr;lp%K$2* +rq>,9?^?b;R$a0DPEhY,h"gaFrr2rpqu?ZorqufrrYte7qVk;LSO%@@oC`.] +s8;ors8Clp_o't$rVulr'`\(*oYQB/F`V_NH$Xd^G&_(,#RC;.!s]#4!WE'/#Z>P\FaAC\G&BY] +"98T(!(?tk!!*'""q+ORH?OX]G&qqI2AR,?)^?s`0d[hG!!!6UD0pbTH&^AGrVQNjrr20LqYpNo +rqcZnqu?Ii8q9T9TT+0nnG`If#Pn;kM//HDQKsh7QN*6MPRit@QC!o'R@053=&m*4qYg3g+929; +r5_WIPQ1CWs8Dlqr;?Qns8Mrqs7P[No^:<1s3goGs8W#us53hE!;h9~> +#.UD5o_ndfqZ#=Ls8NB(qX^G[Y.+3&q#1s(s8Vopq#C)d>#!-7s7u]nrr<#trW3&trr3Z*gdGG6 +Ng,ouQ'R]#PEqT#QBma!Pm3G=_8F'4G("dbIX[-4O-,QfPE;eNffK`QN"`*_ns4]s8W)trtkRpn,E:arr2corqufo +;G)C0;4WVgqYgBlqu?Tnrr36#r:GbXQBd]uPld26PPp^TQ^F&&Q^L6krVd9+rVlf; +8n=+bqZ$Tpqu6WqrXAc)s8W#R['R9MSDF"frWrQ%q!+KBS"[ +%r>Bf\AlV1a2l?AaNDZH`nJK@`OfMU[S;W]!TWPfE`6\5JmHW]Ymb,_$ +`P]^@]thk:bfn5Ja25X9d5XCB:fWg)=4,:8rlG,Zrl#DfaND`Nb/VB>b1PNp?]pW=Po5dIOHZ*( +TUq[>OckolQ(4;#P!qR1e]l:Wrl$/&aNVfJa2>m?Ud&1/eAKAK`P]g;`lQ +&-(\@s8W#srqu]nrqZBhs5Eqfr;Q`rr;6Els4ZZ+jo>AZo)9R*j@F0;qu-Qlqu?]ps8W&tp]($\ +`($/[QBqK7s-2c5&!WNHOdMAtR@fX`LA:fGrV?Ens7lTn*rH!9s8)G(P,DPkF'":rs82ips8Dup +i5NUOe,91Err*Z4qtTg#LO"#cH@gNgH$3h1&.AjK!r`09"U5)4!WW608T8foI!^9Z57dl'!sAr4 +rW!9+!WrK-%TmduJ:@K?2InKH"pk;7&/#Qe&e,$F!!b/tGC4RYN7IP"rVlfrs68nHrr<#trr;lq +qtf>6LP%ISW*%[KrVlusrr;rmrX\o+s8)ch9Tk[,S!KD'Q]U0k0Tq`cIqYkUr;ZQls8Dlqqu6Hl +qt+`Q:%nJ`rr)iqrVuosrr;uprr;NYq![Xus8UOH!rr8srr3,anF#Z>J,~> +$+m"8pAb$hrVlfps53eds8Mros8W)qorFmh[.*tko)9L)i^R[1r;Zfrqu?]qrr;lqq#C0_`'foU +iKXt=RZil$Pa%N(NGjLFs82fqr;Q]q"Si#rrVHNn)>Wu>OJH)aDcDVks82ios8N&ri5WaTf)>RH +rW)oqrrLulrkirp`kfI0a1]<4G^+O]H?spdK8YkTOH>O0aiM<6^W"$dJ9-'[FaJ=XIt`iBOcYT_ +`PoR/_S*h*]T[D[I!9dWF)uSWM3*m^M3l2p^r=4-o`+sis8W)pk3rU%ZOcklqPEq;uP3nP6Pk^LbP*V8\B<(\)s7u]prqufps8Dus +ok\b@o(rCdrr<#rrXAc)s8W&K\[AcSRd'^trX/])rVufSURRgJ]mp~> +%rtrk\AlG*`QZQG`QH?E`ne]D`lQBF\7863BX#@ooZ7'T(t6Yg?>%^.aiDNHai)9BaND6Cc-raQ +O-'=("I5=AR@!l;!0cl:&X8`JOd_T%R$rkAD:I.W`Q$!ub^RXQ`luBIcHO5E^ra^H;1tQC=(Xg8 +dEfeV`lH'CeAer.\%1&4`lcHEai_rbdbF9_n*'0)mJ$VTs0fJO^r""._7[Iu`l>d+\_ZlHlg=-5 +oAIBk_7mh/`4s.*_o0I.]!1>algXH5q#C6@[(*fY\[f2TZFIQ^_8 +&-(\Bs8W&ts8;corqZBhs5O"hr;6Els8;]js8Up&,!!*0'qu@67=_VbuG'%[p'EA.?"9So,!<3*9 +!!<^6FaS7VG&q+J"onf,!!<6'!<<0"!"B#>11toYFEiboo`+mhrr3)am.gSZrt550r;QTkmV6`m +>th;c7E +r;Zcprr2lrs8N#trqlWnnaZAAm*G_3df'=JrVHNn"R#=Cl2#o~> +"hg_5p&FshrW3&urr:pUrr3H)r;ZfrqtRLnX0Cpes76-qrUjN?=nVUis8W)r%KHD+qu?ZiEDMm_ +Q'@NnPn07EPF%K#P`goRD#=&.rVulr!<)or"TSB!rqcTn)YF'T5 +`RXqcrr)orrVloT_#D4Z_SNn(_nX03GBe@Xrcg,BG^P.&OHGZb^qde,^qdgbKQ_QhG^"IVG^Fpo +MN!QAP`M?I_8"%/_=dj.rVlfpqW@;Ir;H`srVld(mqH]g +=@]?W=8MjirVloqrr2rrrr91$NL)(s81ZIS"6:iJ,~> +%s_Mt\&ZD+a3DlJ`QH?E`o5#=`XU)3`lQEI\S"W8Aui_ho#N!#fhcKUc,@TBd`TGBa2Q-?bg4^= +6BR=pQ'IPsQ'[r.Qg0i7R$!T!Q("#&LNQ_Sd*9VRaND`Obf\#H`QucLccF)D^=\fISVo^G>r0aI +aihfKa2Q('!]YDA%rkp\2]tM8#`PT. +`4Ne+`Pfp;`50:,`5TU,Zg75Qkk+WJpscjfaMu3B`P]U1_u@SF_naXip[[q:cg99*a2l9Cd(R08 +b/hZD`5]a:aj%k!@!Z0TWf96k_Rdk8da#hK_8F:6b0%fEa1T@9dFQMnL67djPb"&$PN%i]S!0=t +Mbo&Ub0.f;ai)HMb/VQJ^ase!eBQ%O`5]d7_o9jEbf[r?["21I6r?a`_pZX+aU$,6^mnCo5u +&-(Y?s8W)us8;corqZBhs5O"er;6Els8;cls8V-@o&frOnbrpkC3rk"rVuQhs8N#qrrq\F@[<+C +rg*MJs-2c5&!rHFR#mc$Q]YAEr;QTnqtU.)s82fpp\OpipJmui9LEZ/?2+C!p\t3mr/q"2FYH$+1SF*)D8.LG +CO1lfo`+mhrr3)am.gSZrtkY6rqu]mql,p](6a7Zj.0RZj&p +Q2d!PR%'!tc2.J>rr3K%rVHQjpP3m:HM[U?rr)iqs8W,u%0->(rr;NWp%.Fos8UOH$NL)#s8W#Z +nF#Q>J,~> +"i6t6nGiIdrW3&urr:pUrr3H)r;ZfrqtRh!WikFZs76-qrV'rK:WWS9q#'sf"mh+TPDkh,PQ@&8 +jcp@CP*VJsRZs+t;Y9haqu?TnrW)orrYGP5s82fqq"t*koi%K^84%0&>PS6up\t1!rr;oS`l,jH +rVc`p!<)lr@,A]:_o0U3`lQ-/H$=O[H[L0eI!^3dIts,MQBAAla25p7VKm9-I!p9eIX-9cH%(I, +PEM-Bahtm4`5.OZFFJO]I!Bp_I!g?mMNO!]QGpk]^WF@cs8W&srr)]UnGiFcs8Nc1s8W"s:PaBu +L8SjnqZ$QpqYpHls8Drsrso&.s7ZKmnjJP)R@05*Qf42:Q^!Z$RYs;Pq#C?mrt5),rVufiKlV6X +q#(0lrVlisrr2rr$i^2+r6i!Y\$VasqpGECr +%t.buYf+K"a3DlK`QH?E`o5#=`XU)3`lQEI]5^PFA"p`[o#N!#fiDlNU<_'#bg4;H`5fpDe]2W) +N/O*jQ'IPqPEhQ(Qg0iTQ]dZ%OIDK"Jj.f9c,I`?aND`Obf\#HaO%uK`kK:2eB^7@U.%7W<^b<] +bJDQLa2Q-`lQEHa_/W2_SsR:_nYI6qXsa`rQr*c`Q#pAaN)?B`PKC0`koI2q>'[Kkg/VIaiDKBb0[i9 +ai_]G`l,p;`lcTTM`l]E?\tCUNQBAecH+/HaMYp8aNDZH`kfO5dE'njdk???TV%R9P*=mj0U@oa +Pa-_GY0kV=aiM`DbK/#Sd;30"?.-s=`lH0?`P][=c-4>M^U/Jg7n6 +&-(M:s8W&ts8;corqZBhs5O"gr;6Els8;cls8VHDn`TrPnGX=(GZpA-eG]FDs8N&up]'s[<0^0gs8DurrVGHk +_o(%&rVulr&HDY&oYQB/F`MM>ASG0T$3Kbu$4'XRBl.<@&c`(rr2p"kj8*Drr3f5s8W#qrVt_CItUfcUSUc`n,N@ar;Z]jrX\o+ +o`+jbrpc4`Q^!MqP*Y'l)O$8LQ]IK'CRkG%qYg'dq>C'fbY +$HAd^Hos7lWeoi.$:PF7Ys +Pa.Q#jcpLDR[0/&Q][D%qt9pfs8N&urr2lprZ_C=r;Zcrs8MVXEMdhCEHOjAqZ$9hrVQWos8:fp +`5U:*rVlcrrVca+hS@%H`5TU-aLZS@G'J<0H:rU1H@^p6P)m&h]#2L`IrTa]H?adcI!L'aGC"gr +O-,:;_Rn"3_N/e^Jq8#hIs$'bI=-?hKSknPR``Xf_8a=as8W&srr)]UnGiFcs8N)srr3Pd7!sJ[ +4JJ]Lr9jU`r;HZorr;rr&HD\.p&Fsbs7):^PELojPaLBo)3U>QNgH2KR/d$Zrq6 +%te2"W56Ek`m)cJ`QH?E`o5#=`XL#2`lQEI]7!=PA":=(a<8a^?UT>qXjGP=c,drG]ZS:D4FW0N +SXGb0PECukPF%X#Q$nmcQBRT#PDhETcd0eS_SsO;bg"ASaN2TF`llp=b/h`G_ns:1aMka_qtC'i$2r)U]>r(1aNha'a9'>q^])+a^oifu3\NKocd +O,[+cg!%IT]?A+9cJ#H\Ae +&-(J8s8W)us8;forqZBhs5O"hr;6Kns8;cns8VcFn`g)RrUKk)pj#,HK4FZNr;?TopAb0lDgI\2 +Pa%<#QBpQr$'pg?S!f5$QLanOrrW)tqt^49s82imrVuilp.M6_5>ZZ>6K\1Cs8N&ts8Domi5NUO +eboCGrr*T2qtTg#LO"#_Chmrf&.SsM!s/N&!<3)r!"'<=EcZ"S$Np\=#5\B;"UGA;!W`<+(.rUi +An2qk#QXo*!I-Hs8)]moBK#:T(`-^!<<&trr<#t +s8NH's8VKSp%RIrs8UOHs8NB%s8VcSn*]9:J,~> +$-f3Bj88fTrVlfps5M2YhT$PnbsF%Gs68"@e]]trr<#ns8W"6G`n&LOcGio +Q2[*3PmNb@Pae)"QBq(9rr33#s8;orrr)fp,6.Q?qu?]pp[q(NVE@OtBKtVWs8W)ur;ZcrrSY]6 +`RXqcrr)orrVm;_^r+(._oC!0G^4R\rd=Zm(4:RYI"$^*OHHod`Q4^"G'eFZH@(0lrd#'"H?t!l +M2db0aMkp4LO/rH+F83SGBeC\H[9s`I=R<7UW(3gbJ1mds8W&srr)]UnGiId)?'U8rVuiqp47[J +G!C2MEfg=us8W#srVuoqrr +%?4b*TtnXe`m)`I`Q63ZaT'6hb/hTDc-!_V8605d^;TT`+O&/5-!P+Re'H@aai1g4dFME8Mi=!i +Q(XJ-OcY]hQ^?s%;3mH2S!f5$N7H8%c,[W@^rFO@c-4>OaNMWE^VJ(:cIXq>TJoGd?nTIEaN;NI +ai;9Bd`/f2]"?M9`lcHEai_rbdbF9_o_ACbo!cS4>]Y;1t_o0R7`Pf[0^qIFm_S"Ckp$h_6cg99*a2l9Cd(R08b5TI" +a2uKGbfe>ZBm#>a7!4u)ESJa`aMQ$9`l@tu'$A53^rOOAairCL*c7(/S;rVnj-:UJQ]%#jRZrh_ +,JMaRaj%ZBd*L*!L5=C1ccjPTrlPhp`Q$'Ebf[r>YB!B,9hJ[!_pZU5aihoK]o#c\7oc=7~> +"973/rr)lsr;ZcrqZ6]rir8uU%fZM.r;6Kns8:F:lMpn_nGX-oqi[7VXS`%is8N&upn:9BT:D75 +rKcK/%[33EOcuDc0(&Q8qu6Tkq#:9m+SYp3q#>huVenqIEGn)3qtU3ko`+sirVGHk_o(%&rVulr +&c_b'oYQB/F`D;/:`0]I#RL\2!s&H(rW5=c#8L'Y?9Ai("UG>>#R:M7!X]2@$jm1@!sTE8FE(h( +)[6TT!!!B:$kE^O"U>DD$O6q@+(]82FFK5!o`+mhrr3)am.gSZrrE#srY,8,qtWj+Jqm8kW2`GY +s8Dupqu?Kks8;os$haProU15HQ^a&%RGjDPPEhYtQ^!f*0erS*r:9d_r;9HOQn.+ks8N#ts8N#s +s8W)ursJZ's6B(Hp>FX(s3goHrs8N%s7,7@m,S+r~> +$.YfLhu!EQrVlfps5*pAP"!p7Fj8S!TA&PEV5r +rg)]3&rr2p%qT>M'StO_d~> +%@Ugu&he@;+AjC9PB.2*M_T0s: +dDj,Jd`/f2]"?M9`lcHEai_rbdbF9_o_\IK\$<3J^:jKZs1M.@^qme"]=>D_hu;rj\$`od]tM1q +^qIFt]Y(kf\$icS]BoRpo;]L-\@];]^V.1l_8*h#]tLtc\?a$Lo_%_8cg99*a2l9Cd(R08b5TI" +a2lEGbK.oU0P,`j=$`LI1=+OpahYd9aNFJ&'$A;5_9's:bK._HBO@!pOcu)pj-;?_O-,ljR$El! ++rf=jcbRQBe(m39L_RGDc-"2PaiM]L`l?0Fbf[r>XDCU#:.f*,_pZX+aU$&0]S0 +"9700rVccrr;ZcrqZ6]rir8rTs8W,s!<2ut"Olo*r;Z9c(]+10/r,QWq"Oddo`+J[5@g.HNLuK$ +Pi7lLEnqu6U:qZ#5FWM)XdEc,JgrVHQjqu?HkrVcTN`P]UDr;HZp +rXf,,q"2FYH$+.@58bCX*#&n]&H*1X&.]&#rC/MSM$/1`A'.Om#(.fLqI.OQVm*E6s" +68UPN-SR/)1Gq'J0.\V)0f(U<.4-KNE-cVZO4 +#25lNg\_$Nrr2lri;W`Us8Dut$3'l#jd<0Qde`q4rY5>2r@EPZ62('Qs7ZKa:ci'NPDYn0P5ggH +QKFG?Ruif(Oc++*o`+pfrVuco"98B!qu6U9qu>8AUn'\SEG];crVZ]mr;ZKjrr;rT`l,gGrVc`p +!<)lr%,Se;_o09TF*;eXG]`n/rH\Efs*=Wg'7YV>]on/2PDYNdPECobN/s-\NW"niOHPI2^V5nl +QB@2qS!TD(OHP`hPEM#gO-#ZmQ,1DY]#)8Us8W&srr)]UnGiCb&cMb/rVu\D@t9/\3+AeDDYa,, +s8Doss8N!"s8;lkr;Qu$=d5)7Q'C6m$^d*;S!&u"NDr2 +$`%KGPeP2ZaNVlJ`SJW8`XU#3aN2TH^nOG)?AQ85n]2fjd+&eWLbdf6e'>nWa#PhZR@',5S!fV. +PECrhPEhL!PnBLIP+@YjCi@PD`4s=-`Q6-CrldFG`lQ?D`PBL1ftKbGS3:(nCKrsQb07]>cbmc@ +ajA&;^V%2/bJq]Ia2uKMgsXsHoCVRrW3*;8['KY>rO*QP\[o;YZEpmsn%lQRd*1"dcHjbYbKeMY +rlPqq`l5m*kOeGg_TU!@e'udnd*0h_rmDY5daHIeb/WrBpZq"gm+9A"aMuBL]tVV2rlG,^0$2>X +aNi+?<.BaZ4^O_1=k1U9^r+17bf\#HaNDZL_SsC5aiMl^N_GP!Q]dDnj-BY.s,8P!Q^F5%:Gk2X +hqHK&c;&&+11\SQbK7fF`l?6IaMudo4~> +"97*/rr2otrqlTorr:sVs8;oss82lrrr3)KnEK`Is76.*rV66X4Hc:$qXs^_oM@_)B9JRER$Ei& +iKXq8SUEkrr;olrZhI>s8Mrqp19Si>XEFODaDV@r;6Ejs8DurrVGHk_o(%&rVulr +&HDY&oYQB/F`VY:EGT?&A8(sR!+u.Bs(3iqC2%6o5&4nJ@W-$lAnGdnD0'`4ChdZtC2%Bo@Q/FQ +FE;&1C1UshBkqX+D#S,\Ci=6-A7&A#F*31bOOWq&rVlfr"6f+Hrr2p6rr;rsq>C9ejZJ9OK0_MZ +W*@mPq>:3hq>Lp#rr<#os8D`d`E/=kOID?kPq\DiP*_K"S +$/MAQf_YUIrVlfps5UC%qZ$TmpVp3tQ]R`%iKY=GRZa#%PF%>n7W;W'dI[.7;NZ-4nc&Rf +r;Q]q!rW#qrr*?(rVulj]XG2QVn`!(df'UPrr2lk_kEZpU#LS~> +$*7lKOhA]Sa3;d,`o"l:`X^)4aNDZH_l?I:>Ca<)`q.7h`l,a=cnUKA.b`4ue]fd#.VP*8Q^jJ/ +RZm`5"-]":Qg'c2OIVMuPa>^;e\T5I^r+42aND`Lb/hQAcc3r=^WP&'O/H2JDJj8LYKb/,_o9pB +`l-!G`jidr]@G*Eb0%cHb0Skkg[Oh+q!7_Jp%S1Xrql`lrV/2FrVcWgp\2Soo(DGKs82Zfqtg3i +rq?0`q"aa\p\"6uoC2AFnGE(VqYL!Zo_8.WrVulqrtG:uc1UK"h9YH>aiDKBb0[i9aiaV(0?VJ[ +c,IcOb/>ZWL5//TMkE_Qd(mB=`QZQKaMu`m(DPOI;9"OlDW\PE1ulR@0G6PES:C +8_LDoe;c\GC/3+%bK@iC`5BR4/6VC.!]Z&7=#g(&rHW!L3@D@<~> +#QNK3p](6mrVQKnrr:sV"oSB"s8;fnrs$j^BiW/d716+=p]1R32_qj--)%[N:-jr;Q`rr@aE-chaOOWq&rVlfr"6f+Hrr2rrrr)a*ogXRcK7enGX. +#j8(]c2.D=r;QWoi;W`Us8N&us8<3#p6r%`a85`)rXf,+s8;YfM3O/f[`EbNP]TXsPl?sIQK=A; +QBRK!Q^:O]qu6Tsrr<#qrr)lsrr +$G(.]K>#7H`luTHrl3m;rl4uZrlPPe_ReX2&KJL6hg@N0o=;uW-`R0/e@ +PEZ!."-]":Qgp@@PPpdHQOfCGOHu/p9r8nF6/Bo_/"No^VqL)tW^qp\b$er;?9^o()51cg99*a2l9Cd(R08b5TK\b5TI! +c-e4iJVT#76Dou7e&]VLaNVlNaMu"1kO9T$R'd`;d9bK%T0E)fP,ABTK~> +#liQ4pAb-lr;QZm!ri6"iVj#Yrr<#rr;HWtdHp2hrr;Qg&-)M+qt*`HS=3\\GCkrZIJ]>ePms.I +Q&gr^=o&'srr)irq#2NL6krVcTN`P]UDr;HZprXAi(q"2FY +H$+7QG]n90FT?L^FoHOrG^4FZG&_P8=t46-F)Z8HH$]I7!."Nh/U;YaDK'T4B-pr.Is,p[Fa84S +F*;_LG'eLWEdi%KFC?@HE-?GTJ/lJMVl~> +#j8([b5D5U?m#&ACL +OdVH#h3Ir'"-Ja3Nr>%FRS\.Rp&G$irqufrrVuj,s8Mrps8;#g[^E?4f_k]rrX/W(s8M\tURdsN +m=5~> +$GUXeJ%inDaNDZHrl3m;s2GSgaN2NHaMu30? +oCqqL\a/n[mHsT7rq$0[+78CZm-dDW(b/_ZE +^V%.oc-abV`lQBJaLd[;779gDQ,:Pga9g#1_R+)Y92B3KJ,~> +&-(>=o)JXfr;Q]nr;Q]qs5!YTr;QZp"4lc)mJd.VrXei(rVlcq7pUe3NL$0#3K]W]PlR!HPQmSE +Le[XBs7H:(pAadbrL7W*HphdkG&B*3b4ko1r;Zfq#lrr2p"kj8*Drr;rrrVR2X4bAH;M1B/2TVl#fpAb$err<#qrr;m$o1b@5P`qMs +iKaA-rKRn\PtlXmQ]ugd`VT9-q#C +$1=df_YsB3r;Q]orrN,tir8rWs8EB*rr)fpq4jml^\@6s&,6,&rql[`>D&&qP+7[oO8G4BQJn)/ +P5^[MS!o1/p\k-frqud0pAadbrgIW&GX?.aF_rm1b5))8rr3B)s8N&si5W^Rec#IGrW)oqrrLul +rknTL!5nQJ&AuT/^lF5b_Sj@1`50:*^qoud(;[Z&_SOL9V2^2Jahtp4a1oF*_Sa:0rl#ej_p5g4 +aMO7#TuXsca2#Oas8W&srr)]UnGi=`rr3Q/ffak +&'K6%G/(r:aNDZH`l5s=b2UMB`Xg&0aNDZH`lGf%>ZbaJ`5_Di&B_u;a3<)m/4=E.Kp/'k3fs6& +s,m;Es-)lo^;;Cn,DqYnK7/alKdQrpZM8Ho>7r[oC)2Aj3R)DaiDKBb0[i9aiaP&s2tA_.E9T: ++`r +#63TRHQrr)j!hraCkrr;Qgrr3E*rqH3_>A\SPNIj`ifp)l(SrT/!O-i3+ +r;?NorV?Hmruq=?nO0UU2-OsCD0'Ya^[qL'rr2rrs8Domi5NUOeboCGrr*6(qtTg#LO"#`FnTuM +G]n=VHZF1@;%EaA@!-[9F`qtTI!U$\F`hkPH$++G@m:b6)-q*#G'.tRH?sgZG'.hHHuaXRDJW`4% +2q'/FE_PNNR[V#rVlfr"6f+Hrr2rrrr)a*l:->[L4Y#-3..T@Qi-[Uqu6Wqqu6Wn#PUoQR?sA)Q +Jn,-QMm'ZN1H.l>[9][q"aabqtU$fq>UEls8N&u#Q4W%l0n37dJj0orX/](rVuoSl0R^%s*t~> +#559r\GQ+%rr2lr!WN&Wrr2rtrX/])rVccmY,&83oC)\Ys8W'*p%\8cCil#%J4H"'QJe#7Nh28t +OcYtspA=jfs8E)urr2`n&,ZCs7'<.==Di7tEc4:Zp&=t#rr)`orr;rT`l,gGrVc`p!<)lr"l@&4 +_o0Ic_A:&+_T'@0aMEpqOM/HI_8O=0_8*k'_Z%F^_Sa4+a2b!G(Bq>1-jqtg?lr;QitrVlfr$iKu'r7eNe\$;Cls3U`Or;Z`a +W1olRYkNY~> +&(Q89Cq[a0b0%fH`l5s=b2UMB`Xg&0aNDZF`lGi1=BAq7`5_Di&B`AGai2KJf%WPqDjZW?8='+7 +s-*JJrKm#=s-*JJrKdhNSrAqnMNKR=bPocdbW*_eaMu6=`Q#p@d*(%e/>8Lf>An\"DJCts_p$$< +b0A,M`5g0A\A,\ie]YtTb/_WHceQt'nFQ8Io_nC\nIb6Zlh1,G^q7JWq=jIKmd0E4rU^'Z&G,Pc +o_eOA^TkNGo^VSDnacYM+S"pflg*O$lL=K>ag/\/nG2bBkKiMHaiDKBb0[i9aiaV(s2H,$b/hZD +bebcKJ;8i0IlDS==Ei<>b08#LaMu6@aNFM+$d-Q1b0DViPaS,+Qf45/QS"JdPEhDmSrts1;)BZR +e'QF_`5^0H`kT7&_p$HNaMl0Cc,dGN90kpB9!Q@Td`;d=`lGit?r0NoHJa5~> +%0,AIkl:V]s8N#qr;Q]qhuQMNc_Y$(I0?PF[ns +5kb-RrW)omrZhI +$2Cs(ZhjV"s8N#ss8W&urSmhRrsJc(rVu]-T<>NfrUBdtpAY*lr;ZT=O*j&L4c5JiQ2R$+PmNqE +O-?0"N^i+;Sr8bhU<:Ko`59@`s8W&srr)]UnGiIds8W,urr3K-qa,"LK7Sf(6V*rO7d^0Sp&=sj#"Fi< +OdV;siKaA+rKR_ZPE:GtWV$#^r;?Nn!V? +&)<+KA\,n*bK@oI`l5p(2-X +Km5pQS!u%Te^2J:a9'B&aSs?^a9fl/eL--1Odh>oiKaD//X;N`Q'Io*Oap,oi8)l,b0A#KdD*cA +_o'I7b08)N`Pp'Gb.2sn5XA1A\AZD8a9p,1a1nKU:J4W;j+%~> +%0,MMkPtS]r;Q]nr;Q]qhu^Hoq#'pco_n:O=+m!(fp)o.Pa@r" +S;p28rVuNh'Dqh0k"i%E:0h"EE,BVO2u`dMq#(0lr/q"2FYH$+1NF`qnN +F`qnNFa!_+&T_u+=V_/F!!cbLGB\4SF`hm)FTli+E+qiXrW"5Q??:71EH$)GH$4@UG&q_LEcPo) +.gZ@Z"?:.2G'\=jeF`e>rr2p"kj8*Drr;rrrVR9'M`urFLPBDOVe`5cHMmO8r;HWps82fqr!2lh +Q(=,,PaUKqrKdDI&!<-CPsO^3o_\R]rVQHbs7uZor;ZcrrsJ](q=*kBm,%dAs3goHrs8Q&s4lf( +m.gU2~> +"SKF'YkS.ss8N#ts8E#sir8lUs8N&s#lj_JS?9*Yqu-*b!;HKm$i0_srqHHbp/cp9P5(=BPiS): +PE_E*NLc,'q#16jrqufqrZ_7>ro?bOQVCagF)Pl70K/q1qu$Kor;Zfrs8Lrr`5L4)rVlcrrVca! +hS@%H`:CeX`5p$9Mi![`NkiKK_8F4._8?)e'#_]/ag7.dO,Ae7`kfX4_o9L/rPJTQ)o]V6aiU-5 +OH5C%b.>C3_85gEs8DrrrVG[Gs8Drss8W)trt,2-N'2lBKnX)HUhHTXHMmU +&)<=P@(=A'b0%fH`l5pGbf%$+]Y2k=`lcHEai_rbdbF9_oCMMPo+1Znp;"8X^qKC9p%%YDnFHMKs7--\&Gl=f +_RR=i\+falo^M8;naZSLs7%?*me?PRc+:O!\_?uKnbD(hm+9A"aMuBL]tVV2aN2B?`Q64$a:leF +Cb's\L4NctPMVQTPEhE"PEh>k0\"t,cH*lCa2l3H +`l5s?bfn5Nb/hK>bg";@F\+e`8mAmFdDu[ +%0,bUj8]/Wr;Q]nr;Q]qiVjDgrquZkrr<#ss8Ud>jnJfTo)A[h!W2iprs8DtqsjMBO-Q+2PhhT7 +Q]IT%Nf[/8q>UEnrVlikrZ_4=?'MQq_Jr[uF*_ahd.I/6r;?Toq>^ElqV]?1_q"\`s8N!2s82T` +_M]+Y+H$XUUEcQ;GH$OXWEb7`W!sSo/'k;<,EccDD +G^4OYH$OXXGB%V80Fn6g!sUJqH[9aZN7@M"rVlfr"6f+Hrr2rrrqu[*nO%b^Jp`<&H:2M18D=(@ +r;HWps82fqr!39!6^!LrP`Xjh".#=?QMm'ZQ^*f&