tqsl-2.0/0000775000076400007640000000000012231074305012343 5ustar rmurphyrmurphytqsl-2.0/README0000664000076400007640000003025412231074305013227 0ustar rmurphyrmurphyThis is the TrustedQSL project, which provides tools for digitally signing Amateur Radio QSO records. src: Source code and documentation for tqsllib, the TrustedQSL library. apps: Source code for "tqsl" and other sample applications. html: Various legacy documents This document describes the changes to TrustedQSL since version 1.13 and explains how applications can use TQSL in their applications. Command Line Changes -------------------- Many applications use the 'tqsl' application in command line mode to sign log files. There were several new capabilities added to command line operation in 1.14. The first is that tqsl can now automatically sign and upload a log to the LoTW site for the user. This allows your application to simply write an adif file which is then processed and uploaded to LoTW without requiring the application to read the output file and either upload it or tell your user to upload it. The command line parser in 1.14 was rewritten and is less forgiving of improperly formatted command lines. Command Line Options -------------------- The following summarizes the command line options and what they do: Usage: tqsl [-a ] [-b ] [-e ] [-d] [-l ] [-s] [-o ] [-u] [-x] [-p ] [-q] [-n] [-v] [-h] [-t ] [Input ADIF or Cabrillo log file to sign] The following command line options may be specified on the command line: -a Specify dialog action - abort, all, compliant or ask This option instructs TQSL on how to handle QSOs that do not appear to be valid. There are many potential causes for invalid QSOs. Examples include QSOs with dates outside the valid range for the certificate being used, QSOs with invalid amateur callsigns, duplicate QSOs, and attempts to sign with an expired certificate. This option specifies how tqsl should handle these exceptions. Using "-a ask" instructs tqsl to use a dialog to ask the user how to proceed. This is the default behavior if "-a" is not provided on the command line. Using "-a abort" instructs tqsl to issue an error message when an exception QSO is processed and immediately abort signing. Using "-a compliant" instructs tqsl to sign the QSOs which are compliant (not duplicates, in date range, and with valid callsigns) and ignore any exception QSOs. This is the recommended behavior for command line applications but is not the default action for compatibility reasons. Using "-a all" instructs tqsl to process all QSOs, ignoring duplicates and invalid callsigns. QSOs outside the range of valid dates for the selected station certificate will not be signed, as they would not be accepted by Logbook. -b Set begin date for the QSO date filter. -e Set end date for the QSL date filter. These options filter QSOs being signed to those after the begin date and before the end date. If neither of these are supplied, then no filtering will be performed. These values will override any date range entries provided by the user. This implies that "-d" (suppress date range dialog) should be used with -b or -e. -d Suppress date range dialog This option instructs tqsl to not ask the user to select a range of dates for processing QSOs. If this is used, all QSOs in the input file will be selected for processing. Command line tools will usually include this option to suppress tqsl dialogs. However, this means that the logging program is responsible for filtering QSOs before delivering them to tqsl. -l Select Station Location. This option selects a station location. This is used for signing logs or in conjunction with the "-s" option to define a location for editing. -s Edit (if used with -l) or create Station Location This option can be used to create a new Station Location (-s without -l) or to edit an existing Station Location (when both -s and -l are provided). -o Output file name (defaults to input name minus extension plus .tq8) This option instructs tqsl where the signed output file will be stored. If it is not provided, the output file will be written to the same location as the input file with the extension changed to ".tq8" -u Upload after signing instead of saving This option instructs tqsl to upload the log file after it is successfully signed. -q Operate in batch mode, not menu-driven mode. -x Operate in batch mode, not menu-driven mode. If -x or -q are included on the command line, tqsl suppresses user dialogs and sends error messages to standard error. A logging application is expected to read this file and possibly display the contents to the user so they can see the results of the command action. If these options are not included, a calling application cannot distinguish between a successful signing and one where a user cancels the signing. -n Look for updated (new) versions of key files. If -n is given on the command line, tqsl checks for new versions of the tqsl program, an updated tqsl configuration file, and verifies that any user certificates are not about to expire. If any of these circumstances exist, the user is prompted to perform the required updates. When the check is completed, tqsl exits. This command line option can not be combined with any other command line options as it only performs an update check and does not sign any logs submitted with the command. -p Password for the signing key This option allows an application to provide the password for the private key that will be used to sign the log file. -v Display the version information and exit -h Display command line help These options allow the user to display the version number of tqsl or to obtain help on the command line usage. -t . Open a diagnostic trace file at startup When supplied, this option enables diagnostic tracing at startup, opening the supplied file to record TQSL operations details. This is useful for debugging purposes. Command Line Usage ------------------ An application that uses the command line invokes the tqsl binary, optionally providing a set of options that dictate how tqsl operates. Normally, such an application should include the "-x" or "-q" options to indicate to tqsl that application popups should be suppressed. Errors discovered during the signing process are sent to the standard error file. Callers would normally indicate where those messages should be sent by adding "2> file.txt" to the command line used to run tqsl. This directs the shell (Windows or Unix) to write the error messages to that file. When operated in "batch" mode (i.e. -x or -q used), tqsl provides information that the calling program can use to determine if the signing operation succeeded. The first way is by capturing tqsl's exit status code. This provides information on success or failure using the following values: 0 - Success: all QSOs submitted were signed and saved or uploaded 1 - Cancelled by user 2 - The log was rejected by the LoTW server 3 - The response from the LoTW server was unexpected 4 - An error occurred in tqsl 5 - An error occurred in tqsllib (invalid filename, bad file format) 6 - Unable to open input file 7 - Unable to open output file 8 - No QSOs were processed because some QSOs were duplicates or out of date range (no QSOs written) 9 - Some QSOs were processed, and some QSOs were ignored because they were duplicates or out of date range (some QSOs written) 10 - Command syntax error 11 - LoTW network connnection failed (no network or LoTW is unreachable) This exit status is also written to stderr in a format that can be parsed by the calling application. The last output from tqsl will be of the format hh:mm:ss AM|PM Final Status: Description (code) The first two fields are a timestamp, the words "Final Status:" always appears. Following that is a short descriptive message giving the exit status. The last thing on the line is the numeric exit code (as above) in parenthesis. Examples of output follows: 05:57:39 PM: Warning: Signing cancelled 05:57:39 PM: No records output 05:57:39 PM: Final Status: cancelled by user (1) 06:05:56 PM: /home/rmurphy/k1mu.adi: 414 QSO records were duplicates 06:05:56 PM: /home/rmurphy/k1mu.adi: wrote 1 records to /home/rmurphy/k1mu.tq8 06:05:56 PM: /home/rmurphy/k1mu.tq8 is ready to be emailed or uploaded. Note: TQSL assumes that this file will be uploaded to LoTW. Resubmitting these QSOs will cause them to be reported as duplicates. 06:05:56 PM: Final Status: Some QSOs were duplicates or out of date range (9) An example usage for signing a log would be tqsl -q -l "K1MU home" -p "Insecure" -a compliant -u -d k1mu.adi 2>temp.txt This indicates quiet mode (-a), selects a station location and a password, indicates that only compliant QSOs will be written (-a), uploads to LoTW (-u), suppresses date popups (-d), provides an input file (k1mu.adi), and finally writes log messages to temp.txt. The logging program would read and process that log once tqsl is done. An application would add "-o" to indicate where tqsl should write the signed log if "-u" (upload) is not provided. Command line applications are strongly encouraged to add "-a=compliant" to their invocations of tqsl, and to consider storing and displaying the log messages to their users. Application Changes ------------------- Some logging applications directly call tqsllib functions to sign log files. The application programming interface (API) to tqsllib has not changed in ways that introduce incompatibilities, but there are additional API calls which are necessary for applications to allow duplicate QSO processing to work properly. Normally, an application will call tqsl_beginCabrilloConverter() or tqsl_beginADIFConverter to begin signing a log file. After the converter is created by those calls, the application should then call tqsl_setConverterAllowDuplicates(conv, false) which tells tqsllib that duplicate processing should be enabled. If you do not call tqsl_setConverterAllowDuplicates, the library will assume that duplicates should be permitted (for compatibility reasons), which may cause unnecessary QSOs to be uploaded. If duplicate suppression is enabled, there is a new error return from tqsl_getConverterGABBI that indicates duplicate QSOs. In this case, tQSL_Error is set to TQSL_DUPLICATE_QSO. Software may need to be modified to handle this new result and act appropriately (ignore it, or abort the signing operation.) After successful processing of a log, an application should call either tqsl_convertCommit(conv) or tqsl_convertRollBack(conv) prior to calling tqsl_endConverter() to signal that a log conversion has completed. tqsl_converterCommit() indicates to tqsllib that the log has been successfully processed and that the QSOs should be added to the duplicate detection database. Calling tqsl_converterRollBack() indicates to tqsllib that the log has not been successfully processed and that the QSO records should not be added to the duplicate database. Simply adding the necessary call before the converter is closed is enough to bring the application up to date. change tqsl_endConverter(&conv) to tqsl_converterCommit(conv); tqsl_endConverter(&conv); Using tqsllib ------------- A minimal set of calls to permit an application to sign a log is the following. Of course, error checking should be performed for each call. tqsl_getStationLocation(&loc, location_name); tqsl_getLocationCallSign(loc, callsign, sizeof callsign); tqsl_getLocationDXCCEntity(loc, &dxcc); tqsl_selectCertificates(&certlist, &ncerts, callsign, dxcc); tqsl_beginADIFConverter(&conv, input_file, certlist, ncerts, loc); tqsl_setConverterAllowDuplicates(conv, false); tqsl_setConverterAppName(conv, "myAppName"); (tell tqsllib the name of your application) while (cp = tqsl_getConverterGABBI(conv) != 0) write the string pointed to by "cp" to your file tqsl_converterCommit(conv); tqsl_endConverter(&conv); tqsl_endStationLocationCapture(&loc); The tq8 files created by tqsl are compressed using zlib functions. You can also submit uncompressed files using a .tq7 extension. tqsl-2.0/win32-msi/0000775000076400007640000000000012231073120014065 5ustar rmurphyrmurphytqsl-2.0/win32-msi/tqsl-install/0000775000076400007640000000000012231073120016514 5ustar rmurphyrmurphytqsl-2.0/win32-msi/tqsl-install/update-helpfrag.cmd0000664000076400007640000000024312231073120022250 0ustar rmurphyrmurphy"C:\Program Files (x86)\WiX Toolset v3.7\bin\heat.exe" dir ..\..\apps\help -cg "HelpDir" -dr "APPLICATIONFOLDER" -indent 2 -out helpfrag.wxs -var "var.helpSrc" -agtqsl-2.0/win32-msi/tqsl-install/tqsl-install.wixproj0000664000076400007640000000476012231073120022576 0ustar rmurphyrmurphy Debug x86 3.7 1dfa6e6b-1725-4fa3-81d7-64d8a82cb824 2.0 tqsl-2.0 Package $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets bin\$(Configuration)\ obj\$(Configuration)\ Debug -b "..\..\bin\Release" -b "..\..\apps" -b "..\..\src" -b "..\..\src\Release" -b "..\..\apps\Release" bin\$(Configuration)\ obj\$(Configuration)\ -b "..\..\bin\Release" -b "..\..\apps" -b "..\..\src" -b "..\..\src\Release" -b "..\..\..\apps\Release" $(WixExtDir)\WixUIExtension.dll WixUIExtension tqsl-2.0/win32-msi/tqsl-install/tqsl-install.sln0000664000076400007640000000151612231073120021664 0ustar rmurphyrmurphy Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2012 Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "tqsl-install", "tqsl-install.wixproj", "{1DFA6E6B-1725-4FA3-81D7-64D8A82CB824}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {1DFA6E6B-1725-4FA3-81D7-64D8A82CB824}.Debug|x86.ActiveCfg = Debug|x86 {1DFA6E6B-1725-4FA3-81D7-64D8A82CB824}.Debug|x86.Build.0 = Debug|x86 {1DFA6E6B-1725-4FA3-81D7-64D8A82CB824}.Release|x86.ActiveCfg = Release|x86 {1DFA6E6B-1725-4FA3-81D7-64D8A82CB824}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal tqsl-2.0/win32-msi/tqsl-install/helpfrag.wxs0000664000076400007640000006030712231073120021055 0ustar rmurphyrmurphy tqsl-2.0/win32-msi/tqsl-install/Product.wxs0000664000076400007640000001642612231073120020710 0ustar rmurphyrmurphy NOT Version9X INSTALLDESKTOPSHORTCUT ISINNOINSTALLED notepad.exe CLONEXIT AND NOT Installed QSONEXIT AND NOT Installed tqsl-2.0/win32-msi/tqsl-install/MyWixUI_InstallDir.wxs0000664000076400007640000001110712231073120022717 0ustar rmurphyrmurphy 1 "1"]]> 1 NOT Installed Installed AND PATCH 1 LicenseAccepted = "1" 1 1 NOT WIXUI_DONTVALIDATEPATH "1"]]> (ISINNOINSTALLED) AND (WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1") (NOT ISINNOINSTALLED) AND (WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1") 1 1 NOT Installed Installed AND NOT PATCH Installed AND PATCH 1 1 1 1 tqsl-2.0/win32-msi/tqsl-install/MyInstallDirDlg.wxs0000664000076400007640000000452712231073120022271 0ustar rmurphyrmurphy 1 tqsl-2.0/win32-msi/tqsl-install/MyExitDialog.wxs0000664000076400007640000000730712231073120021625 0ustar rmurphyrmurphy tqsl-2.0/win32-msi/tqsl-install/AlertUninstall.wxs0000664000076400007640000000204212231073120022216 0ustar rmurphyrmurphy 1 1 1 tqsl-2.0/win32-msi/tqsl-install/.gitignore0000664000076400007640000000001212231073120020475 0ustar rmurphyrmurphybin/ obj/ tqsl-2.0/toolset-to-vc08.py0000664000076400007640000000120212231073120015571 0ustar rmurphyrmurphyVCXPROJ=".vcxproj" v2012_PLATFORM_TOOLSET="v110" v2008_PLATFORM_TOOLSET="v90" from os import walk, path if __name__=="__main__": count=0 for root, dirs, files in walk("."): for file in files: if file.endswith(VCXPROJ): print "Replacing in", path.join(root, file), "...", with open(path.join(root, file), 'r') as proj: s=proj.read() s=s.replace(v2012_PLATFORM_TOOLSET, v2008_PLATFORM_TOOLSET) with open(path.join(root, file), 'w') as proj: proj.write(s) print "done" count+=1 print "Replaced toolset in", count, "project files"tqsl-2.0/src/0000775000076400007640000000000012231073120013124 5ustar rmurphyrmurphytqsl-2.0/src/xml.h0000664000076400007640000001425212231073120014101 0ustar rmurphyrmurphy/*************************************************************************** xml.h - description ------------------- begin : Fri Aug 9 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __xml_h #define __xml_h #include #include #include #include #include namespace tqsllib { class XMLElement; typedef std::multimap XMLElementList; typedef std::map XMLElementAttributeList; /** Encapsulates an XML element * * An XMLElement comprises a name, the enclosed text, an optional set of * attributes, and an optional list of contained elements. * * Having a list of contained elements allows construction of the XML * document tree structure. In most cases, the structure will be populated * by a call to parseFile(). */ class XMLElement { public: XMLElement() : _name(""), _text(""), _pretext("") {} /// Constructor initializes element name XMLElement(const std::string& name) : _text(""), _pretext("") { _name = name; } /// Clear the element of all data void clear(); /// Set the element name void setElementName(const std::string& name) { _name = name; } /// Get the element name std::string getElementName() const { return _name; } /// Set an attribute. /** Attributes are treated as unique key/value pairs. */ void setAttribute(const std::string& key, const std::string& value); /// Get an attribute by its key. /** Returns a pair where: * * \li \c getAttribute().first := the attribute's value * \li \c getAttribute().second := a bool, true if the atrtribute key exists */ std::pair getAttribute(const std::string& key); /// Add an element to the list of contained subelements XMLElementList::iterator addElement(const XMLElement& element); XMLElementAttributeList& getAttributeList() { return _attributes; } XMLElementList& getElementList() { return _elements; } /// Parse an XML file and add its element tree to this element int parseFile(const char *filename); #define XML_PARSE_NO_ERROR 0 #define XML_PARSE_SYSTEM_ERROR 1 #define XML_PARSE_SYNTAX_ERROR 2 /// Parse an XML string and add its element tree to this element int parseString(const char *xmlstring); /// Get the first attribute of the element /** Provides the attribute key and value. Returns \c false if the * element contains no attributes */ bool getFirstAttribute(std::string& key, std::string& attr); /// Get the next attribute of the element /** Should be called only after calling getFirstAttribute and getting * a return value of \c true. * Provides the attribute key and value. Returns \c false if the * element contains no more attributes */ bool getNextAttribute(std::string& key, std::string& attr); /// Get the first contained element named \c name. /** Returns \c false if the element contains no elements named \c name */ bool getFirstElement(const std::string& name, XMLElement&); /// Get the first contained element. /** Returns \c false if the element contains no elements */ bool getFirstElement(XMLElement&); /// Get the next contained element. /** Should be called only after calling getFirstElement and getting * a return value of \c true. If the getFirstElement that takes an * element name was called, getNextElement will return \c false when there * are no more elements of that name in the element list. * * Returns \c false if the element contains no more elements */ bool getNextElement(XMLElement&); /// Set the contained text string void setText(const std::string& s) { _text = s; } /// Get the contained text string. /** Note that this string comprises the text contained in this * element only, not any text contained in elements on the * element list; they each have their own contained text. */ std::string getText() const { return _text; } void setPretext(const std::string& s) { _pretext = s; } std::string getPretext() const { return _pretext; } private: static void xml_start(void *data, const XML_Char *name, const XML_Char **atts); static void xml_end(void *data, const XML_Char *name); static void xml_text(void *data, const XML_Char *text, int len); std::string _name, _text, _pretext; XMLElementAttributeList _attributes; XMLElementList _elements; std::vector _parsingStack; XMLElementList::iterator _iter; bool _iterByName; std::string _iterName; XMLElementAttributeList::iterator _aiter; }; inline void XMLElement::clear() { _name = _text = _pretext = _iterName = ""; _attributes.clear(); _elements.clear(); _parsingStack.clear(); } inline void XMLElement::setAttribute(const std::string& key, const std::string& value) { _attributes[key] = value; } inline XMLElementList::iterator XMLElement::addElement(const XMLElement& element) { XMLElementList::iterator it = _elements.insert(make_pair(element.getElementName(), element)); return it; } inline bool XMLElement::getFirstElement(XMLElement& element) { _iterByName = false; _iter = _elements.begin(); return getNextElement(element); } inline bool XMLElement::getFirstElement(const std::string& name, XMLElement& element) { _iterName = name; _iterByName = true; _iter = _elements.find(_iterName); return getNextElement(element); } inline bool XMLElement::getNextElement(XMLElement& element) { if (_iter == _elements.end()) return false; if (_iterByName && _iter->second.getElementName() != _iterName) return false; element = _iter->second; ++_iter; return true; } inline bool XMLElement::getFirstAttribute(std::string& key, std::string& attr) { _aiter = _attributes.begin(); return getNextAttribute(key, attr); } inline bool XMLElement::getNextAttribute(std::string& key, std::string& attr) { if (_aiter == _attributes.end()) return false; key = _aiter->first; attr = _aiter->second; ++_aiter; return true; } std::ostream& operator<< (std::ostream& stream, XMLElement& el); } // namespace tqsllib #endif // __xml_h tqsl-2.0/src/xml.cpp0000664000076400007640000001246112231073120014434 0ustar rmurphyrmurphy/*************************************************************************** xml.cpp - description ------------------- begin : Fri Aug 9 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include "xml.h" #include #include #include #include using namespace std; namespace tqsllib { pair XMLElement::getAttribute(const string& key) { string s; XMLElementAttributeList::iterator pos; pos = _attributes.find(key); pair rval; if (pos == _attributes.end()) rval.second = false; else { rval.first = pos->second; rval.second = true; } return rval; } void XMLElement::xml_start(void *data, const XML_Char *name, const XML_Char **atts) { XMLElement *el = (XMLElement *)data; XMLElement new_el(name); //cout << "Element: " << name << endl; for (int i = 0; atts[i]; i += 2) { new_el.setAttribute(atts[i], atts[i+1]); } if (el->_parsingStack.empty()) { el->_parsingStack.push_back(el->addElement(new_el)); //cout << "Empty: " << new_el.getElementName() << endl; } else { //cout << "Adding: " << el->_parsingStack.back()->second.getElementName() << endl; new_el.setPretext(el->_parsingStack.back()->second.getText()); el->_parsingStack.back()->second.setText(""); el->_parsingStack.push_back(el->_parsingStack.back()->second.addElement(new_el)); } } void XMLElement::xml_end(void *data, const XML_Char *name) { XMLElement *el = (XMLElement *)data; if (!(el->_parsingStack.empty())) el->_parsingStack.pop_back(); } void XMLElement::xml_text(void *data, const XML_Char *text, int len) { XMLElement *el = (XMLElement *)data; el->_parsingStack.back()->second._text.append(text, len); } /* bool XMLElement::parseFile(const char *filename) { ifstream in; in.open(filename); if (!in) return false; // Failed to open file char buf[256]; XML_Parser xp = XML_ParserCreate(0); XML_SetUserData(xp, (void *)this); XML_SetStartElementHandler(xp, &XMLElement::xml_start); XML_SetEndElementHandler(xp, &XMLElement::xml_end); XML_SetCharacterDataHandler(xp, &XMLElement::xml_text); _parsingStack.clear(); while (in.get(buf, sizeof buf, 0).good()) { // Process the XML if (XML_Parse(xp, buf, strlen(buf), 0) == 0) { XML_ParserFree(xp); return false; } } bool rval = !in.bad(); if (!rval) rval = (XML_Parse(xp, "", 0, 1) != 0); XML_ParserFree(xp); return rval; } */ int XMLElement::parseString(const char *xmlstring) { XML_Parser xp = XML_ParserCreate(0); XML_SetUserData(xp, (void *)this); XML_SetStartElementHandler(xp, &XMLElement::xml_start); XML_SetEndElementHandler(xp, &XMLElement::xml_end); XML_SetCharacterDataHandler(xp, &XMLElement::xml_text); _parsingStack.clear(); // Process the XML if (XML_Parse(xp, xmlstring, strlen(xmlstring), 1) == 0) { XML_ParserFree(xp); return XML_PARSE_SYNTAX_ERROR; } XML_ParserFree(xp); return XML_PARSE_NO_ERROR; } int XMLElement::parseFile(const char *filename) { gzFile in = gzopen(filename, "rb"); if (!in) return XML_PARSE_SYSTEM_ERROR; // Failed to open file char buf[256]; XML_Parser xp = XML_ParserCreate(0); XML_SetUserData(xp, (void *)this); XML_SetStartElementHandler(xp, &XMLElement::xml_start); XML_SetEndElementHandler(xp, &XMLElement::xml_end); XML_SetCharacterDataHandler(xp, &XMLElement::xml_text); _parsingStack.clear(); int rcount; while ((rcount = gzread(in, buf, sizeof buf)) > 0) { // Process the XML if (XML_Parse(xp, buf, rcount, 0) == 0) { gzclose(in); XML_ParserFree(xp); return XML_PARSE_SYNTAX_ERROR; } } gzclose(in); bool rval = (rcount == 0); if (rval) rval = (XML_Parse(xp, "", 0, 1) != 0); XML_ParserFree(xp); return (rval ? XML_PARSE_NO_ERROR : XML_PARSE_SYNTAX_ERROR); } static struct { char c; const char *ent; } xml_entity_table[] = { { '"', """ }, { '\'', "'" }, { '>', ">" }, { '<', "<" } }; static string xml_entities(const string& s) { string ns = s; string::size_type idx = 0; while ((idx = ns.find('&', idx)) != string::npos) { ns.replace(idx, 1, "&"); idx++; } for (int i = 0; i < int(sizeof xml_entity_table / sizeof xml_entity_table[0]); i++) { while ((idx = ns.find(xml_entity_table[i].c)) != string::npos) ns.replace(idx, 1, xml_entity_table[i].ent); } return ns; } /* Stream out an XMLElement as XML text */ ostream& operator<< (ostream& stream, XMLElement& el) { bool ok; XMLElement subel; if (el.getElementName() != "") { stream << "<" << el.getElementName(); string key, val; bool ok = el.getFirstAttribute(key, val); while (ok) { stream << " " << key << "=\"" << xml_entities(val) << "\""; ok = el.getNextAttribute(key, val); } if (el.getText() == "" && !el.getFirstElement(subel)) { stream << " />"; return stream; } else stream << ">"; } ok = el.getFirstElement(subel); while (ok) { string s = subel.getPretext(); if (s != "") stream << xml_entities(s); stream << subel; ok = el.getNextElement(subel); } if (el.getText() != "") stream << xml_entities(el.getText()); if (el.getElementName() != "") stream << ""; return stream; } } // namespace tqsllib tqsl-2.0/src/winstrdefs.h0000664000076400007640000000043312231073120015465 0ustar rmurphyrmurphy#ifndef WINSTRDEFS_H #define WINSTRDEFS_H #if defined(_WIN32) || defined(_WIN64) #define snprintf _snprintf #define vsnprintf _vsnprintf #define strcasecmp _stricmp #define strncasecmp _strnicmp #define unlink _unlink #define strdup _strdup #endif #endif//WINSTRDEFS_H tqsl-2.0/src/windirent.h0000664000076400007640000006110612231073120015304 0ustar rmurphyrmurphy/* * dirent.h - dirent API for Microsoft Visual Studio * * Copyright (C) 2006-2012 Toni Ronkko * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * ``Software''), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * * * Version 1.13, Dec 12 2012, Toni Ronkko * Use traditional 8+3 file name if the name cannot be represented in the * default ANSI code page. Now compiles again with MSVC 6.0. Thanks to * Konstantin Khomoutov for testing. * * Version 1.12.1, Oct 1 2012, Toni Ronkko * Bug fix: renamed wide-character DIR structure _wDIR to _WDIR (with * capital W) in order to maintain compatibility with MingW. * * Version 1.12, Sep 30 2012, Toni Ronkko * Define PATH_MAX and NAME_MAX. Added wide-character variants _wDIR, * _wdirent, _wopendir(), _wreaddir(), _wclosedir() and _wrewinddir(). * Thanks to Edgar Buerkle and Jan Nijtmans for ideas and code. * * Do not include windows.h. This allows dirent.h to be integrated more * easily into programs using winsock. Thanks to Fernando Azaldegui. * * Version 1.11, Mar 15, 2011, Toni Ronkko * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0. * * Version 1.10, Aug 11, 2010, Toni Ronkko * Added d_type and d_namlen fields to dirent structure. The former is * especially useful for determining whether directory entry represents a * file or a directory. For more information, see * http://www.delorie.com/gnu/docs/glibc/libc_270.html * * Improved conformance to the standards. For example, errno is now set * properly on failure and assert() is never used. Thanks to Peter Brockam * for suggestions. * * Fixed a bug in rewinddir(): when using relative directory names, change * of working directory no longer causes rewinddir() to fail. * * Version 1.9, Dec 15, 2009, John Cunningham * Added rewinddir member function * * Version 1.8, Jan 18, 2008, Toni Ronkko * Using FindFirstFileA and WIN32_FIND_DATAA to avoid converting string * between multi-byte and unicode representations. This makes the * code simpler and also allows the code to be compiled under MingW. Thanks * to Azriel Fasten for the suggestion. * * Mar 4, 2007, Toni Ronkko * Bug fix: due to the strncpy_s() function this file only compiled in * Visual Studio 2005. Using the new string functions only when the * compiler version allows. * * Nov 2, 2006, Toni Ronkko * Major update: removed support for Watcom C, MS-DOS and Turbo C to * simplify the file, updated the code to compile cleanly on Visual * Studio 2005 with both unicode and multi-byte character strings, * removed rewinddir() as it had a bug. * * Aug 20, 2006, Toni Ronkko * Removed all remarks about MSVC 1.0, which is antiqued now. Simplified * comments by removing SGML tags. * * May 14 2002, Toni Ronkko * Embedded the function definitions directly to the header so that no * source modules need to be included in the Visual Studio project. Removed * all the dependencies to other projects so that this header file can be * used independently. * * May 28 1998, Toni Ronkko * First version. *****************************************************************************/ #ifndef DIRENT_H #define DIRENT_H #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86) # define _X86_ #endif #include #include #include #include #include #include #include #include #include #include #include /* Indicates that d_type field is available in dirent structure */ #define _DIRENT_HAVE_D_TYPE /* Indicates that d_namlen field is available in dirent structure */ #define _DIRENT_HAVE_D_NAMLEN /* Entries missing from MSVC 6.0 */ #if !defined(FILE_ATTRIBUTE_DEVICE) # define FILE_ATTRIBUTE_DEVICE 0x40 #endif /* File type and permission flags for stat() */ #if !defined(S_IFMT) # define S_IFMT _S_IFMT /* File type mask */ #endif #if !defined(S_IFDIR) # define S_IFDIR _S_IFDIR /* Directory */ #endif #if !defined(S_IFCHR) # define S_IFCHR _S_IFCHR /* Character device */ #endif #if !defined(S_IFFIFO) # define S_IFFIFO _S_IFFIFO /* Pipe */ #endif #if !defined(S_IFREG) # define S_IFREG _S_IFREG /* Regular file */ #endif #if !defined(S_IREAD) # define S_IREAD _S_IREAD /* Read permission */ #endif #if !defined(S_IWRITE) # define S_IWRITE _S_IWRITE /* Write permission */ #endif #if !defined(S_IEXEC) # define S_IEXEC _S_IEXEC /* Execute permission */ #endif #if !defined(S_IFIFO) # define S_IFIFO _S_IFIFO /* Pipe */ #endif #if !defined(S_IFBLK) # define S_IFBLK 0 /* Block device */ #endif #if !defined(S_IFLNK) # define S_IFLNK 0 /* Link */ #endif #if !defined(S_IFSOCK) # define S_IFSOCK 0 /* Socket */ #endif #if defined(_MSC_VER) # define S_IRUSR S_IREAD /* Read user */ # define S_IWUSR S_IWRITE /* Write user */ # define S_IXUSR 0 /* Execute user */ # define S_IRGRP 0 /* Read group */ # define S_IWGRP 0 /* Write group */ # define S_IXGRP 0 /* Execute group */ # define S_IROTH 0 /* Read others */ # define S_IWOTH 0 /* Write others */ # define S_IXOTH 0 /* Execute others */ #endif /* Maximum length of file name */ #if !defined(PATH_MAX) # define PATH_MAX MAX_PATH #endif #if !defined(FILENAME_MAX) # define FILENAME_MAX MAX_PATH #endif #if !defined(NAME_MAX) # define NAME_MAX FILENAME_MAX #endif /* File type flags for d_type */ #define DT_UNKNOWN 0 #define DT_REG S_IFREG #define DT_DIR S_IFDIR #define DT_FIFO S_IFIFO #define DT_SOCK S_IFSOCK #define DT_CHR S_IFCHR #define DT_BLK S_IFBLK /* Macros for converting between st_mode and d_type */ #define IFTODT(mode) ((mode) & S_IFMT) #define DTTOIF(type) (type) /* * File type macros. Note that block devices, sockets and links cannot be * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are * only defined for compatibility. These macros should always return false * on Windows. */ #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) /* Return the exact length of d_namlen without zero terminator */ #define _D_EXACT_NAMLEN(p) ((p)->d_namlen) /* Return number of bytes needed to store d_namlen */ #define _D_ALLOC_NAMLEN(p) (PATH_MAX + 1) #ifdef __cplusplus extern "C" { #endif /* Wide-character version */ struct _wdirent { long d_ino; /* Always zero */ unsigned short d_reclen; /* Structure size */ size_t d_namlen; /* Length of name without \0 */ int d_type; /* File type */ wchar_t d_name[PATH_MAX + 1]; /* File name */ }; typedef struct _wdirent _wdirent; struct _WDIR { struct _wdirent ent; /* Current directory entry */ WIN32_FIND_DATAW data; /* Private file data */ int cached; /* True if data is valid */ HANDLE handle; /* Win32 search handle */ wchar_t *patt; /* Initial directory name */ }; typedef struct _WDIR _WDIR; static _WDIR *_wopendir (const wchar_t *dirname); static struct _wdirent *_wreaddir (_WDIR *dirp); static int _wclosedir (_WDIR *dirp); static void _wrewinddir (_WDIR* dirp); /* For compatibility with Symbian */ #define wdirent _wdirent #define WDIR _WDIR #define wopendir _wopendir #define wreaddir _wreaddir #define wclosedir _wclosedir #define wrewinddir _wrewinddir /* Multi-byte character versions */ struct dirent { long d_ino; /* Always zero */ unsigned short d_reclen; /* Structure size */ size_t d_namlen; /* Length of name without \0 */ int d_type; /* File type */ char d_name[PATH_MAX + 1]; /* File name */ }; typedef struct dirent dirent; struct DIR { struct dirent ent; struct _WDIR *wdirp; }; typedef struct DIR DIR; static DIR *opendir (const char *dirname); static struct dirent *readdir (DIR *dirp); static int closedir (DIR *dirp); static void rewinddir (DIR* dirp); /* Internal utility functions */ static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp); static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp); static int dirent_mbstowcs_s( size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count); static int dirent_wcstombs_s( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count); static void dirent_set_errno (int error); /* * Open directory stream DIRNAME for read and return a pointer to the * internal working area that is used to retrieve individual directory * entries. */ static _WDIR* _wopendir( const wchar_t *dirname) { _WDIR *dirp = NULL; int error; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { dirent_set_errno (ENOENT); return NULL; } /* Allocate new _WDIR structure */ dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); if (dirp != NULL) { DWORD n; /* Reset _WDIR structure */ dirp->handle = INVALID_HANDLE_VALUE; dirp->patt = NULL; dirp->cached = 0; /* Compute the length of full path plus zero terminator */ n = GetFullPathNameW (dirname, 0, NULL, NULL); /* Allocate room for absolute directory name and search pattern */ dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); if (dirp->patt) { /* * Convert relative directory name to an absolute one. This * allows rewinddir() to function correctly even when current * working directory is changed between opendir() and rewinddir(). */ n = GetFullPathNameW (dirname, n, dirp->patt, NULL); if (n > 0) { wchar_t *p; /* Append search pattern \* to the directory name */ p = dirp->patt + n; if (dirp->patt < p) { switch (p[-1]) { case '\\': case '/': case ':': /* Directory ends in path separator, e.g. c:\temp\ */ /*NOP*/; break; default: /* Directory name doesn't end in path separator */ *p++ = '\\'; } } *p++ = '*'; *p = '\0'; /* Open directory stream and retrieve the first entry */ if (dirent_first (dirp)) { /* Directory stream opened successfully */ error = 0; } else { /* Cannot retrieve first entry */ error = 1; dirent_set_errno (ENOENT); } } else { /* Cannot retrieve full path name */ dirent_set_errno (ENOENT); error = 1; } } else { /* Cannot allocate memory for search pattern */ error = 1; } } else { /* Cannot allocate _WDIR structure */ error = 1; } /* Clean up in case of error */ if (error && dirp) { _wclosedir (dirp); dirp = NULL; } return dirp; } /* * Read next directory entry. The directory entry is returned in dirent * structure in the d_name field. Individual directory entries returned by * this function include regular files, sub-directories, pseudo-directories * "." and ".." as well as volume labels, hidden files and system files. */ static struct _wdirent* _wreaddir( _WDIR *dirp) { WIN32_FIND_DATAW *datap; struct _wdirent *entp; /* Read next directory entry */ datap = dirent_next (dirp); if (datap) { size_t n; DWORD attr; /* Pointer to directory entry to return */ entp = &dirp->ent; /* * Copy file name as wide-character string. If the file name is too * long to fit in to the destination buffer, then truncate file name * to PATH_MAX characters and zero-terminate the buffer. */ n = 0; while (n < PATH_MAX && datap->cFileName[n] != 0) { entp->d_name[n] = datap->cFileName[n]; n++; } dirp->ent.d_name[n] = 0; /* Length of file name excluding zero terminator */ entp->d_namlen = n; /* File type */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { entp->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { entp->d_type = DT_DIR; } else { entp->d_type = DT_REG; } /* Reset dummy fields */ entp->d_ino = 0; entp->d_reclen = sizeof (struct _wdirent); } else { /* Last directory entry read */ entp = NULL; } return entp; } /* * Close directory stream opened by opendir() function. This invalidates the * DIR structure as well as any directory entry read previously by * _wreaddir(). */ static int _wclosedir( _WDIR *dirp) { int ok; if (dirp) { /* Release search handle */ if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose (dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; } /* Release search pattern */ if (dirp->patt) { free (dirp->patt); dirp->patt = NULL; } /* Release directory structure */ free (dirp); ok = /*success*/0; } else { /* Invalid directory stream */ dirent_set_errno (EBADF); ok = /*failure*/-1; } return ok; } /* * Rewind directory stream such that _wreaddir() returns the very first * file name again. */ static void _wrewinddir( _WDIR* dirp) { if (dirp) { /* Release existing search handle */ if (dirp->handle != INVALID_HANDLE_VALUE) { FindClose (dirp->handle); } /* Open new search handle */ dirent_first (dirp); } } /* Get first directory entry (internal) */ static WIN32_FIND_DATAW* dirent_first( _WDIR *dirp) { WIN32_FIND_DATAW *datap; /* Open directory and retrieve the first entry */ dirp->handle = FindFirstFileW (dirp->patt, &dirp->data); if (dirp->handle != INVALID_HANDLE_VALUE) { /* a directory entry is now waiting in memory */ datap = &dirp->data; dirp->cached = 1; } else { /* Failed to re-open directory: no directory entry in memory */ dirp->cached = 0; datap = NULL; } return datap; } /* Get next directory entry (internal) */ static WIN32_FIND_DATAW* dirent_next( _WDIR *dirp) { WIN32_FIND_DATAW *p; /* Get next directory entry */ if (dirp->cached != 0) { /* A valid directory entry already in memory */ p = &dirp->data; dirp->cached = 0; } else if (dirp->handle != INVALID_HANDLE_VALUE) { /* Get the next directory entry from stream */ if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) { /* Got a file */ p = &dirp->data; } else { /* The very last entry has been processed or an error occured */ FindClose (dirp->handle); dirp->handle = INVALID_HANDLE_VALUE; p = NULL; } } else { /* End of directory stream reached */ p = NULL; } return p; } /* * Open directory stream using plain old C-string. */ static DIR* opendir( const char *dirname) { struct DIR *dirp; int error; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { dirent_set_errno (ENOENT); return NULL; } /* Allocate memory for DIR structure */ dirp = (DIR*) malloc (sizeof (struct DIR)); if (dirp) { wchar_t wname[PATH_MAX + 1]; size_t n; /* Convert directory name to wide-character string */ error = dirent_mbstowcs_s( &n, wname, PATH_MAX + 1, dirname, PATH_MAX); if (!error) { /* Open directory stream using wide-character name */ dirp->wdirp = _wopendir (wname); if (dirp->wdirp) { /* Directory stream opened */ error = 0; } else { /* Failed to open directory stream */ error = 1; } } else { /* * Cannot convert file name to wide-character string. This * occurs if the string contains invalid multi-byte sequences or * the output buffer is too small to contain the resulting * string. */ error = 1; } } else { /* Cannot allocate DIR structure */ error = 1; } /* Clean up in case of error */ if (error && dirp) { free (dirp); dirp = NULL; } return dirp; } /* * Read next directory entry. * * When working with text consoles, please note that file names returned by * readdir() are represented in the default ANSI code page while any output to * console is typically formatted on another code page. Thus, non-ASCII * characters in file names will not usually display correctly on console. The * problem can be fixed in two ways: (1) change the character set of console * to 1252 using chcp utility and use Lucida Console font, or (2) use * _cprintf function when writing to console. The _cprinf() will re-encode * ANSI strings to the console code page so many non-ASCII characters will * display correcly. */ static struct dirent* readdir( DIR *dirp) { WIN32_FIND_DATAW *datap; struct dirent *entp; /* Read next directory entry */ datap = dirent_next (dirp->wdirp); if (datap) { size_t n; int error; /* Attempt to convert file name to multi-byte string */ error = dirent_wcstombs_s( &n, dirp->ent.d_name, MAX_PATH + 1, datap->cFileName, MAX_PATH); /* * If the file name cannot be represented by a multi-byte string, * then attempt to use old 8+3 file name. This allows traditional * Unix-code to access some file names despite of unicode * characters, although file names may seem unfamiliar to the user. * * Be ware that the code below cannot come up with a short file * name unless the file system provides one. At least * VirtualBox shared folders fail to do this. */ if (error && datap->cAlternateFileName[0] != '\0') { error = dirent_wcstombs_s( &n, dirp->ent.d_name, MAX_PATH + 1, datap->cAlternateFileName, sizeof (datap->cAlternateFileName) / sizeof (datap->cAlternateFileName[0])); } if (!error) { DWORD attr; /* Initialize directory entry for return */ entp = &dirp->ent; /* Length of file name excluding zero terminator */ entp->d_namlen = n - 1; /* File attributes */ attr = datap->dwFileAttributes; if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) { entp->d_type = DT_CHR; } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { entp->d_type = DT_DIR; } else { entp->d_type = DT_REG; } /* Reset dummy fields */ entp->d_ino = 0; entp->d_reclen = sizeof (struct dirent); } else { /* * Cannot convert file name to multi-byte string so construct * an errornous directory entry and return that. Note that * we cannot return NULL as that would stop the processing * of directory entries completely. */ entp = &dirp->ent; entp->d_name[0] = '?'; entp->d_name[1] = '\0'; entp->d_namlen = 1; entp->d_type = DT_UNKNOWN; entp->d_ino = 0; entp->d_reclen = 0; } } else { /* No more directory entries */ entp = NULL; } return entp; } /* * Close directory stream. */ static int closedir( DIR *dirp) { int ok; if (dirp) { /* Close wide-character directory stream */ ok = _wclosedir (dirp->wdirp); dirp->wdirp = NULL; /* Release multi-byte character version */ free (dirp); } else { /* Invalid directory stream */ dirent_set_errno (EBADF); ok = /*failure*/-1; } return ok; } /* * Rewind directory stream to beginning. */ static void rewinddir( DIR* dirp) { /* Rewind wide-character string directory stream */ _wrewinddir (dirp->wdirp); } /* Convert multi-byte string to wide character string */ static int dirent_mbstowcs_s( size_t *pReturnValue, wchar_t *wcstr, size_t sizeInWords, const char *mbstr, size_t count) { int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual Studio 2005 or later */ error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count); #else /* Older Visual Studio or non-Microsoft compiler */ size_t n; /* Convert to wide-character string */ n = mbstowcs (wcstr, mbstr, count); if (n < sizeInWords) { /* Zero-terminate output buffer */ if (wcstr) { wcstr[n] = 0; } /* Length of resuting multi-byte string WITH zero terminator */ if (pReturnValue) { *pReturnValue = n + 1; } /* Success */ error = 0; } else { /* Could not convert string */ error = 1; } #endif return error; } /* Convert wide-character string to multi-byte string */ static int dirent_wcstombs_s( size_t *pReturnValue, char *mbstr, size_t sizeInBytes, const wchar_t *wcstr, size_t count) { int error; #if defined(_MSC_VER) && _MSC_VER >= 1400 /* Microsoft Visual Studio 2005 or later */ error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count); #else /* Older Visual Studio or non-Microsoft compiler */ size_t n; /* Convert to multi-byte string */ n = wcstombs (mbstr, wcstr, count); if (n < sizeInBytes) { /* Zero-terminate output buffer */ if (mbstr) { mbstr[n] = '\0'; } /* Lenght of resulting multi-bytes string WITH zero-terminator */ if (pReturnValue) { *pReturnValue = n + 1; } /* Success */ error = 0; } else { /* Cannot convert string */ error = 1; } #endif return error; } /* Set errno variable */ static void dirent_set_errno( int error) { #if defined(_MSC_VER) /* Microsoft Visual Studio */ _set_errno (error); #else /* Non-Microsoft compiler */ errno = error; #endif } #ifdef __cplusplus } #endif #endif /*DIRENT_H*/ tqsl-2.0/src/tqsllib2.def0000664000076400007640000004716512231073120015355 0ustar rmurphyrmurphyLIBRARY tqsllib2.dll EXPORTS _tqsl_getSelectedCertificate@12 tqsl_getSelectedCertificate@12=_tqsl_getSelectedCertificate@12 tqsl_getSelectedCertificate=_tqsl_getSelectedCertificate@12 _tqsl_getNumStationLocationCapturePages@8 tqsl_getNumStationLocationCapturePages@8=_tqsl_getNumStationLocationCapturePages@8 tqsl_getNumStationLocationCapturePages=_tqsl_getNumStationLocationCapturePages@8 _tqsl_adifGetError@4 tqsl_adifGetError@4=_tqsl_adifGetError@4 tqsl_adifGetError=_tqsl_adifGetError@4 _tqsl_adifMakeField@24 tqsl_adifMakeField@24=_tqsl_adifMakeField@24 tqsl_adifMakeField=_tqsl_adifMakeField@24 _tqsl_beginADIF@8 tqsl_beginADIF@8=_tqsl_beginADIF@8 tqsl_beginADIF=_tqsl_beginADIF@8 _tqsl_beginADIFConverter@20 tqsl_beginADIFConverter@20=_tqsl_beginADIFConverter@20 tqsl_beginADIFConverter=_tqsl_beginADIFConverter@20 _tqsl_beginCabrillo@8 tqsl_beginCabrillo@8=_tqsl_beginCabrillo@8 tqsl_beginCabrillo=_tqsl_beginCabrillo@8 _tqsl_beginCabrilloConverter@20 tqsl_beginCabrilloConverter@20=_tqsl_beginCabrilloConverter@20 tqsl_beginCabrilloConverter=_tqsl_beginCabrilloConverter@20 _tqsl_beginSigning@16 tqsl_beginSigning@16=_tqsl_beginSigning@16 tqsl_beginSigning=_tqsl_beginSigning@16 _tqsl_cabrilloGetError@4 tqsl_cabrilloGetError@4=_tqsl_cabrilloGetError@4 tqsl_cabrilloGetError=_tqsl_cabrilloGetError@4 _tqsl_checkSigningStatus@4 tqsl_checkSigningStatus@4=_tqsl_checkSigningStatus@4 tqsl_checkSigningStatus=_tqsl_checkSigningStatus@4 _tqsl_clearADIFModes@0 tqsl_clearADIFModes@0=_tqsl_clearADIFModes@0 tqsl_clearADIFModes=_tqsl_clearADIFModes@0 _tqsl_clearCabrilloMap@0 tqsl_clearCabrilloMap@0=_tqsl_clearCabrilloMap@0 tqsl_clearCabrilloMap=_tqsl_clearCabrilloMap@0 _tqsl_compareDates@8 tqsl_compareDates@8=_tqsl_compareDates@8 tqsl_compareDates=_tqsl_compareDates@8 _tqsl_convertDateToText@12 tqsl_convertDateToText@12=_tqsl_convertDateToText@12 tqsl_convertDateToText=_tqsl_convertDateToText@12 _tqsl_convertTimeToText@12 tqsl_convertTimeToText@12=_tqsl_convertTimeToText@12 tqsl_convertTimeToText=_tqsl_convertTimeToText@12 _tqsl_converterCommit@4 tqsl_converterCommit@4=_tqsl_converterCommit@4 tqsl_converterCommit=_tqsl_converterCommit@4 _tqsl_converterRollBack@4 tqsl_converterRollBack@4=_tqsl_converterRollBack@4 tqsl_converterRollBack=_tqsl_converterRollBack@4 _tqsl_createCertRequest@16 tqsl_createCertRequest@16=_tqsl_createCertRequest@16 tqsl_createCertRequest=_tqsl_createCertRequest@16 _tqsl_decodeBase64@12 tqsl_decodeBase64@12=_tqsl_decodeBase64@12 tqsl_decodeBase64=_tqsl_decodeBase64@12 _tqsl_deleteCertificate@4 tqsl_deleteCertificate@4=_tqsl_deleteCertificate@4 tqsl_deleteCertificate=_tqsl_deleteCertificate@4 _tqsl_deleteStationLocation@4 tqsl_deleteStationLocation@4=_tqsl_deleteStationLocation@4 tqsl_deleteStationLocation=_tqsl_deleteStationLocation@4 _tqsl_encodeBase64@16 tqsl_encodeBase64@16=_tqsl_encodeBase64@16 tqsl_encodeBase64=_tqsl_encodeBase64@16 _tqsl_endADIF@4 tqsl_endADIF@4=_tqsl_endADIF@4 tqsl_endADIF=_tqsl_endADIF@4 _tqsl_endCabrillo@4 tqsl_endCabrillo@4=_tqsl_endCabrillo@4 tqsl_endCabrillo=_tqsl_endCabrillo@4 _tqsl_endConverter@4 tqsl_endConverter@4=_tqsl_endConverter@4 tqsl_endConverter=_tqsl_endConverter@4 _tqsl_endSigning@4 tqsl_endSigning@4=_tqsl_endSigning@4 tqsl_endSigning=_tqsl_endSigning@4 _tqsl_endStationLocationCapture@4 tqsl_endStationLocationCapture@4=_tqsl_endStationLocationCapture@4 tqsl_endStationLocationCapture=_tqsl_endStationLocationCapture@4 _tqsl_exportPKCS12File@12 tqsl_exportPKCS12File@12=_tqsl_exportPKCS12File@12 tqsl_exportPKCS12File=_tqsl_exportPKCS12File@12 _tqsl_freeCertificate@4 tqsl_freeCertificate@4=_tqsl_freeCertificate@4 tqsl_freeCertificate=_tqsl_freeCertificate@4 _tqsl_getADIFField@24 tqsl_getADIFField@24=_tqsl_getADIFField@24 tqsl_getADIFField=_tqsl_getADIFField@24 _tqsl_getADIFLine@8 tqsl_getADIFLine@8=_tqsl_getADIFLine@8 tqsl_getADIFLine=_tqsl_getADIFLine@8 _tqsl_getADIFMode@12 tqsl_getADIFMode@12=_tqsl_getADIFMode@12 tqsl_getADIFMode=_tqsl_getADIFMode@12 _tqsl_getBand@20 tqsl_getBand@20=_tqsl_getBand@20 tqsl_getBand=_tqsl_getBand@20 _tqsl_getCabrilloContest@12 tqsl_getCabrilloContest@12=_tqsl_getCabrilloContest@12 tqsl_getCabrilloContest=_tqsl_getCabrilloContest@12 _tqsl_getCabrilloField@12 tqsl_getCabrilloField@12=_tqsl_getCabrilloField@12 tqsl_getCabrilloField=_tqsl_getCabrilloField@12 _tqsl_getCabrilloFreqType@8 tqsl_getCabrilloFreqType@8=_tqsl_getCabrilloFreqType@8 tqsl_getCabrilloFreqType=_tqsl_getCabrilloFreqType@8 _tqsl_getCabrilloLine@8 tqsl_getCabrilloLine@8=_tqsl_getCabrilloLine@8 tqsl_getCabrilloLine=_tqsl_getCabrilloLine@8 _tqsl_getCabrilloMapEntry@12 tqsl_getCabrilloMapEntry@12=_tqsl_getCabrilloMapEntry@12 tqsl_getCabrilloMapEntry=_tqsl_getCabrilloMapEntry@12 _tqsl_getCabrilloRecordText@4 tqsl_getCabrilloRecordText@4=_tqsl_getCabrilloRecordText@4 tqsl_getCabrilloRecordText=_tqsl_getCabrilloRecordText@4 _tqsl_getCertificateAROName@12 tqsl_getCertificateAROName@12=_tqsl_getCertificateAROName@12 tqsl_getCertificateAROName=_tqsl_getCertificateAROName@12 _tqsl_getCertificateCallSign@12 tqsl_getCertificateCallSign@12=_tqsl_getCertificateCallSign@12 tqsl_getCertificateCallSign=_tqsl_getCertificateCallSign@12 _tqsl_getCertificateDXCCEntity@8 tqsl_getCertificateDXCCEntity@8=_tqsl_getCertificateDXCCEntity@8 tqsl_getCertificateDXCCEntity=_tqsl_getCertificateDXCCEntity@8 _tqsl_getCertificateEmailAddress@12 tqsl_getCertificateEmailAddress@12=_tqsl_getCertificateEmailAddress@12 tqsl_getCertificateEmailAddress=_tqsl_getCertificateEmailAddress@12 _tqsl_getCertificateEncoded@12 tqsl_getCertificateEncoded@12=_tqsl_getCertificateEncoded@12 tqsl_getCertificateEncoded=_tqsl_getCertificateEncoded@12 _tqsl_getCertificateIssuer@12 tqsl_getCertificateIssuer@12=_tqsl_getCertificateIssuer@12 tqsl_getCertificateIssuer=_tqsl_getCertificateIssuer@12 _tqsl_getCertificateIssuerOrganization@12 tqsl_getCertificateIssuerOrganization@12=_tqsl_getCertificateIssuerOrganization@12 tqsl_getCertificateIssuerOrganization=_tqsl_getCertificateIssuerOrganization@12 _tqsl_getCertificateIssuerOrganizationalUnit@12 tqsl_getCertificateIssuerOrganizationalUnit@12=_tqsl_getCertificateIssuerOrganizationalUnit@12 tqsl_getCertificateIssuerOrganizationalUnit=_tqsl_getCertificateIssuerOrganizationalUnit@12 _tqsl_getCertificateKeyOnly@8 tqsl_getCertificateKeyOnly@8=_tqsl_getCertificateKeyOnly@8 tqsl_getCertificateKeyOnly=_tqsl_getCertificateKeyOnly@8 _tqsl_getCertificateNotAfterDate@8 tqsl_getCertificateNotAfterDate@8=_tqsl_getCertificateNotAfterDate@8 tqsl_getCertificateNotAfterDate=_tqsl_getCertificateNotAfterDate@8 _tqsl_getCertificateNotBeforeDate@8 tqsl_getCertificateNotBeforeDate@8=_tqsl_getCertificateNotBeforeDate@8 tqsl_getCertificateNotBeforeDate=_tqsl_getCertificateNotBeforeDate@8 _tqsl_getCertificatePrivateKeyType@4 tqsl_getCertificatePrivateKeyType@4=_tqsl_getCertificatePrivateKeyType@4 tqsl_getCertificatePrivateKeyType=_tqsl_getCertificatePrivateKeyType@4 _tqsl_getCertificateQSONotAfterDate@8 tqsl_getCertificateQSONotAfterDate@8=_tqsl_getCertificateQSONotAfterDate@8 tqsl_getCertificateQSONotAfterDate=_tqsl_getCertificateQSONotAfterDate@8 _tqsl_getCertificateQSONotBeforeDate@8 tqsl_getCertificateQSONotBeforeDate@8=_tqsl_getCertificateQSONotBeforeDate@8 tqsl_getCertificateQSONotBeforeDate=_tqsl_getCertificateQSONotBeforeDate@8 _tqsl_getCertificateRequestAddress1@12 tqsl_getCertificateRequestAddress1@12=_tqsl_getCertificateRequestAddress1@12 tqsl_getCertificateRequestAddress1=_tqsl_getCertificateRequestAddress1@12 _tqsl_getCertificateRequestAddress2@12 tqsl_getCertificateRequestAddress2@12=_tqsl_getCertificateRequestAddress2@12 tqsl_getCertificateRequestAddress2=_tqsl_getCertificateRequestAddress2@12 _tqsl_getCertificateRequestCity@12 tqsl_getCertificateRequestCity@12=_tqsl_getCertificateRequestCity@12 tqsl_getCertificateRequestCity=_tqsl_getCertificateRequestCity@12 _tqsl_getCertificateRequestCountry@12 tqsl_getCertificateRequestCountry@12=_tqsl_getCertificateRequestCountry@12 tqsl_getCertificateRequestCountry=_tqsl_getCertificateRequestCountry@12 _tqsl_getCertificateRequestPostalCode@12 tqsl_getCertificateRequestPostalCode@12=_tqsl_getCertificateRequestPostalCode@12 tqsl_getCertificateRequestPostalCode=_tqsl_getCertificateRequestPostalCode@12 _tqsl_getCertificateRequestState@12 tqsl_getCertificateRequestState@12=_tqsl_getCertificateRequestState@12 tqsl_getCertificateRequestState=_tqsl_getCertificateRequestState@12 _tqsl_getCertificateSerial@8 tqsl_getCertificateSerial@8=_tqsl_getCertificateSerial@8 tqsl_getCertificateSerial=_tqsl_getCertificateSerial@8 _tqsl_getCertificateSerialExt@12 tqsl_getCertificateSerialExt@12=_tqsl_getCertificateSerialExt@12 tqsl_getCertificateSerialExt=_tqsl_getCertificateSerialExt@12 _tqsl_getCertificateSerialLength@4 tqsl_getCertificateSerialLength@4=_tqsl_getCertificateSerialLength@4 tqsl_getCertificateSerialLength=_tqsl_getCertificateSerialLength@4 _tqsl_getConfigVersion@8 tqsl_getConfigVersion@8=_tqsl_getConfigVersion@8 tqsl_getConfigVersion=_tqsl_getConfigVersion@8 _tqsl_getConverterCert@8 tqsl_getConverterCert@8=_tqsl_getConverterCert@8 tqsl_getConverterCert=_tqsl_getConverterCert@8 _tqsl_getConverterGABBI@4 tqsl_getConverterGABBI@4=_tqsl_getConverterGABBI@4 tqsl_getConverterGABBI=_tqsl_getConverterGABBI@4 _tqsl_getConverterLine@8 tqsl_getConverterLine@8=_tqsl_getConverterLine@8 tqsl_getConverterLine=_tqsl_getConverterLine@8 _tqsl_getConverterRecordText@4 tqsl_getConverterRecordText@4=_tqsl_getConverterRecordText@4 tqsl_getConverterRecordText=_tqsl_getConverterRecordText@4 _tqsl_getDXCCEntity@12 tqsl_getDXCCEntity@12=_tqsl_getDXCCEntity@12 tqsl_getDXCCEntity=_tqsl_getDXCCEntity@12 _tqsl_getDXCCEntityName@8 tqsl_getDXCCEntityName@8=_tqsl_getDXCCEntityName@8 tqsl_getDXCCEntityName=_tqsl_getDXCCEntityName@8 _tqsl_getDXCCZoneMap@8 tqsl_getDXCCZoneMap@8=_tqsl_getDXCCZoneMap@8 tqsl_getDXCCZoneMap=_tqsl_getDXCCZoneMap@8 _tqsl_getErrorString@0 tqsl_getErrorString@0=_tqsl_getErrorString@0 tqsl_getErrorString=_tqsl_getErrorString@0 _tqsl_getErrorString_v@4 tqsl_getErrorString_v@4=_tqsl_getErrorString_v@4 tqsl_getErrorString_v=_tqsl_getErrorString_v@4 _tqsl_getGABBItCERT@8 tqsl_getGABBItCERT@8=_tqsl_getGABBItCERT@8 tqsl_getGABBItCERT=_tqsl_getGABBItCERT@8 _tqsl_getGABBItCONTACT@16 tqsl_getGABBItCONTACT@16=_tqsl_getGABBItCONTACT@16 tqsl_getGABBItCONTACT=_tqsl_getGABBItCONTACT@16 _tqsl_getGABBItCONTACTData@24 tqsl_getGABBItCONTACTData@24=_tqsl_getGABBItCONTACTData@24 tqsl_getGABBItCONTACTData=_tqsl_getGABBItCONTACTData@24 _tqsl_getGABBItSTATION@12 tqsl_getGABBItSTATION@12=_tqsl_getGABBItSTATION@12 tqsl_getGABBItSTATION=_tqsl_getGABBItSTATION@12 _tqsl_getLocationCallSign@12 tqsl_getLocationCallSign@12=_tqsl_getLocationCallSign@12 tqsl_getLocationCallSign=_tqsl_getLocationCallSign@12 _tqsl_getLocationDXCCEntity@8 tqsl_getLocationDXCCEntity@8=_tqsl_getLocationDXCCEntity@8 tqsl_getLocationDXCCEntity=_tqsl_getLocationDXCCEntity@8 _tqsl_getLocationFieldChanged@12 tqsl_getLocationFieldChanged@12=_tqsl_getLocationFieldChanged@12 tqsl_getLocationFieldChanged=_tqsl_getLocationFieldChanged@12 _tqsl_getLocationFieldCharData@16 tqsl_getLocationFieldCharData@16=_tqsl_getLocationFieldCharData@16 tqsl_getLocationFieldCharData=_tqsl_getLocationFieldCharData@16 _tqsl_getLocationFieldDataGABBI@16 tqsl_getLocationFieldDataGABBI@16=_tqsl_getLocationFieldDataGABBI@16 tqsl_getLocationFieldDataGABBI=_tqsl_getLocationFieldDataGABBI@16 _tqsl_getLocationFieldDataGABBISize@12 tqsl_getLocationFieldDataGABBISize@12=_tqsl_getLocationFieldDataGABBISize@12 tqsl_getLocationFieldDataGABBISize=_tqsl_getLocationFieldDataGABBISize@12 _tqsl_getLocationFieldDataLabel@16 tqsl_getLocationFieldDataLabel@16=_tqsl_getLocationFieldDataLabel@16 tqsl_getLocationFieldDataLabel=_tqsl_getLocationFieldDataLabel@16 _tqsl_getLocationFieldDataLabelSize@12 tqsl_getLocationFieldDataLabelSize@12=_tqsl_getLocationFieldDataLabelSize@12 tqsl_getLocationFieldDataLabelSize=_tqsl_getLocationFieldDataLabelSize@12 _tqsl_getLocationFieldDataLength@12 tqsl_getLocationFieldDataLength@12=_tqsl_getLocationFieldDataLength@12 tqsl_getLocationFieldDataLength=_tqsl_getLocationFieldDataLength@12 _tqsl_getLocationFieldDataType@12 tqsl_getLocationFieldDataType@12=_tqsl_getLocationFieldDataType@12 tqsl_getLocationFieldDataType=_tqsl_getLocationFieldDataType@12 _tqsl_getLocationFieldFlags@12 tqsl_getLocationFieldFlags@12=_tqsl_getLocationFieldFlags@12 tqsl_getLocationFieldFlags=_tqsl_getLocationFieldFlags@12 _tqsl_getLocationFieldIndex@12 tqsl_getLocationFieldIndex@12=_tqsl_getLocationFieldIndex@12 tqsl_getLocationFieldIndex=_tqsl_getLocationFieldIndex@12 _tqsl_getLocationFieldInputType@12 tqsl_getLocationFieldInputType@12=_tqsl_getLocationFieldInputType@12 tqsl_getLocationFieldInputType=_tqsl_getLocationFieldInputType@12 _tqsl_getLocationFieldIntData@12 tqsl_getLocationFieldIntData@12=_tqsl_getLocationFieldIntData@12 tqsl_getLocationFieldIntData=_tqsl_getLocationFieldIntData@12 _tqsl_getLocationFieldListItem@20 tqsl_getLocationFieldListItem@20=_tqsl_getLocationFieldListItem@20 tqsl_getLocationFieldListItem=_tqsl_getLocationFieldListItem@20 _tqsl_getMaxSignatureSize@8 tqsl_getMaxSignatureSize@8=_tqsl_getMaxSignatureSize@8 tqsl_getMaxSignatureSize=_tqsl_getMaxSignatureSize@8 _tqsl_getMode@12 tqsl_getMode@12=_tqsl_getMode@12 tqsl_getMode=_tqsl_getMode@12 _tqsl_getNumBand@4 tqsl_getNumBand@4=_tqsl_getNumBand@4 tqsl_getNumBand=_tqsl_getNumBand@4 _tqsl_getNumDXCCEntity@4 tqsl_getNumDXCCEntity@4=_tqsl_getNumDXCCEntity@4 tqsl_getNumDXCCEntity=_tqsl_getNumDXCCEntity@4 _tqsl_getNumLocationField@8 tqsl_getNumLocationField@8=_tqsl_getNumLocationField@8 tqsl_getNumLocationField=_tqsl_getNumLocationField@8 _tqsl_getNumLocationFieldListItems@12 tqsl_getNumLocationFieldListItems@12=_tqsl_getNumLocationFieldListItems@12 tqsl_getNumLocationFieldListItems=_tqsl_getNumLocationFieldListItems@12 _tqsl_getNumMode@4 tqsl_getNumMode@4=_tqsl_getNumMode@4 tqsl_getNumMode=_tqsl_getNumMode@4 _tqsl_getNumPropagationMode@4 tqsl_getNumPropagationMode@4=_tqsl_getNumPropagationMode@4 tqsl_getNumPropagationMode=_tqsl_getNumPropagationMode@4 _tqsl_getNumProviders@4 tqsl_getNumProviders@4=_tqsl_getNumProviders@4 tqsl_getNumProviders=_tqsl_getNumProviders@4 _tqsl_getNumSatellite@4 tqsl_getNumSatellite@4=_tqsl_getNumSatellite@4 tqsl_getNumSatellite=_tqsl_getNumSatellite@4 _tqsl_getNumStationLocations@8 tqsl_getNumStationLocations@8=_tqsl_getNumStationLocations@8 tqsl_getNumStationLocations=_tqsl_getNumStationLocations@8 _tqsl_getPropagationMode@12 tqsl_getPropagationMode@12=_tqsl_getPropagationMode@12 tqsl_getPropagationMode=_tqsl_getPropagationMode@12 _tqsl_getProvider@8 tqsl_getProvider@8=_tqsl_getProvider@8 tqsl_getProvider=_tqsl_getProvider@8 _tqsl_getSatellite@20 tqsl_getSatellite@20=_tqsl_getSatellite@20 tqsl_getSatellite=_tqsl_getSatellite@20 _tqsl_getSerialFromTQSLFile@8 tqsl_getSerialFromTQSLFile@8=_tqsl_getSerialFromTQSLFile@8 tqsl_getSerialFromTQSLFile=_tqsl_getSerialFromTQSLFile@8 _tqsl_getStationLocation@8 tqsl_getStationLocation@8=_tqsl_getStationLocation@8 tqsl_getStationLocation=_tqsl_getStationLocation@8 _tqsl_getStationLocationCallSign@16 tqsl_getStationLocationCallSign@16=_tqsl_getStationLocationCallSign@16 tqsl_getStationLocationCallSign=_tqsl_getStationLocationCallSign@16 _tqsl_getStationLocationCaptureName@12 tqsl_getStationLocationCaptureName@12=_tqsl_getStationLocationCaptureName@12 tqsl_getStationLocationCaptureName=_tqsl_getStationLocationCaptureName@12 _tqsl_getStationLocationCapturePage@8 tqsl_getStationLocationCapturePage@8=_tqsl_getStationLocationCapturePage@8 tqsl_getStationLocationCapturePage=_tqsl_getStationLocationCapturePage@8 _tqsl_getStationLocationName@16 tqsl_getStationLocationName@16=_tqsl_getStationLocationName@16 tqsl_getStationLocationName=_tqsl_getStationLocationName@16 _tqsl_getVersion@8 tqsl_getVersion@8=_tqsl_getVersion@8 tqsl_getVersion=_tqsl_getVersion@8 _tqsl_hasNextStationLocationCapture@8 tqsl_hasNextStationLocationCapture@8=_tqsl_hasNextStationLocationCapture@8 tqsl_hasNextStationLocationCapture=_tqsl_hasNextStationLocationCapture@8 _tqsl_hasPrevStationLocationCapture@8 tqsl_hasPrevStationLocationCapture@8=_tqsl_hasPrevStationLocationCapture@8 tqsl_hasPrevStationLocationCapture=_tqsl_hasPrevStationLocationCapture@8 _tqsl_importPKCS12File@24 tqsl_importPKCS12File@24=_tqsl_importPKCS12File@24 tqsl_importPKCS12File=_tqsl_importPKCS12File@24 _tqsl_importTQSLFile@12 tqsl_importTQSLFile@12=_tqsl_importTQSLFile@12 tqsl_importTQSLFile=_tqsl_importTQSLFile@12 _tqsl_init@0 tqsl_init@0=_tqsl_init@0 tqsl_init=_tqsl_init@0 _tqsl_initDate@8 tqsl_initDate@8=_tqsl_initDate@8 tqsl_initDate=_tqsl_initDate@8 _tqsl_initStationLocationCapture@4 tqsl_initStationLocationCapture@4=_tqsl_initStationLocationCapture@4 tqsl_initStationLocationCapture=_tqsl_initStationLocationCapture@4 _tqsl_initTime@8 tqsl_initTime@8=_tqsl_initTime@8 tqsl_initTime=_tqsl_initTime@8 _tqsl_isDateNull@4 tqsl_isDateNull@4=_tqsl_isDateNull@4 tqsl_isDateNull=_tqsl_isDateNull@4 _tqsl_isDateValid@4 tqsl_isDateValid@4=_tqsl_isDateValid@4 tqsl_isDateValid=_tqsl_isDateValid@4 _tqsl_isTimeValid@4 tqsl_isTimeValid@4=_tqsl_isTimeValid@4 tqsl_isTimeValid=_tqsl_isTimeValid@4 _tqsl_nextStationLocationCapture@4 tqsl_nextStationLocationCapture@4=_tqsl_nextStationLocationCapture@4 tqsl_nextStationLocationCapture=_tqsl_nextStationLocationCapture@4 _tqsl_prevStationLocationCapture@4 tqsl_prevStationLocationCapture@4=_tqsl_prevStationLocationCapture@4 tqsl_prevStationLocationCapture=_tqsl_prevStationLocationCapture@4 _tqsl_saveStationLocationCapture@8 tqsl_saveStationLocationCapture@8=_tqsl_saveStationLocationCapture@8 tqsl_saveStationLocationCapture=_tqsl_saveStationLocationCapture@8 _tqsl_selectCertificates@28 tqsl_selectCertificates@28=_tqsl_selectCertificates@28 tqsl_selectCertificates=_tqsl_selectCertificates@28 _tqsl_setADIFConverterDateFilter@12 tqsl_setADIFConverterDateFilter@12=_tqsl_setADIFConverterDateFilter@12 tqsl_setADIFConverterDateFilter=_tqsl_setADIFConverterDateFilter@12 _tqsl_setADIFMode@8 tqsl_setADIFMode@8=_tqsl_setADIFMode@8 tqsl_setADIFMode=_tqsl_setADIFMode@8 _tqsl_setCabrilloMapEntry@12 tqsl_setCabrilloMapEntry@12=_tqsl_setCabrilloMapEntry@12 tqsl_setCabrilloMapEntry=_tqsl_setCabrilloMapEntry@12 _tqsl_setConverterAllowBadCall@8 tqsl_setConverterAllowBadCall@8=_tqsl_setConverterAllowBadCall@8 tqsl_setConverterAllowBadCall=_tqsl_setConverterAllowBadCall@8 _tqsl_setConverterAllowDuplicates@8 tqsl_setConverterAllowDuplicates@8=_tqsl_setConverterAllowDuplicates@8 tqsl_setConverterAllowDuplicates=_tqsl_setConverterAllowDuplicates@8 _tqsl_setDirectory@4 tqsl_setDirectory@4=_tqsl_setDirectory@4 tqsl_setDirectory=_tqsl_setDirectory@4 _tqsl_setLocationFieldCharData@12 tqsl_setLocationFieldCharData@12=_tqsl_setLocationFieldCharData@12 tqsl_setLocationFieldCharData=_tqsl_setLocationFieldCharData@12 _tqsl_setLocationFieldIndex@12 tqsl_setLocationFieldIndex@12=_tqsl_setLocationFieldIndex@12 tqsl_setLocationFieldIndex=_tqsl_setLocationFieldIndex@12 _tqsl_setLocationFieldIntData@12 tqsl_setLocationFieldIntData@12=_tqsl_setLocationFieldIntData@12 tqsl_setLocationFieldIntData=_tqsl_setLocationFieldIntData@12 _tqsl_setStationLocationCaptureName@8 tqsl_setStationLocationCaptureName@8=_tqsl_setStationLocationCaptureName@8 tqsl_setStationLocationCaptureName=_tqsl_setStationLocationCaptureName@8 _tqsl_setStationLocationCapturePage@8 tqsl_setStationLocationCapturePage@8=_tqsl_setStationLocationCapturePage@8 tqsl_setStationLocationCapturePage=_tqsl_setStationLocationCapturePage@8 _tqsl_signDataBlock@20 tqsl_signDataBlock@20=_tqsl_signDataBlock@20 tqsl_signDataBlock=_tqsl_signDataBlock@20 _tqsl_signQSORecord@20 tqsl_signQSORecord@20=_tqsl_signQSORecord@20 tqsl_signQSORecord=_tqsl_signQSORecord@20 _tqsl_updateStationLocationCapture@4 tqsl_updateStationLocationCapture@4=_tqsl_updateStationLocationCapture@4 tqsl_updateStationLocationCapture=_tqsl_updateStationLocationCapture@4 _tqsl_verifyDataBlock@20 tqsl_verifyDataBlock@20=_tqsl_verifyDataBlock@20 tqsl_verifyDataBlock=_tqsl_verifyDataBlock@20 tQSL_ADIF_Error DATA tQSL_Cabrillo_Error DATA tQSL_CustomError DATA tQSL_Errno DATA tQSL_Error DATA tQSL_ErrorFile DATA tqsl-2.0/src/tqsllib.spec.in0000664000076400007640000000276412231073120016070 0ustar rmurphyrmurphySummary: The TrustedQSL library Name: tqsllib Version: @VERSION@ Release: 2 Copyright: Custom BSD-like Group: Development/Libraries Source: tqsllib-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-buildroot Requires: openssl expat zlib BuildPrereq: openssl-devel expat-devel zlib-devel %package devel Summary: The TrustedQSL Library development tools Group: System/Libraries %description The TrustedQSL library is used for generating digitally signed QSO records (records of Amateur Radio contacts). This package contains the library and configuration files needed to run TrustedQSL applications. %description devel The TrustedQSL library is used for generating digitally signed QSO records (records of Amateur Radio contacts). This package contains the header files needed to build TrustedQSL applications as well as a static tqsllib library and API documentation. %prep %setup -q -n tqsllib-%{version} %build # use --disable-docs because RPM handles docs itself cmake -DCMAKE_INSTALL_PREFIX=/usr . make %install make install %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc LICENSE ChangeLog /usr/lib/libtqsllib.so /usr/lib/libtqsllib.so.1 /usr/lib/libtqsllib.so.1.0.0 /usr/share/tqsl/config.xml /usr/bin/dumptqsldata %files devel %defattr(-,root,root) %doc LICENSE ChangeLog doxygen/html /usr/lib/libtqsllib.a /usr/lib/libtqsllib.la /usr/include/tqsllib.h /usr/include/tqslerrno.h /usr/include/cabrillo.h /usr/include/adif.h /usr/include/tqslconvert.h %post /sbin/ldconfig %postun /sbin/ldconfig tqsl-2.0/src/tqsllib.rc.in0000664000076400007640000000210312231073120015525 0ustar rmurphyrmurphy#include 1 VERSIONINFO FILEVERSION @TQSLLIB_VERSION_MAJOR@, @TQSLLIB_VERSION_MINOR@, 0, 0 PRODUCTVERSION @TQSLLIB_VERSION_MAJOR@, @TQSLLIB_VERSION_MINOR@, 0, 0 FILEFLAGSMASK 0 FILEFLAGS VS_FFI_FILEFLAGSMASK FILEOS VOS__WINDOWS32 FILETYPE VFT_DLL BEGIN BLOCK "StringFileInfo" BEGIN // Language type = U.S. English(0x0409) and Character Set = Windows, Multilingual(0x04e4) BLOCK "040904E4" // Matches VarFileInfo Translation hex value. BEGIN VALUE "CompanyName", "American Radio Relay League, Inc.\000" VALUE "FileDescription", "TrustedQSL Library\000" VALUE "FileVersion", "@TQSLLIB_VERSION@\000" VALUE "InternalName", "TQSLLIB\000" VALUE "LegalCopyright", "Copyright 2013 American Radio Relay League.\000" VALUE "OriginalFilename", "tqsllib@DLLVER@.dll\000" VALUE "ProductName", "TQSLLIB\000" VALUE "ProductVersion", "@TQSLLIB_VERSION@\000" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 END END tqsl-2.0/src/tqsllib.h0000664000076400007640000014444412231073120014762 0ustar rmurphyrmurphy/*************************************************************************** tqsllib.h - description ------------------- begin : Mon May 20 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: tqsllib.h,v 1.14 2013/03/01 13:26:44 k1mu Exp $ ***************************************************************************/ #ifndef TQSLLIB_H #define TQSLLIB_H #if defined(_WIN32) && !defined(TQSL_NODLL) #ifdef TQSLLIB_DEF #define DLLEXPORT __declspec(dllexport) #define DLLEXPORTDATA __declspec(dllexport) #define CALLCONVENTION __stdcall #else #define DLLEXPORT __declspec(dllimport) #define DLLEXPORTDATA __declspec(dllimport) #define CALLCONVENTION __stdcall #endif #else #define DLLEXPORT ///< Symbol exports - Windows only #define DLLEXPORTDATA ///< Symbol exports - Windows only #define CALLCONVENTION ///< Symbol exports - Windows only #endif #include "adif.h" #include "cabrillo.h" /** \file * tQSL library functions. */ /* Sizes */ #define TQSL_MAX_PATH_LEN 256 ///< Max length of a FS path #define TQSL_PASSWORD_MAX 80 ///< Max password length #define TQSL_NAME_ELEMENT_MAX 256 ///< Max Org name length #define TQSL_CALLSIGN_MAX 13 ///< Max callsign length #define TQSL_CRQ_NAME_MAX 60 ///< Max length of request name #define TQSL_CRQ_ADDR_MAX 80 ///< Max length of request addr #define TQSL_CRQ_CITY_MAX 80 ///< Max length of request city #define TQSL_CRQ_STATE_MAX 80 ///< Max length of request state #define TQSL_CRQ_POSTAL_MAX 20 ///< Max length of request zip #define TQSL_CRQ_COUNTRY_MAX 80 ///< Max length of req entity #define TQSL_CRQ_EMAIL_MAX 180 ///< Max length of req email #define TQSL_BAND_MAX 6 ///< Max length of a band name #define TQSL_MODE_MAX 16 ///< Max length of a mode name #define TQSL_FREQ_MAX 20 ///< Max length of a frequency #define TQSL_SATNAME_MAX 6 ///< Max length of a sat name #define TQSL_PROPMODE_MAX 6 ///< Max length of a prop mode #define TQSL_CERT_CB_USER 0 ///< Callback is for user cert #define TQSL_CERT_CB_CA 1 ///< Callback is for CA cert #define TQSL_CERT_CB_ROOT 2 ///< Callback is for root cert #define TQSL_CERT_CB_PKEY 3 ///< Callback is for private key #define TQSL_CERT_CB_CONFIG 4 ///< Callback for config file #define TQSL_CERT_CB_CERT_TYPE(x) ((x) & 0xf) ///< Type of the cert #define TQSL_CERT_CB_MILESTONE 0 ///< New certificate #define TQSL_CERT_CB_RESULT 0x10 ///< Cert import result #define TQSL_CERT_CB_CALL_TYPE(x) ((x) & TQSL_CERT_CB_RESULT) ///< Callback type #define TQSL_CERT_CB_PROMPT 0 ///< Callback prompt #define TQSL_CERT_CB_DUPLICATE 0x100 ///< Dupe cert callback #define TQSL_CERT_CB_ERROR 0x200 ///< Error import callback #define TQSL_CERT_CB_LOADED 0x300 ///< Cert loaded callback #define TQSL_CERT_CB_RESULT_TYPE(x) ((x) & 0x0f00) ///< Result type mask typedef void * tQSL_Cert; ///< Opaque certificate type typedef void * tQSL_Location; ///< Opaque location type typedef char * tQSL_StationDataEnc; ///< Opaque station data type /** Struct that holds y-m-d */ typedef struct { int year; ///< Numeric year int month; ///< Numeric month int day; ///< Numeric day } tQSL_Date; /** Struct that holds h-m-s */ typedef struct { int hour; ///< Time hour field int minute; ///< Time minute field int second; ///< Time seconds field } tQSL_Time; /** Certificate provider data */ typedef struct tqsl_provider_st { char organizationName[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider name char organizationalUnitName[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider unit char emailAddress[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider e-mail char url[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider URL } TQSL_PROVIDER; /** Certificate request data */ typedef struct tqsl_cert_req_st { ///< Cert request data char providerName[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider name char providerUnit[TQSL_NAME_ELEMENT_MAX+1]; ///< Provider unit char callSign[TQSL_CALLSIGN_MAX+1]; ///< Callsign char name[TQSL_CRQ_NAME_MAX+1]; ///< Name char address1[TQSL_CRQ_ADDR_MAX+1]; ///< Address 1 char address2[TQSL_CRQ_ADDR_MAX+1]; ///< Address 2 char city[TQSL_CRQ_CITY_MAX+1]; ///< City char state[TQSL_CRQ_STATE_MAX+1]; ///< State char postalCode[TQSL_CRQ_POSTAL_MAX+1]; ///< Postal Code char country[TQSL_CRQ_COUNTRY_MAX+1]; ///< Country char emailAddress[TQSL_CRQ_EMAIL_MAX+1]; ///< e-mail int dxccEntity; ///< DXCC Entity code tQSL_Date qsoNotBefore; ///< QSOs not before date tQSL_Date qsoNotAfter; ///< QSOs not after date char password[TQSL_PASSWORD_MAX+1]; ///< Password tQSL_Cert signer; ///< Signing cert char renew; ///< Rewewal reference } TQSL_CERT_REQ; /** QSO data */ typedef struct { char callsign[TQSL_CALLSIGN_MAX+1]; ///< QSO callsign char band[TQSL_BAND_MAX+1]; ///< QSO band char mode[TQSL_MODE_MAX+1]; ///< QSO mode tQSL_Date date; ///< QSO date tQSL_Time time; ///< QSO time char freq[TQSL_FREQ_MAX+1]; ///< QSO frequency char rxfreq[TQSL_FREQ_MAX+1]; ///< QSO receive frequency char rxband[TQSL_BAND_MAX+1]; ///< QSO RX band char propmode[TQSL_PROPMODE_MAX+1]; ///< QSO prop mode char satname[TQSL_SATNAME_MAX+1]; ///< QSO satellite name } TQSL_QSO_RECORD; /// Base directory for tQSL library working files. DLLEXPORTDATA extern const char *tQSL_BaseDir; #ifdef __cplusplus extern "C" { #endif /** \defgroup Util Utility API */ /** @{ */ /// Error code from most recent tQSL library call. /** * The values for the error code are defined in tqslerrno.h */ DLLEXPORTDATA extern int tQSL_Error; /// The ADIF error code DLLEXPORTDATA extern TQSL_ADIF_GET_FIELD_ERROR tQSL_ADIF_Error; /// The ADIF error code DLLEXPORTDATA extern TQSL_CABRILLO_ERROR_TYPE tQSL_Cabrillo_Error; /// File name of file giving error. (May be empty.) DLLEXPORTDATA extern char tQSL_ErrorFile[256]; /// Custom error message string DLLEXPORTDATA extern char tQSL_CustomError[256]; /// System errno - stored when tQSL_Error == TQSL_SYSTEM_ERROR DLLEXPORTDATA extern int tQSL_Errno; /// Callsign used in import - used for missing public key error DLLEXPORTDATA extern char tQSL_ImportCall[256]; /** Initialize the tQSL library * * This function should be called prior to calling any other library functions. */ DLLEXPORT int CALLCONVENTION tqsl_init(); /** Set the directory where the TQSL files are kept. * May be called either before of after tqsl_init(), but should be called * before calling any other functions in the library. * * Note that this is purely optional. The library will figure out an * approriate directory if tqsl_setDirectory isn't called. Unless there is * some particular need to set the directory explicitly, programs should * refrain from doing so. */ DLLEXPORT int CALLCONVENTION tqsl_setDirectory(const char *dir); /** Gets the error string for the current tQSL library error and resets the error status. * See tqsl_getErrorString_v(). */ DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString(); /** Gets the error string corresponding to the given error number. * The error string is available only until the next call to * tqsl_getErrorString_v or tqsl_getErrorString. */ DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString_v(int err); /** Encode a block of data into Base64 text. * * \li \c data = block of data to encode * \li \c datalen = length of \c data in bytes * \li \c output = pointer to output buffer * \li \c outputlen = size of output buffer in bytes */ DLLEXPORT int CALLCONVENTION tqsl_encodeBase64(const unsigned char *data, int datalen, char *output, int outputlen); /** Decode Base64 text into binary data. * * \li \c input = NUL-terminated text string of Base64-encoded data * \li \c data = pointer to output buffer * \li \c datalen = pointer to int containing the size of the output buffer in bytes * * Places the number of resulting data bytes into \c *datalen. */ DLLEXPORT int CALLCONVENTION tqsl_decodeBase64(const char *input, unsigned char *data, int *datalen); /** Initialize a tQSL_Date object from a date string. * * The date string must be YYYY-MM-DD or YYYYMMDD format. * * Returns 0 on success, nonzero on failure */ DLLEXPORT int CALLCONVENTION tqsl_initDate(tQSL_Date *date, const char *str); /** Initialize a tQSL_Time object from a time string. * * The time string must be HH[:]MM[[:]SS] format. * * Returns 0 on success, nonzero on failure */ DLLEXPORT int CALLCONVENTION tqsl_initTime(tQSL_Time *time, const char *str); /** Compare two tQSL_Date objects. * * Returns: * - -1 if \c a < \c b * * - 0 if \c a == \c b * * - 1 if \c a > \c b */ DLLEXPORT int CALLCONVENTION tqsl_compareDates(const tQSL_Date *a, const tQSL_Date *b); /** Calculate the number of days between two tQSL_Date objects. * * Returns a positive result if the first date is earlier, otherwise * negative. */ DLLEXPORT int CALLCONVENTION tqsl_subtractDates(const tQSL_Date *a, const tQSL_Date *b, int *diff); /** Converts a tQSL_Date object to a YYYY-MM-DD string. * * Returns a pointer to \c buf or NULL on error */ DLLEXPORT char* CALLCONVENTION tqsl_convertDateToText(const tQSL_Date *date, char *buf, int bufsiz); /** Test whether a tQSL_Date contains a valid date value * * Returns 1 if the date is valid */ DLLEXPORT int CALLCONVENTION tqsl_isDateValid(const tQSL_Date *d); /** Test whether a tQSL_Date is empty (contains all zeroes) * * Returns 1 if the date is null */ DLLEXPORT int CALLCONVENTION tqsl_isDateNull(const tQSL_Date *d); /** Test whether a tQSL_Time contains a valid time value * * Returns 1 if the time is valid */ DLLEXPORT int CALLCONVENTION tqsl_isTimeValid(const tQSL_Time *t); /** Converts a tQSL_Time object to a HH:MM:SSZ string. * * Returns a pointer to \c buf or NULL on error */ DLLEXPORT char* CALLCONVENTION tqsl_convertTimeToText(const tQSL_Time *time, char *buf, int bufsiz); /** Returns the library version. \c major and/or \c minor may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getVersion(int *major, int *minor); /** Returns the configuration-file version. \c major and/or \c minor may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion(int *major, int *minor); /** @} */ /** \defgroup CertStuff Certificate Handling API * * Certificates are managed by manipulating \c tQSL_Cert objects. A \c tQSL_Cert * contains: * * \li The identity of the organization that issued the certificate (the "issuer"). * \li The name and call sign of the amateur radio operator (ARO). * \li The DXCC entity number for which this certificate is valid. * \li The range of QSO dates for which this certificate can be used. * \li The resources needed to digitally sign and verify QSO records. * * The certificate management process consists of: * * \li Applying for a certificate. Certificate requests are produced via the * tqsl_createCertRequest() function, which produces a certificate-request * file to send to the issuer. * \li Importing the certificate file received from the issuer into the local * "certificate store," a directory managed by the tQSL library, via * tqsl_importTQSLFile(). * \li Selecting an appropriate certificate to use to sign a QSO record via * tqsl_selectCertificates(). */ /** @{ */ #define TQSL_SELECT_CERT_WITHKEYS 1 ///< Private keys only (no cert) #define TQSL_SELECT_CERT_EXPIRED 2 ///< Include expired certs #define TQSL_SELECT_CERT_SUPERCEDED 4 ///< Include superseded certs /** Get a list of certificates * * Selects a set of certificates from the user's certificate store * based on optional selection criteria. The function produces a * list of tQSL_Cert objects. * * \li \c certlist - Pointer to a variable that is set by the * function to point to the list of tQSL_Cert objects. * \li \c ncerts - Pointer to an int that is set to the number * of objects in the \c certlist list. * \li \c callsign - Optional call sign to match. * \li \c date - Optional QSO date string in ISO format. Only certs * that have a QSO date range that encompasses this date will be * returned. * \li \c issuer - Optional issuer (DN) string to match. * \li \c flag - OR of \c TQSL_SELECT_CERT_EXPIRED (include expired * certs), \c TQSL_SELECT_CERT_SUPERCEDED and \c TQSL_SELECT_CERT_WITHKEYS * (keys that don't have associated certs will be returned). * * Returns 0 on success, nonzero on failure. * * Each of the tQSL_Cert objects in the list should be freed * by calling tqsl_freeCertificate(). * */ DLLEXPORT int CALLCONVENTION tqsl_selectCertificates(tQSL_Cert **certlist, int *ncerts, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flag); /** Get a list of authority certificates * * Selects a set of certificates from the root or authorities certificate stores * The function produces a list of tQSL_Cert objects. * * Each of the tQSL_Cert objects in the list should be freed * by calling tqsl_freeCertificate(). * */ DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates(tQSL_Cert **certlist, int *ncerts, const char *type); /** Get a particulat certificate from the list returnded by * tqsl_selectCertificates. This function exists principally * to make it easier for VB programs to access the list of * certificates. * * It is the caller's responsibility to ensure that 0 <= idx < ncerts * (where ncerts is the value returned by tqsl_selectCertificates) */ DLLEXPORT int CALLCONVENTION tqsl_getSelectedCertificate(tQSL_Cert *cert, const tQSL_Cert **certlist, int idx); /** Find out if the "certificate" is expired */ DLLEXPORT int CALLCONVENTION tqsl_isCertificateExpired(tQSL_Cert cert, int *status); /** Find out if the "certificate" is superceded */ DLLEXPORT int CALLCONVENTION tqsl_isCertificateSuperceded(tQSL_Cert cert, int *status); /** Find out if the "certificate" is just a key pair. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateKeyOnly(tQSL_Cert cert, int *keyonly); /** Get the encoded certificate for inclusion in a GABBI file. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded(tQSL_Cert cert, char *buf, int bufsiz); /** Get the encoded private key for inclusion in a backup file. */ DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded(tQSL_Cert cert, char *buf, int bufsiz); /** Import a base64 encoded certificate and private key from a backup file. */ DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded(const char *callsign, const char *type, const char *keybuf, const char *certbuf); /** Get the issuer's serial number of the certificate. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerial(tQSL_Cert cert, long *serial); /** Get the issuer's serial number of the certificate as a hexadecimal string. * Needed for certs with long serial numbers (typically root certs). */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt(tQSL_Cert cert, char *serial, int serialsiz); /** Get the length of the issuer's serial number of the certificate as it will be * returned by tqsl_getCertificateSerialExt. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialLength(tQSL_Cert cert); /** Get the issuer (DN) string from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer(tQSL_Cert cert, char *buf, int bufsiz); /** Get the issuer's organization name from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganization(tQSL_Cert cert, char *buf, int bufsiz); /** Get the issuer's organizational unit name from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganizationalUnit(tQSL_Cert cert, char *buf, int bufsiz); /** Get the ARO call sign string from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign(tQSL_Cert cert, char *buf, int bufsiz); /** Get the ARO name string from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName(tQSL_Cert cert, char *buf, int bufsiz); /** Get the email address from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress(tQSL_Cert cert, char *buf, int bufsiz); /** Get the QSO not-before date from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c date - Pointer to a tQSL_Date struct to hold the returned date. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotBeforeDate(tQSL_Cert cert, tQSL_Date *date); /** Get the QSO not-after date from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c date - Pointer to a tQSL_Date struct to hold the returned date. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotAfterDate(tQSL_Cert cert, tQSL_Date *date); /** Get the certificate's not-before date from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c date - Pointer to a tQSL_Date struct to hold the returned date. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotBeforeDate(tQSL_Cert cert, tQSL_Date *date); /** Get the certificate's not-after date from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c date - Pointer to a tQSL_Date struct to hold the returned date. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotAfterDate(tQSL_Cert cert, tQSL_Date *date); /** Get the DXCC entity number from a tQSL_Cert. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c dxcc - Pointer to an int to hold the returned date. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateDXCCEntity(tQSL_Cert cert, int *dxcc); /** Get the first address line from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress1(tQSL_Cert cert, char *str, int bufsiz); /** Get the second address line from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress2(tQSL_Cert cert, char *str, int bufsiz); /** Get the city from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity(tQSL_Cert cert, char *str, int bufsiz); /** Get the state from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState(tQSL_Cert cert, char *str, int bufsiz); /** Get the postal (ZIP) code from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestPostalCode(tQSL_Cert cert, char *str, int bufsiz); /** Get the country from the certificate request used in applying * for a tQSL_Cert certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * \li \c buf - Buffer to hold the returned string. * \li \c bufsiz - Size of \c buf. * * Returns 0 on success, nonzero on failure. */ DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCountry(tQSL_Cert cert, char *str, int bufsiz); #define TQSL_PK_TYPE_ERR 0 ///< Error retrieving private key #define TQSL_PK_TYPE_NONE 1 ///< No private key #define TQSL_PK_TYPE_UNENC 2 ///< Private key is not encrypted #define TQSL_PK_TYPE_ENC 3 ///< Private key is encrypted /** Determine the nature of the private key associated with a * certificate. * * \li \c cert - a tQSL_Cert object, normally one returned from * tqsl_selectCertificates() * * Returns one of the following values: * * \li \c TQSL_PK_TYPE_ERR - An error occurred. Use tqsl_getErrorString() to examine. * \li \c TQSL_PK_TYPE_NONE - No matching private key was found. * \li \c TQSL_PK_TYPE_UNENC - The matching private key is unencrypted. * \li \c TQSL_PK_TYPE_ENC - The matching private key is encrypted * (password protected). */ DLLEXPORT int CALLCONVENTION tqsl_getCertificatePrivateKeyType(tQSL_Cert cert); /** Free the memory used by the tQSL_Cert. Once this function is called, * \c cert should not be used again in any way. */ DLLEXPORT void CALLCONVENTION tqsl_freeCertificate(tQSL_Cert cert); /* int tqsl_checkCertificate(tQSL_Cert); */ /** Import a Gabbi cert file received from a CA * * The callback, \c cb, will be called whenever a certificate is ready * to be imported: * * cb(type, message); * * \c type has several fields that can be accessed via macros: * * \c TQSL_CERT_CB_CALL_TYPE(type) := \c TQSL_CERT_CB_MILESTONE | \c TQSL_CERT_CB_RESULT * * \c TQSL_CERT_CB_CERT_TYPE(type) := \c TQSL_CERT_CB_ROOT | \c TQSL_CERT_CB_CA | \c TQSL_CERT_CB_USER * * \c TQSL_CERT_CB_RESULT_TYPE(type) := \c TQSL_CERT_CB_PROMPT | \c TQSL_CERT_CB_WARNING | \c TQSL_CERT_CB_ERROR * * \c TQSL_CERT_CB_RESULT_TYPE() is meaningful only if \c TQSL_CERT_CB_CALL_TYPE() == \c TQSL_CERT_CB_RESULT */ DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile(const char *file, int(*cb)(int type, const char *message, void *userdata), void *user); /** Get the serial for the first user cert from a .tq6 file * used to support asking the user to save their cert after import * \li \c file is the path to the file * \li \c serial is where the serial number is returned * * Returns 0 on success, nonzero on failure. * */ DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile(const char *file, long *serial); /** Get the number of certificate providers known to tqsllib. */ DLLEXPORT int CALLCONVENTION tqsl_getNumProviders(int *n); /** Get the information for a certificate provider. * * \li \c idx is the index, 0 <= idx < tqsl_getNumProviders() */ DLLEXPORT int CALLCONVENTION tqsl_getProvider(int idx, TQSL_PROVIDER *provider); /** Create a certificate-request Gabbi file. * * The \c req parameter must be properly populated with the required fields. * * If \c req->password is NULL and \c cb is not NULL, the callback will be * called to acquire the password. Otherwise \c req->password will be used as * the password. If the password is NULL or an empty string the generated * private key will be stored unencrypted. * * If req->signer is not zero and the signing certificate requires a password, * the password may be in req->signer_password, else signer_pwcb is called. */ DLLEXPORT int CALLCONVENTION tqsl_createCertRequest(const char *filename, TQSL_CERT_REQ *req, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user); /** Save a key pair and certificates to a file in PKCS12 format. * * The tQSL_Cert must be initialized for signing (see tqsl_beginSigning()) * if the user certificate is being exported. * * The supplied \c p12password is used to encrypt the PKCS12 data. */ DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File(tQSL_Cert cert, const char *filename, const char *p12password); /** Save a key pair and certificates to a Base64 string in PKCS12 format. * * The tQSL_Cert must be initialized for signing (see tqsl_beginSigning()) * if the user certificate is being exported. * * The supplied \c p12password is used to encrypt the PKCS12 data. */ DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64(tQSL_Cert cert, char *base64, int b64len, const char *p12password); /** Load certificates and a private key from a PKCS12 file. */ DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File(const char *filename, const char *p12password, const char *password, int (*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type , const char *message, void *userdata), void *user); /** Load certificates and a private key from a Base64 encoded PKCS12 string. */ DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64(const char *base64, const char *p12password, const char *password, int (*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type , const char *message, void *userdata), void *user); /** Delete a certificate and private key */ DLLEXPORT int CALLCONVENTION tqsl_deleteCertificate(tQSL_Cert cert); /** @} */ /** \defgroup Sign Signing API * * The Signing API uses a tQSL_Cert (see \ref CertStuff) to digitally * sign a block of data. */ /** @{ */ /** Initialize the tQSL_Cert object for use in signing. * * This produces an unencrypted copy of the private key in memory. * * if \c password is not NULL, it must point to the password to use to decrypt * the private key. If \c password is NULL and \c pwcb is not NULL, \c pwcb * is called to get the password. If the private key is encrypted and both * \c password and \c pwcb are NULL, or if the supplied password fails to * decrypt the key, a TQSL_PASSWORD_ERROR error is returned. * * \c pwcb parameters: \c pwbuf is a pointer to a buffer of \c pwsize chars. * The buffer should be NUL-terminated. */ DLLEXPORT int CALLCONVENTION tqsl_beginSigning(tQSL_Cert cert, char *password, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user); /** Test whether the tQSL_Cert object is initialized for signing. * * Returns 0 if initialized. Sets tQSL_Error to TQSL_SIGNINIT_ERROR if not. */ DLLEXPORT int CALLCONVENTION tqsl_checkSigningStatus(tQSL_Cert cert); /** Get the maximum size of a signature block that will be produced * when the tQSL_Cert is used to sign data. (Note that the size of the * signature block is unaffected by the size of the data block being signed.) */ DLLEXPORT int CALLCONVENTION tqsl_getMaxSignatureSize(tQSL_Cert cert, int *sigsize); /** Sign a data block. * * tqsl_beginSigning() must have been called for * the tQSL_Cert object before calling this function. */ DLLEXPORT int CALLCONVENTION tqsl_signDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int *siglen); /** Verify a signed data block. * * tqsl_beginSigning() need \em not have been called. */ DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int siglen); /** Sign a single QSO record * * tqsl_beginSigning() must have been called for * the tQSL_Cert object before calling this function. * * \c loc must be a valid tQSL_Location object. See \ref Data. */ DLLEXPORT int CALLCONVENTION tqsl_signQSORecord(tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *rec, unsigned char *sig, int *siglen); /** Terminate signing operations for this tQSL_Cert object. * * This zero-fills the unencrypted private key in memory. */ DLLEXPORT int CALLCONVENTION tqsl_endSigning(tQSL_Cert cert); /** @} */ /** \defgroup Data Data API * * The Data API is used to form data into TrustedQSL records. A TrustedQSL record * consists of a station record and a QSO record. Together, the two records * fully describe one station's end of the QSO -- just as a paper QSL card does. * * The station record contains the callsign and geographic location of the * station submitting the QSO record. The library manages the station records. * The tqsl_xxxStationLocationCapture functions are used to generate and save * a station record. The intent is to provide an interface that makes a step-by-step * system (such as a GUI "wizard") easily implemented. * * The tqsl_getStationLocation() function is used to retrieve station records. * * With the necessary station location available, a signed GABBI output file can * be generated using the tqsl_getGABBIxxxxx functions: * * \li tqsl_getGABBItCERT() - Returns a GABBI tCERT record for the given tQSL_Cert * \li tqsl_getGABBItSTATION() - Returns a GABBI tSTATION record for the given * tQSL_Location * \li tqsl_getGABBItCONTACT() - Returns a GABBI tCONTACT record for the given * TQSL_QSO_RECORD, using the given tQSL_Cert and tQSL_Location. * \li tqsl_getGABBItCONTACTData() - Returns a GABBI tCONTACT record and the * SIGNDATA for the given TQSL_QSO_RECORD, using the given tQSL_Cert and * tQSL_Location. * * The GABBI format requires that the tCERT record contain an integer identifier * that is unique within the GABBI file. Similarly, each tSTATION record must * contain a unique identifier. Aditionally, the tSTATION record must reference * the identifier of a preceding tCERT record. Finally, each tCONTACT record must * reference a preceding tSTATION record. (A GABBI processor uses these identifiers * and references to tie the station and contact records together and to verify * their signature via the certificate.) It is the responsibility of the caller * to supply these identifiers and to ensure that the supplied references match * the tQSL_Cert and tQSL_Location used to create the referenced GABBI records. * * Station Location Generation * * The station-location generation process involves determining the values * for a number of station-location parameters. Normally this * will be done by prompting the user for the values. The responses given * by the user may determine which later fields are required. For example, * if the user indicates that the DXCC entity is UNITED STATES, a later * field would ask for the US state. This field would not be required if the * DXCC entity were not in the US. * * To accommodate the dynamic nature of the field requirements, the fields * are ordered such that dependent fields are queried after the field(s) * on which they depend. To make this process acceptable in a GUI * system, the fields are grouped into pages, where multiple fields may * be displayed on the same page. The grouping is such that which fields * are within the page is not dependent on any of the values of the * fields within the page. That is, a page of fields contains the same * fields no matter what value any of the fields contains. (However, * the \em values of fields within the page can depend on the values * of fields that precede them in the page.) * * Here is a brief overview of the sequence of events involved in * generating a station location interactively, one field at a time: * * 1) Call tqsl_initStationLocationCapture() (new location) or tqsl_getStationLocation() * (existing location). * * 2) For \c field from 0 to tqsl_getNumLocationField(): * \li Display the field label [tqsl_getLocationFieldDataLabel()] * \li Get the field content from the user. This can be a selection * from a list, an entered integer or an entered character string, * depending on the value returned by tqsl_getLocationFieldInputType(). * * 3) If tqsl_hasNextStationLocationCapture() returns 1, call * tqsl_nextStationLocationCapture() and go back to step 2. * * In the case of a GUI system, you'll probably want to display the * fields in pages. The sequence of events is a bit different: * * 1) Call tqsl_initStationLocationCapture() (new location) or tqsl_getStationLocation() * (existing location). * * 2) For \c field from 0 to tqsl_getNumLocationField(), * \li Display the field label [tqsl_getLocationFieldDataLabel()] * \li Display the field-input control This can be a list-selection * or an entered character string or integer, depending on the value * returned by tqsl_getLocationFieldInputType(). * * 3) Each time the user changes a field, call tqsl_updateStationLocationCapture(). * This may change the allowable selection for fields that follow the field * the user changed, so the control for each of those fields should be updated * as in step 2. * * 4) Once the user has completed entries for the page, if * tqsl_hasNextStationLocationCapture() returns 1, call * tqsl_nextStationLocationCapture() and go back to step 2. * * N.B. The first two fields in the station-location capture process are * always call sign and DXCC entity, in that order. As a practical matter, these * two fields must match the corresponding fields in the available certificates. * The library will therefore constrain the values of these fields to match * what's available in the certificate store. See \ref CertStuff. */ /** @{ */ /* Location field input types */ #define TQSL_LOCATION_FIELD_TEXT 1 ///< Text type input field #define TQSL_LOCATION_FIELD_DDLIST 2 ///< Dropdown list input field #define TQSL_LOCATION_FIELD_LIST 3 ///< List type input field #define TQSL_LOCATION_FIELD_BADZONE 4 ///< Used to return zone selection errors /* Location field data types */ #define TQSL_LOCATION_FIELD_CHAR 1 ///< Character field #define TQSL_LOCATION_FIELD_INT 2 ///< Integer field /** Begin the process of generating a station record */ DLLEXPORT int CALLCONVENTION tqsl_initStationLocationCapture(tQSL_Location *locp); /** Release the station-location resources. This should be called for * any tQSL_Location that was initialized via tqsl_initStationLocationCapture() * or tqsl_getStationLocation() */ DLLEXPORT int CALLCONVENTION tqsl_endStationLocationCapture(tQSL_Location *locp); /** Update the pages based on the currently selected settings. */ DLLEXPORT int CALLCONVENTION tqsl_updateStationLocationCapture(tQSL_Location loc); /** Return the number of station location capture pages. */ DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocationCapturePages(tQSL_Location loc, int *npages); /** Get the current page number */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCapturePage(tQSL_Location loc, int *page); /** Set the current page number. * Typically, the page number will be 1 (the starting page) or a value * obtained from tqsl_getStationLocationCapturePage(). */ DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCapturePage(tQSL_Location loc, int page); /** Set the certificate flags used in a location page. * This is used to enable expired certs (or disable). */ DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCertFlags(tQSL_Location loc, int flags); /** Advance the page to the next one in the page sequence */ DLLEXPORT int CALLCONVENTION tqsl_nextStationLocationCapture(tQSL_Location loc); /** Return the page to the previous one in the page sequence. */ DLLEXPORT int CALLCONVENTION tqsl_prevStationLocationCapture(tQSL_Location loc); /** Returns 1 (in rval) if there is a next page */ DLLEXPORT int CALLCONVENTION tqsl_hasNextStationLocationCapture(tQSL_Location loc, int *rval); /** Returns 1 (in rval) if there is a previous page */ DLLEXPORT int CALLCONVENTION tqsl_hasPrevStationLocationCapture(tQSL_Location loc, int *rval); /** Save the station location data. Note that the name must have been * set via tqsl_setStationLocationCaptureName if this is a new * station location. If the \c overwrite parameter is zero and a * station location of that name is already in existance, an error * occurs with tQSL_Error set to TQSL_NAME_EXISTS. */ DLLEXPORT int CALLCONVENTION tqsl_saveStationLocationCapture(tQSL_Location loc, int overwrite); /** Get the name of the station location */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCaptureName(tQSL_Location loc, char *namebuf, int bufsiz); /** Set the name of the station location */ DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCaptureName(tQSL_Location loc, const char *name); /** Get the number of saved station locations */ DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocations(tQSL_Location loc, int *nloc); /** Get the name of the specified (by \c idx) saved station location */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName(tQSL_Location loc, int idx, char *buf, int bufsiz); /** Get the call sign from the station location */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign(tQSL_Location loc, int idx, char *buf, int bufsiz); /** Get a named field from the station location */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField(tQSL_Location locp, const char *name, char *namebuf, int bufsize); /** Retrieve a saved station location. * Once finished wih the station location, tqsl_endStationLocationCapture() * should be called to release resources. */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocation(tQSL_Location *loc, const char *name); /** Get any errors returned from parsing the selected station location. * This should be called after tqsl_getStationLocation to determine if * any of the existing fields failed validation. Currently only zone * data is validated here, but future validations for things like * properly formatted grid squares is likely. */ DLLEXPORT int CALLCONVENTION tqsl_getStationLocationErrors(tQSL_Location loc, char *buf, int bufsiz); /** Return the contents of the station data file as a byte stream. * The caller is required to tqsl_freeStationDataEnc() this pointer when done with it. */ DLLEXPORT int CALLCONVENTION tqsl_getStationDataEnc(tQSL_StationDataEnc *sdata); /** Free the pointer returned by tqsl_getStationDataEnc(tQSL_StationDataEnc*) */ DLLEXPORT int CALLCONVENTION tqsl_freeStationDataEnc(tQSL_StationDataEnc sdata); /** Merge saved location data with existing */ DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations(const char *locdata); /** Remove the stored station location by name. */ DLLEXPORT int CALLCONVENTION tqsl_deleteStationLocation(const char *name); /** Get the number of fields on the current station location page */ DLLEXPORT int CALLCONVENTION tqsl_getNumLocationField(tQSL_Location loc, int *numf); /** Get the number of characters in the label for the specified field */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabelSize(tQSL_Location loc, int field_num, int *rval); /** Get the label for the specified field */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel(tQSL_Location loc, int field_num, char *buf, int bufsiz); /** Get the size of the GABBI name of the specified field */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBISize(tQSL_Location loc, int field_num, int *rval); /** Get the GABBI name of the specified field */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI(tQSL_Location loc, int field_num, char *buf, int bufsiz); /** Get the input type of the input field. * * \c type will be one of TQSL_LOCATION_FIELD_TEXT, TQSL_LOCATION_FIELD_DDLIST * or TQSL_LOCATION_FIELD_LIST */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType(tQSL_Location loc, int field_num, int *type); /** Get the data type of the input field. * * \c type will be either TQSL_LOCATION_FIELD_CHAR or TQSL_LOCATION_FIELD_INT */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType(tQSL_Location loc, int field_num, int *type); /** Get the flags for the input field. * * \c flags will be either * TQSL_LOCATION_FIELD_UPPER Field is to be uppercased on input * TQSL_LOCATION_FIELD_MUSTSEL Value must be selected * TQSL_LOCATION_FIELD_SELNXT Value must be selected to allow Next/Finish * */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags(tQSL_Location loc, int field_num, int *flags); /** Get the length of the input field data. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength(tQSL_Location loc, int field_num, int *rval); /** Get the character data from the specified field. * * If the field input type (see tqsl_getLocationFieldInputType()) is * TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, this will * return the text of the selected item. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData(tQSL_Location loc, int field_num, char *buf, int bufsiz); /** Get the integer data from the specified field. * * This is only meaningful if the field data type (see tqsl_getLocationFieldDataType()) * is TQSL_LOCATION_FIELD_INT. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData(tQSL_Location loc, int field_num, int *dat); /** If the field input type (see tqsl_getLocationFieldInputType()) is * TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, gets the * index of the selected list item. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex(tQSL_Location loc, int field_num, int *dat); /** Get the number of items in the specified field's pick list. */ DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems(tQSL_Location loc, int field_num, int *rval); /** Get the text of a specified item of a specified field */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem(tQSL_Location loc, int field_num, int item_idx, char *buf, int bufsiz); /** Set the text data of a specified field. */ DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData(tQSL_Location loc, int field_num, const char *buf); /** Set the integer data of a specified field. */ DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData(tQSL_Location loc, int field_num, int dat); /** If the field input type (see tqsl_getLocationFieldInputType()) is * TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, sets the * index of the selected list item. */ DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex(tQSL_Location loc, int field_num, int dat); /** Get the \e changed status of a field. The changed flag is set to 1 if the * field's pick list was changed during the last call to tqsl_updateStationLocationCapture * or zero if the list was not changed. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged(tQSL_Location loc, int field_num, int *changed); /** Get the call sign from the station location. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign(tQSL_Location loc, char *buf, int bufsiz); /** Get the DXCC entity from the station location. */ DLLEXPORT int CALLCONVENTION tqsl_getLocationDXCCEntity(tQSL_Location loc, int *dxcc); /** Get the number of DXCC entities in the master DXCC list. */ DLLEXPORT int CALLCONVENTION tqsl_getNumDXCCEntity(int *number); /** Get a DXCC entity from the list of DXCC entities by its index. */ DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity(int index, int *number, const char **name); /** Get the name of a DXCC Entity by its DXCC number. */ DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName(int number, const char **name); /** Get the zonemap of a DXCC Entity by its DXCC number. */ DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap(int number, const char **zonemap); /** Get the number of Band entries in the Band list */ DLLEXPORT int CALLCONVENTION tqsl_getNumBand(int *number); /** Get a band by its index. * * \c name - The GAABI name of the band. * \c spectrum - HF | VHF | UHF * \c low - The low end of the band in kHz (HF) or MHz (VHF/UHF) * \c high - The low high of the band in kHz (HF) or MHz (VHF/UHF) * * Note: \c spectrum, \c low and/or \c high may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getBand(int index, const char **name, const char **spectrum, int *low, int *high); /** Get the number of Mode entries in the Mode list */ DLLEXPORT int CALLCONVENTION tqsl_getNumMode(int *number); /** Get a mode by its index. * * \c mode - The GAABI mode name * \c group - CW | PHONE | IMAGE | DATA * * Note: \c group may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getMode(int index, const char **mode, const char **group); /** Get the number of Propagation Mode entries in the Propagation Mode list */ DLLEXPORT int CALLCONVENTION tqsl_getNumPropagationMode(int *number); /** Get a propagation mode by its index. * * \c name - The GAABI propagation mode name * \c descrip - Text description of the propagation mode * * Note: \c descrip may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode(int index, const char **name, const char **descrip); /** Get the number of Satellite entries in the Satellite list */ DLLEXPORT int CALLCONVENTION tqsl_getNumSatellite(int *number); /** Get a satellite by its index. * * \c name - The GAABI satellite name * \c descrip - Text description of the satellite * \c start - The date the satellite entered service * \c end - The last date the satellite was in service * * Note: \c descrip, start and/or end may be NULL. */ DLLEXPORT int CALLCONVENTION tqsl_getSatellite(int index, const char **name, const char **descrip, tQSL_Date *start, tQSL_Date *end); /** Clear the map of Cabrillo contests. */ DLLEXPORT int CALLCONVENTION tqsl_clearCabrilloMap(); /** Set the mapping of a Cabrillo contest name (as found in the * CONTEST line of a Cabrillo file) to the QSO line call-worked field number * and the contest type. * * \c field can have a value of TQSL_MIN_CABRILLO_MAP_FIELD (cabrillo.h) * or greater. Field number starts at 1. * * \c contest_type must be TQSL_CABRILLO_HF or TQSL_CABRILLO_VHF, * defined in cabrillo.h */ DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry(const char *contest, int field, int contest_type); /** Get the mapping of a Cabrillo contest name (as found in the * CONTEST line of a Cabrillo file) to a call-worked field number * and the contest type. * * \c fieldnum will be set to 0 if the contest name isn't in the Cabrillo * map. Otherwise it is set to the QSO line field number of the call-worked * field, with field counting starting at 1. * * \c contest_type may be NULL. If not, it is set to the Cabrillo contest * type (TQSL_CABRILLO_HF or TQSL_CABRILLO_VHF), defined in cabrillo.h. */ DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry(const char *contest, int *fieldnum, int *contest_type); /** Clear the map of ADIF modes */ DLLEXPORT int CALLCONVENTION tqsl_clearADIFModes(); /** Set the mapping of an ADIF mode to a TQSL mode. */ DLLEXPORT int CALLCONVENTION tqsl_setADIFMode(const char *adif_item, const char *mode); /** Map an ADIF mode to its TQSL equivalent. */ DLLEXPORT int CALLCONVENTION tqsl_getADIFMode(const char *adif_item, char *mode, int nmode); /** Get a GABBI record that contains the certificate. * * \c uid is the value for the CERT_UID field * * Returns the NULL pointer on error. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the GABBI records should be written in binary mode. */ DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCERT(tQSL_Cert cert, int uid); /** Get a GABBI record that contains the Staion Location data. * * \li \c uid is the value for the STATION_UID field. * \li \c certuid is the value of the asociated CERT_UID field. * * Returns the NULL pointer on error. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the GABBI records should be written in binary mode. */ DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItSTATION(tQSL_Location loc, int uid, int certuid); /** Get a GABBI record that contains the QSO data. * * \li \c stationuid is the value of the associated STATION_UID field. * * N.B.: If \c cert is not initialized for signing (see tqsl_beginSigning()) * the function will return with a TQSL_SIGNINIT_ERROR error. * * Returns the NULL pointer on error. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the GABBI records should be written in binary mode. */ DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACT(tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid); /** Get a GABBI record that contains the QSO data along with the associated * signdata (QSO data signed to validate the QSO). * * \li \c stationuid is the value of the associated STATION_UID field. * * N.B.: If \c cert is not initialized for signing (see tqsl_beginSigning()) * the function will return with a TQSL_SIGNINIT_ERROR error. * * Returns the NULL pointer on error. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the GABBI records should be written in binary mode. */ DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACTData(tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid, char *signdata, int sdlen); /** @} */ #ifdef __cplusplus } #endif /* Useful defines */ #define TQSL_MAX_PW_LENGTH 32 ///< Password buffer length #endif /* TQSLLIB_H */ tqsl-2.0/src/tqsllib.css0000664000076400007640000000211612231073120015310 0ustar rmurphyrmurphyBODY { font-family: Helvetica,Arial,sans-serif; font-size: small } H1 { text-align: center; font-size: x-large } H2 { font-size: large } CODE { font-size: medium } A.qindex {} A.qindexRef {} A.el { text-decoration: none; font-weight: bold; } A.elRef { font-weight: bold } A.code { text-decoration: none; font-weight: normal; color: #4444ee } A.codeRef { font-weight: normal; color: #4444ee } A:link { color: #0000ff } A:visited { color: #0066cc } DL.el { margin-left: -1cm } DIV.fragment { width: 100%; border: none; background-color: #eeeeee } DIV.ah { background-color: black; margin-bottom: 3; margin-top: 3 } TD.md { background-color: #f2f2ff } DIV.groupHeader { margin-left: 16; margin-top: 12; margin-bottom: 6; font-weight: bold } DIV.groupText { margin-left: 16; font-style: italic; font-size: smaller } FONT.keyword { color: #008000 } FONT.keywordtype { color: #604020 } FONT.keywordflow { color: #e08000 } FONT.comment { color: #800000 } FONT.preprocessor { color: #806020 } FONT.stringliteral { color: #002080 } FONT.charliteral { color: #008080 } TD { font-size: small } tqsl-2.0/src/tqsllib.cpp0000664000076400007640000004664112231073120015315 0ustar rmurphyrmurphy/*************************************************************************** tqsllib.c - description ------------------- begin : Mon May 20 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #define TQSLLIB_DEF //#include "sysconfig.h" //KC2YWE: Removed provisionally #include "tqsllib.h" #include "tqslerrno.h" #include "adif.h" #include "winstrdefs.h" #include #include #include #include #include #ifdef _WIN32 #include #include #include #endif #include #include #include #ifdef _WIN32 #define MKDIR(x,y) _mkdir(x) #else #define MKDIR(x,y) mkdir(x,y) #endif DLLEXPORTDATA int tQSL_Error = 0; DLLEXPORTDATA int tQSL_Errno = 0; DLLEXPORTDATA TQSL_ADIF_GET_FIELD_ERROR tQSL_ADIF_Error; DLLEXPORTDATA const char *tQSL_BaseDir = 0; DLLEXPORTDATA char tQSL_ErrorFile[256]; DLLEXPORTDATA char tQSL_CustomError[256]; DLLEXPORTDATA char tQSL_ImportCall[256]; #define TQSL_OID_BASE "1.3.6.1.4.1.12348.1." #define TQSL_OID_CALLSIGN TQSL_OID_BASE "1" #define TQSL_OID_QSO_NOT_BEFORE TQSL_OID_BASE "2" #define TQSL_OID_QSO_NOT_AFTER TQSL_OID_BASE "3" #define TQSL_OID_DXCC_ENTITY TQSL_OID_BASE "4" #define TQSL_OID_SUPERCEDED_CERT TQSL_OID_BASE "5" #define TQSL_OID_CRQ_ISSUER_ORGANIZATION TQSL_OID_BASE "6" #define TQSL_OID_CRQ_ISSUER_ORGANIZATIONAL_UNIT TQSL_OID_BASE "7" #define TQSL_OID_CRQ_EMAIL TQSL_OID_BASE "8" #define TQSL_OID_CRQ_ADDRESS1 TQSL_OID_BASE "9" #define TQSL_OID_CRQ_ADDRESS2 TQSL_OID_BASE "10" #define TQSL_OID_CRQ_CITY TQSL_OID_BASE "11" #define TQSL_OID_CRQ_STATE TQSL_OID_BASE "12" #define TQSL_OID_CRQ_POSTAL TQSL_OID_BASE "13" #define TQSL_OID_CRQ_COUNTRY TQSL_OID_BASE "14" static const char *custom_objects[][3] = { { TQSL_OID_CALLSIGN, "AROcallsign", NULL }, { TQSL_OID_QSO_NOT_BEFORE, "QSONotBeforeDate", NULL }, { TQSL_OID_QSO_NOT_AFTER, "QSONotAfterDate", NULL }, { TQSL_OID_DXCC_ENTITY, "dxccEntity", NULL }, { TQSL_OID_SUPERCEDED_CERT, "supercededCertificate", NULL }, { TQSL_OID_CRQ_ISSUER_ORGANIZATION, "tqslCRQIssuerOrganization", NULL }, { TQSL_OID_CRQ_ISSUER_ORGANIZATIONAL_UNIT, "tqslCRQIssuerOrganizationalUnit", NULL }, { TQSL_OID_CRQ_EMAIL, "tqslCRQEmail", NULL }, { TQSL_OID_CRQ_ADDRESS1, "tqslCRQAddress1", NULL }, { TQSL_OID_CRQ_ADDRESS2, "tqslCRQAddress2", NULL }, { TQSL_OID_CRQ_CITY, "tqslCRQCity", NULL }, { TQSL_OID_CRQ_STATE, "tqslCRQState", NULL }, { TQSL_OID_CRQ_POSTAL, "tqslCRQPostal", NULL }, { TQSL_OID_CRQ_COUNTRY, "tqslCRQCountry", NULL }, }; static const char *error_strings[] = { "Memory allocation failure", /* TQSL_ALLOC_ERROR */ "Unable to initialize random number generator", /* TQSL_RANDOM_ERROR */ "Invalid argument", /* TQSL_ARGUMENT_ERROR */ "Operator aborted operation", /* TQSL_OPERATOR_ABORT */ "No Certificate Request matches the selected Callsign Certificate",/* TQSL_NOKEY_ERROR */ "Buffer too small", /* TQSL_BUFFER_ERROR */ "Invalid date format", /* TQSL_INVALID_DATE */ "Certificate not initialized for signing", /* TQSL_SIGNINIT_ERROR */ "Password not correct", /* TQSL_PASSWORD_ERROR */ "Expected name", /* TQSL_EXPECTED_NAME */ "Name exists", /* TQSL_NAME_EXISTS */ "Data for this DXCC entity could not be found", /* TQSL_NAME_NOT_FOUND */ "Invalid time format", /* TQSL_INVALID_TIME */ "QSO date is not within the date range specified on your Callsign Certificate", /* TQSL_CERT_DATE_MISMATCH */ "Certificate provider not found", /* TQSL_PROVIDER_NOT_FOUND */ "No callsign certificate for key", /* TQSL_CERT_KEY_ONLY */ "Configuration file cannot be opened", /* TQSL_CONFIG_ERROR */ "Callsign Certificate or Certificate Request not found",/* TQSL_CERT_NOT_FOUND */ "PKCS#12 file not TQSL compatible", /* TQSL_PKCS12_ERROR */ "Callsign Certificate not TQSL compatible", /* TQSL_CERT_TYPE_ERROR */ "Date out of range", /* TQSL_DATE_OUT_OF_RANGE */ "Duplicate QSO suppressed", /* TQSL_DUPLICATE_QSO */ "Database error", /* TQSL_DB_ERROR */ "The selected station location could not be found", /* TQSL_LOCATION_NOT_FOUND */ "The selected callsign could not be found", /* TQSL_CALL_NOT_FOUND */ "The TQSL configuration file cannot be parsed", /* TQSL_CONFIG_SYNTAX_ERROR */ "This file can not be processed due to a system error", /* TQSL_FILE_SYSTEM_ERROR */ "The format of this file is incorrect.", /* TQSL_FILE_SYNTAX_ERROR */ }; static int pmkdir(const char *path, int perm) { char dpath[TQSL_MAX_PATH_LEN]; char npath[TQSL_MAX_PATH_LEN]; char *cp; strncpy(dpath, path, sizeof dpath); cp = strtok(dpath, "/\\"); npath[0] = 0; while (cp) { if (strlen(cp) > 0 && cp[strlen(cp)-1] != ':') { #ifdef _WIN32 strcat(npath, "\\"); #else strcat(npath, "/"); #endif strcat(npath, cp); if (MKDIR(npath, perm) != 0 && errno != EEXIST) return 1; } else strcat(npath, cp); cp = strtok(NULL, "/\\"); } return 0; } DLLEXPORT int CALLCONVENTION tqsl_init() { static char semaphore = 0; unsigned int i; static char path[TQSL_MAX_PATH_LEN]; #ifdef _WIN32 //lets cin/out/err work in windows //AllocConsole(); //freopen("CONIN$", "r", stdin); //freopen("CONOUT$", "w", stdout); //freopen("CONOUT$", "w", stderr); static char shortPath[TQSL_MAX_PATH_LEN]; HKEY hkey; DWORD dtype; DWORD bsize = sizeof path; int wval; #endif /* OpenSSL API tends to change between minor version numbers, so make sure * we're using the right version */ long SSLver = SSLeay(); int SSLmajor = (SSLver >> 28) & 0xff; int SSLminor = (SSLver >> 20) & 0xff; int TQSLmajor = (OPENSSL_VERSION_NUMBER >> 28) & 0xff; int TQSLminor = (OPENSSL_VERSION_NUMBER >> 20) & 0xff; if (SSLmajor != TQSLmajor || (SSLminor != TQSLminor && (SSLmajor != 9 && SSLminor != 7 && TQSLminor == 6))) { tQSL_Error = TQSL_OPENSSL_VERSION_ERROR; return 1; } ERR_clear_error(); tqsl_getErrorString(); /* Clear the error status */ if (semaphore) return 0; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); for (i = 0; i < (sizeof custom_objects / sizeof custom_objects[0]); i++) { if (OBJ_create(custom_objects[i][0], custom_objects[i][1], custom_objects[i][2]) == 0) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } } if (tQSL_BaseDir == NULL) { char *cp; if ((cp = getenv("TQSLDIR")) != NULL && *cp != '\0') strncpy(path, cp, sizeof path); else { #if defined(_WIN32) if ((wval = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hkey)) == ERROR_SUCCESS) { wval = RegQueryValueEx(hkey, "AppData", 0, &dtype, (LPBYTE)path, &bsize); RegCloseKey(hkey); } if (wval != ERROR_SUCCESS) strcpy(path, "C:"); wval = GetShortPathName(path, shortPath, TQSL_MAX_PATH_LEN); if (wval != 0) strncpy(path, shortPath, TQSL_MAX_PATH_LEN); strncat(path, "\\TrustedQSL", sizeof path - strlen(path) - 1); #elif defined(LOTW_SERVER) strcpy(path, "/var/lotw/tqsl"); #else //some unix flavor if (getenv("HOME") != NULL) { strncpy(path, getenv("HOME"), sizeof path); strncat(path, "/", sizeof path - strlen(path)-1); strncat(path, ".tqsl", sizeof path - strlen(path)-1); } else strcpy(path, ".tqsl"); #endif } if (pmkdir(path, 0700)) { strncpy(tQSL_ErrorFile, path, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return 1; } tQSL_BaseDir = path; } semaphore = 1; return 0; } DLLEXPORT int CALLCONVENTION tqsl_setDirectory(const char *dir) { static char path[TQSL_MAX_PATH_LEN]; if (strlen(dir) >= TQSL_MAX_PATH_LEN) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(path, dir); tQSL_BaseDir = path; return 0; } DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString_v(int err) { static char buf[256]; unsigned long openssl_err; int adjusted_err; if (err == 0) return "NO ERROR"; if (err == TQSL_CUSTOM_ERROR) { if (tQSL_CustomError[0] == 0) return "Unknown custom error"; else { strncpy(buf, tQSL_CustomError, sizeof buf); return buf; } } if (err == TQSL_DB_ERROR && tQSL_CustomError[0] != 0) { snprintf(buf, sizeof buf, "Database Error: %s", tQSL_CustomError); return buf; } if (err == TQSL_SYSTEM_ERROR || err == TQSL_FILE_SYSTEM_ERROR) { strcpy(buf, "System error: "); if (strlen(tQSL_ErrorFile) > 0) { strncat(buf, tQSL_ErrorFile, sizeof buf - strlen(buf)-1); strncat(buf, ": ", sizeof buf - strlen(buf)-1); } strncat(buf, strerror(tQSL_Errno), sizeof buf - strlen(buf)-1); return buf; } if (err == TQSL_FILE_SYNTAX_ERROR) { strcpy(buf, "File syntax error: "); if (strlen(tQSL_ErrorFile) > 0) { strncat(buf, tQSL_ErrorFile, sizeof buf - strlen(buf)-1); strncat(buf, ": ", sizeof buf - strlen(buf)-1); } return buf; } if (err == TQSL_OPENSSL_ERROR) { openssl_err = ERR_get_error(); strcpy(buf, "OpenSSL error: "); if (openssl_err) ERR_error_string_n(openssl_err, buf + strlen(buf), sizeof buf - strlen(buf)-1); else strncat(buf, "[error code not available]", sizeof buf - strlen(buf)-1); return buf; } if (err == TQSL_ADIF_ERROR) { buf[0] = 0; if (strlen(tQSL_ErrorFile) > 0) { strncpy(buf, tQSL_ErrorFile, sizeof buf); strncat(buf, ": ", sizeof buf - strlen(buf)-1); } strncat(buf, tqsl_adifGetError(tQSL_ADIF_Error), sizeof buf - strlen(buf)-1); return buf; } if (err == TQSL_CABRILLO_ERROR) { buf[0] = 0; if (strlen(tQSL_ErrorFile) > 0) { strncpy(buf, tQSL_ErrorFile, sizeof buf); strncat(buf, ": ", sizeof buf - strlen(buf)-1); } strncat(buf, tqsl_cabrilloGetError(tQSL_Cabrillo_Error), sizeof buf - strlen(buf)-1); return buf; } if (err == TQSL_OPENSSL_VERSION_ERROR) { snprintf(buf, sizeof buf, "Incompatible OpenSSL Library version %d.%d.%d; expected %d.%d.%d", int(SSLeay() >> 28) & 0xff, int(SSLeay() >> 20) & 0xff, int(SSLeay() >> 12) & 0xff, int(OPENSSL_VERSION_NUMBER >> 28) & 0xff, int(OPENSSL_VERSION_NUMBER >> 20) & 0xff, int(OPENSSL_VERSION_NUMBER >> 12) & 0xff); return buf; } if (err == TQSL_CERT_NOT_FOUND && tQSL_ImportCall[0] != '\0') { snprintf(buf, sizeof buf, "Callsign Certificate or Certificate Request not found for callsign %s", tQSL_ImportCall); return buf; } adjusted_err = err - TQSL_ERROR_ENUM_BASE; if (adjusted_err < 0 || adjusted_err >= (int)(sizeof error_strings / sizeof error_strings[0])) { snprintf(buf, sizeof buf, "Invalid error code: %d", err); return buf; } return error_strings[adjusted_err]; } DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString() { const char *cp; cp = tqsl_getErrorString_v(tQSL_Error); tQSL_Error = TQSL_NO_ERROR; tQSL_Errno = 0; tQSL_ErrorFile[0] = 0; tQSL_CustomError[0] = 0; return cp; } DLLEXPORT int CALLCONVENTION tqsl_encodeBase64(const unsigned char *data, int datalen, char *output, int outputlen) { BIO *bio = NULL, *bio64 = NULL; int n; char *memp; int rval = 1; if (data == NULL || output == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return rval; } if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err; if ((bio64 = BIO_new(BIO_f_base64())) == NULL) goto err; bio = BIO_push(bio64, bio); if (BIO_write(bio, data, datalen) < 1) goto err; if (BIO_flush(bio) != 1) goto err;; n = BIO_get_mem_data(bio, &memp); if (n > outputlen-1) { tQSL_Error = TQSL_BUFFER_ERROR; goto end; } memcpy(output, memp, n); output[n] = 0; BIO_free_all(bio); bio = NULL; rval = 0; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: if (bio != NULL) BIO_free_all(bio); return rval; } DLLEXPORT int CALLCONVENTION tqsl_decodeBase64(const char *input, unsigned char *data, int *datalen) { BIO *bio = NULL, *bio64 = NULL; int n; int rval = 1; if (input == NULL || data == NULL || datalen == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return rval; } if ((bio = BIO_new_mem_buf((void *)input, strlen(input))) == NULL) goto err; BIO_set_mem_eof_return(bio, 0); if ((bio64 = BIO_new(BIO_f_base64())) == NULL) goto err; bio = BIO_push(bio64, bio); n = BIO_read(bio, data, *datalen); if (n < 0) goto err; if (BIO_ctrl_pending(bio) != 0) { tQSL_Error = TQSL_BUFFER_ERROR; goto end; } *datalen = n; rval = 0; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: if (bio != NULL) BIO_free_all(bio); return rval; } /* Convert a tQSL_Date field to an ISO-format date string */ DLLEXPORT char* CALLCONVENTION tqsl_convertDateToText(const tQSL_Date *date, char *buf, int bufsiz) { char lbuf[10]; int len; char *cp = buf; int bufleft = bufsiz-1; if (date == NULL || buf == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; if (buf) buf[0] = '\0'; return NULL; } if (date->year < 1 || date->year > 9999 || date->month < 1 || date->month > 12 || date->day < 1 || date->day > 31) { buf[0] = '\0'; return NULL; } len = snprintf(lbuf, sizeof lbuf, "%04d-", date->year); strncpy(cp, lbuf, bufleft); cp += len; bufleft -= len; len = snprintf(lbuf, sizeof lbuf, "%02d-", date->month); if (bufleft > 0) strncpy(cp, lbuf, bufleft); cp += len; bufleft -= len; len = snprintf(lbuf, sizeof lbuf, "%02d", date->day); if (bufleft > 0) strncpy(cp, lbuf, bufleft); bufleft -= len; if (bufleft < 0) return NULL; buf[bufsiz-1] = '\0'; return buf; } DLLEXPORT int CALLCONVENTION tqsl_isDateValid(const tQSL_Date *d) { static int mon_days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (d == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } if (d->year < 1 || d->year > 9999) return 0; if (d->month < 1 || d->month > 12) return 0; if (d->day < 1 || d->day > 31) return 0; mon_days[2] = ((d->year % 4) == 0 && ((d->year % 100) != 0 || (d->year % 400) == 0)) ? 29 : 28; if (d->day > mon_days[d->month]) return 0; return 1; } DLLEXPORT int CALLCONVENTION tqsl_isDateNull(const tQSL_Date *d) { if (d == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } return (d->year == 0 && d->month == 0 && d->day == 0) ? 1 : 0; } /* Convert a tQSL_Time field to an ISO-format date string */ DLLEXPORT char* CALLCONVENTION tqsl_convertTimeToText(const tQSL_Time *time, char *buf, int bufsiz) { char lbuf[10]; int len; char *cp = buf; int bufleft = bufsiz-1; if (time == NULL || time == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return NULL; } if (!tqsl_isTimeValid(time)) return NULL; len = snprintf(lbuf, sizeof lbuf, "%02d:", time->hour); strncpy(cp, lbuf, bufleft); cp += len; bufleft -= len; len = snprintf(lbuf, sizeof lbuf, "%02d:", time->minute); if (bufleft > 0) strncpy(cp, lbuf, bufleft); cp += len; bufleft -= len; len = snprintf(lbuf, sizeof lbuf, "%02d", time->second); if (bufleft > 0) strncpy(cp, lbuf, bufleft); cp += len; bufleft -= len; if (bufleft > 0) strcpy(cp, "Z"); bufleft -= 1; if (bufleft < 0) return NULL; buf[bufsiz-1] = '\0'; return buf; } DLLEXPORT int CALLCONVENTION tqsl_isTimeValid(const tQSL_Time *t) { if (t == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } if (t->hour < 0 || t->hour > 23) return 0; if (t->minute < 0 || t->minute > 59) return 0; if (t->second < 0 || t->second > 59) return 0; return 1; } /* Compare two tQSL_Date values, returning -1, 0, 1 */ DLLEXPORT int CALLCONVENTION tqsl_compareDates(const tQSL_Date *a, const tQSL_Date *b) { if (a == NULL || b == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (a->year < b->year) return -1; if (a->year > b->year) return 1; if (a->month < b->month) return -1; if (a->month > b->month) return 1; if (a->day < b->day) return -1; if (a->day > b->day) return 1; return 0; } // Return the number of days for a given year/month (January=1) static int days_per_month(int year, int month) { switch (month) { case 2: if ((((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0)) return 29; else return 28; case 4: case 6: case 9: case 11: return 30; default: return 31; } return 0; } // Return the julian day number for a given date. // One-based year/month/day static int julian_day(int year, int month, int day) { int jday = 0; for (int mon = 1; mon < month; mon ++) { jday += days_per_month(year, mon); } jday += day; return jday; } /* Calculate the difference between two tQSL_Date values */ DLLEXPORT int CALLCONVENTION tqsl_subtractDates(const tQSL_Date *a, const tQSL_Date *b, int *diff) { if (a == NULL || b == NULL || diff == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tQSL_Date first = *a; tQSL_Date last = *b; int mult = 1; // Ensure that the first is earliest if (tqsl_compareDates(&last, &first) < 0) { first = *b; last = *a; mult = -1; } int delta = 0; for (; first.year < last.year; first.year++) { int fday = julian_day(first.year, first.month, first.day); int fend = julian_day(first.year, 12, 31); delta += (fend - fday + 1); // days until next 1 Jan first.month = 1; first.day = 1; } // Now the years are the same - calculate delta int fjulian = julian_day(first.year, first.month, first.day); int ljulian = julian_day(last.year, last.month, last.day); delta += (ljulian - fjulian); *diff = (delta * mult); // Swap sign if necessary return 0; } /* Fill a tQSL_Date struct with the date from a text string */ DLLEXPORT int CALLCONVENTION tqsl_initDate(tQSL_Date *date, const char *str) { const char *cp; if (date == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (str == NULL) { date->year = date->month = date->day = 0; return 0; } if ((cp = strchr(str, '-')) != NULL) { /* Parse YYYY-MM-DD */ date->year = strtol(str, NULL, 10); cp++; date->month = strtol(cp, NULL, 10); cp = strchr(cp, '-'); if (cp == NULL) goto err; cp++; date->day = strtol(cp, NULL, 10); } else if (strlen(str) == 8) { /* Parse YYYYMMDD */ char frag[10]; strncpy(frag, str, 4); frag[4] = 0; date->year = strtol(frag, NULL, 10); strncpy(frag, str+4, 2); frag[2] = 0; date->month = strtol(frag, NULL, 10); date->day = strtol(str+6, NULL, 10); } else /* Invalid ISO date string */ goto err; if (date->year < 1 || date->year > 9999) goto err; if (date->month < 1 || date->month > 12) goto err; if (date->day < 1 || date->day > 31) goto err; return 0; err: tQSL_Error = TQSL_INVALID_DATE; return 1; } /* Fill a tQSL_Time struct with the time from a text string */ DLLEXPORT int CALLCONVENTION tqsl_initTime(tQSL_Time *time, const char *str) { const char *cp; int parts[3]; int i; if (time == NULL || str == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } time->hour = time->minute = time->second = 0; if (strlen(str) < 3) { tQSL_Error = TQSL_INVALID_TIME; return 1; } parts[0] = parts[1] = parts[2] = 0; for (i = 0, cp = str; i < int(sizeof parts / sizeof parts[0]); i++) { if (strlen(cp) < 2) break; if (!isdigit(*cp) || !isdigit(*(cp+1))) goto err; if (i == 0 && strlen(str) == 3) { // Special case: HMM -- no colons, one-digit hour parts[i] = *cp - '0'; ++cp; } else { parts[i] = (*cp - '0') * 10 + *(cp+1) - '0'; cp += 2; } if (*cp == ':') cp++; } if (parts[0] < 0 || parts[0] > 23) goto err; if (parts[1] < 0 || parts[1] > 59) goto err; if (parts[2] < 0 || parts[2] > 59) goto err; time->hour = parts[0]; time->minute = parts[1]; time->second = parts[2]; return 0; err: tQSL_Error = TQSL_INVALID_TIME; return 1; } DLLEXPORT int CALLCONVENTION tqsl_getVersion(int *major, int *minor) { if (major) *major = TQSLLIB_VERSION_MAJOR; if (minor) *minor = TQSLLIB_VERSION_MINOR; return 0; } tqsl-2.0/src/tqsllib-doc.h0000664000076400007640000000264412231073120015520 0ustar rmurphyrmurphy/*************************************************************************** tqsllib-doc.h - description ------------------- begin : Tue Jun 4 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ /** \mainpage * * The TrustedQSL library API is divided into several groups: * * \li \ref CertStuff - Request, load and retrieve digital certificates * \li \ref Data - Manage station-location data and produce signed data records * \li \ref Convert - Convert and sign ADIF and Cabrillo log files * \li \ref Util - Functions to operate on objects, set system parameters, and report errors * \li \ref Sign - Low-level digital signing * \li \ref ADIF - Low-level parsing and creation of ADIF files * \li \ref Cabrillo - Low-level parsing of Cabrillo files. * * Most of the library functions return an integer value that is * zero if there is no error and 1 if there is an error. The specific * error can be determined by examining #tQSL_Error and, possibly, * #tQSL_ADIF_Error, #tQSL_Cabrillo_Error, #tQSL_ErrorFile and * #tQSL_CustomError. The tqsl_getErrorString() and tqsl_getErrorString_v() * functions can be used to get error text strings. * */ tqsl-2.0/src/tqslexc.h0000664000076400007640000000167012231073120014764 0ustar rmurphyrmurphy/*************************************************************************** tqslexc.h - description ------------------- begin : Sat Dec 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslexc_h #define __tqslexc_h #include #include #include "tqsllib.h" class myexc : public std::exception { public: myexc(const std::string& err) : std::exception() { _err = err; } myexc(const myexc& x) { _err = x._err; } virtual const char *what() const throw () { return _err.c_str(); } virtual ~myexc() throw () {} private: std::string _err; }; class tqslexc : public myexc { public: tqslexc() : myexc(tqsl_getErrorString()) {} }; #endif // __tqslexc_h tqsl-2.0/src/tqslerrno.h0000664000076400007640000000544712231073120015340 0ustar rmurphyrmurphy/*************************************************************************** tqslerrno.h - description ------------------- begin : Tue May 28 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __TQSLERRNO_H #define __TQSLERRNO_H /** \file * #tQSL_Error values */ #define TQSL_NO_ERROR 0 ///< No error #define TQSL_SYSTEM_ERROR 1 ///< System Error #define TQSL_OPENSSL_ERROR 2 ///< Error in OpenSSL calls #define TQSL_ADIF_ERROR 3 ///< ADIF Errors #define TQSL_CUSTOM_ERROR 4 ///< Custom errors - output to tQSL_CustomError #define TQSL_CABRILLO_ERROR 5 ///< Cabrillo handler error #define TQSL_OPENSSL_VERSION_ERROR 6 ///< OpenSSL version obsolete #define TQSL_ERROR_ENUM_BASE 16 ///< Base for enumerated errors #define TQSL_ALLOC_ERROR 16 ///< Memory allocation error #define TQSL_RANDOM_ERROR 17 ///< Error initializing random number generator #define TQSL_ARGUMENT_ERROR 18 ///< Invalid arguments #define TQSL_OPERATOR_ABORT 19 ///< Aborted by operator #define TQSL_NOKEY_ERROR 20 ///< No key available #define TQSL_BUFFER_ERROR 21 ///< Insufficient buffer space #define TQSL_INVALID_DATE 22 ///< Date string invalid #define TQSL_SIGNINIT_ERROR 23 ///< Error initializing signing routine #define TQSL_PASSWORD_ERROR 24 ///< Invalid password #define TQSL_EXPECTED_NAME 25 ///< Name expected but not supplied #define TQSL_NAME_EXISTS 26 ///< Entity name exists already #define TQSL_NAME_NOT_FOUND 27 ///< Entity name does not exist #define TQSL_INVALID_TIME 28 ///< Time format is invalid #define TQSL_CERT_DATE_MISMATCH 29 ///< Certificate date mismatch #define TQSL_PROVIDER_NOT_FOUND 30 ///< Certificate provider unknown #define TQSL_CERT_KEY_ONLY 31 ///< No signed public key is installed #define TQSL_CONFIG_ERROR 32 ///< There is an error in the configuration file #define TQSL_CERT_NOT_FOUND 33 ///< The certificate could not be found #define TQSL_PKCS12_ERROR 34 ///< There is an error parsing the .p12 file #define TQSL_CERT_TYPE_ERROR 35 ///< The certificate type is invalid #define TQSL_DATE_OUT_OF_RANGE 36 ///< The date is out of the valid range #define TQSL_DUPLICATE_QSO 37 ///< This QSO is a duplicate #define TQSL_DB_ERROR 38 ///< The dupe database could not be accessed #define TQSL_LOCATION_NOT_FOUND 39 ///< The station location is invalid #define TQSL_CALL_NOT_FOUND 40 ///< The callsign could not be located #define TQSL_CONFIG_SYNTAX_ERROR 41 ///< The config file has a syntax error #define TQSL_FILE_SYSTEM_ERROR 42 ///< There was a file system I/O error #define TQSL_FILE_SYNTAX_ERROR 43 ///< The file format is invalid #endif /* __TQSLERRNO_H */ tqsl-2.0/src/tqslconvert.h0000664000076400007640000001544512231073120015672 0ustar rmurphyrmurphy/*************************************************************************** convert.h - description ------------------- begin : Sun Nov 17 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslconvert_h #define __tqslconvert_h #include "tqsllib.h" /** \file * tQSL library converter functions. */ /** \defgroup Convert Converter API * * The Converter API provides the capability of converting Cabrillo * and ADIF files to GABBI output. */ /** @{ */ typedef void * tQSL_Converter; //!< Opaque converter type used by applications //!< to access conversion functions //!< #ifdef __cplusplus extern "C" { #endif /** Create a simple converter object * * Allocates resources for converting logs and processing duplicate records. */ DLLEXPORT int CALLCONVENTION tqsl_beginConverter(tQSL_Converter *convp); /** Initiates the conversion process for an ADIF file. * * \c certs and \c ncerts define a set of certificates that are available to the * converter for signing records. Typically, this list will be obtained by * calling tqsl_selectCertificates(). * * tqsl_endConverter() should be called to free the resources when the conversion * is finished. */ DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter(tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc); /** Initiates the conversion process for a Cabrillo file. * * \c certs and \c ncerts define a set of certificates that are available to the * converter for signing records. Typically, this list will be obtained by * calling tqsl_selectCertificates(). * * tqsl_endConverter() should be called to free the resources when the conversion * is finished. */ DLLEXPORT int CALLCONVENTION tqsl_beginCabrilloConverter(tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc); /** End the conversion process by freeing the used resources. */ DLLEXPORT int CALLCONVENTION tqsl_endConverter(tQSL_Converter *conv); /** Configure the converter to allow (allow != 0) or disallow (allow == 0) * nonamateur call signs in the CALL field. (Note: the test for * validity is fairly trivial and will allow some nonamateur calls to * get through, but it does catch most common errors.) * * \c allow defaults to 0 when tqsl_beginADIFConverter or * tqsl_beginCabrilloConverter is called. */ DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowBadCall(tQSL_Converter conv, int allow); /** Configure the converter to allow (allow != 0) or disallow (allow == 0) * duplicate QSOs in a signed log. * Duplicate detection is done using QSO details, location details, and * certificate serial number. * * \c allow defaults to 1 for backwards compatibility when tqsl_beginADIFConverter or * tqsl_beginCabrilloConverter is called. */ DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowDuplicates(tQSL_Converter convp, int allow); /** Specify the name of the application using the conversion library. * This is output in a header record in the exported log file. * Call this before calling tqsl_getConverterGABBI. * * \c app is a c string containing the application name. */ DLLEXPORT int CALLCONVENTION tqsl_setConverterAppName(tQSL_Converter convp, const char *app); /** Roll back insertions into the duplicates database. * * This is called when cancelling creating a log, and causes any records * added to the duplicates database to be removed so re-processing that * log does not cause the records to be mis-marked as duplicates. */ DLLEXPORT int CALLCONVENTION tqsl_converterRollBack(tQSL_Converter convp); /** Commits insertions into the duplicates database. * * This is called when a log is created normally and without issue, and so * the presumption is that we are "done" with these QSOs. */ DLLEXPORT int CALLCONVENTION tqsl_converterCommit(tQSL_Converter convp); /** Bulk read the duplicate DB records * * This is called to retrieve the QSO records from the dupe database. * It returns the key/value pair upon each call. * Return -1 for end of file, 0 for success, 1 for errors. */ DLLEXPORT int CALLCONVENTION tqsl_getDuplicateRecords(tQSL_Converter convp, char *key, char *data, int keylen); /** Bulk write duplicate DB records * * This is called to store a QSO record into the dupe database. * * Return -1 for duplicate insertion, 0 for success, 1 for errors. */ DLLEXPORT int CALLCONVENTION tqsl_putDuplicateRecord(tQSL_Converter convp, const char *key, const char *data, int keylen); /** Set QSO date filtering in the converter. * * If \c start points to a valid date, QSOs prior to that date will be ignored * by the converter. Similarly, if \c end points to a valid date, QSOs after * that date will be ignored. Either or both may be NULL (or point to an * invalid date) to disable date filtering for the respective range. */ DLLEXPORT int CALLCONVENTION tqsl_setADIFConverterDateFilter(tQSL_Converter conv, tQSL_Date *start, tQSL_Date *end); /** This is the main converter function. It returns a single GABBI * record. * * Returns the NULL pointer on error or EOF. (Test tQSL_Error to determine which.) * * tQSL_Error is set to TQSL_DATE_OUT_OF_RANGE if QSO date range checking * is active and the QSO date is outside the specified range. * This is a non-fatal error. * * tQSL_Error is set to TQSL_DUPLICATE_QSO if the QSO has already been * processed on the current computer. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the GABBI records should be written in binary mode. * * N.B. If the selected certificate has not been initialized for signing via * tqsl_beginSigning(), this function will return a TQSL_SIGNINIT_ERROR. * The cert that caused the error can be obtained via tqsl_getConverterCert(), * initialized for signing, and then this function can be called again. No * data records will be lost in this process. */ DLLEXPORT const char* CALLCONVENTION tqsl_getConverterGABBI(tQSL_Converter conv); /** Get the certificate used to sign the most recent QSO record. */ DLLEXPORT int CALLCONVENTION tqsl_getConverterCert(tQSL_Converter conv, tQSL_Cert *certp); /** Get the input-file line number last read by the converter, starting * at line 1. */ DLLEXPORT int CALLCONVENTION tqsl_getConverterLine(tQSL_Converter conv, int *lineno); /** Get the text of the last record read by the converter. * * Returns NULL on error. */ DLLEXPORT const char* CALLCONVENTION tqsl_getConverterRecordText(tQSL_Converter conv); /** @} */ #ifdef __cplusplus } #endif #endif /* __tqslconvert_h */ tqsl-2.0/src/tqslconvert.cpp0000664000076400007640000006627612231073120016235 0ustar rmurphyrmurphy/*************************************************************************** tqslconvert.cpp - description ------------------- begin : Sun Nov 17 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #define TQSLLIB_DEF #include "tqsllib.h" #include "tqslconvert.h" #include #include #include #include "tqslerrno.h" #include #include #include #include #include #include #include //#include #ifndef _WIN32 #include #include #endif #include "winstrdefs.h" using namespace std; static bool checkCallSign(const string& call); namespace tqsllib { class TQSL_CONVERTER { public: TQSL_CONVERTER(); ~TQSL_CONVERTER(); void clearRec(); int sentinel; // FILE *file; tQSL_ADIF adif; tQSL_Cabrillo cab; tQSL_Cert *certs; int ncerts; tQSL_Location loc; TQSL_QSO_RECORD rec; bool rec_done; int cert_idx; int base_idx; bool need_station_rec; bool *certs_used; bool allow_bad_calls; set modes; set bands; set propmodes; set satellites; string rec_text; tQSL_Date start, end; DB *seendb; char *dbpath; DB_ENV* dbenv; DB_TXN* txn; DBC* cursor; FILE* errfile; char serial[512]; bool allow_dupes; bool need_ident_rec; char *appName; }; inline TQSL_CONVERTER::TQSL_CONVERTER() : sentinel(0x4445) { // file = 0; adif = 0; cab = 0; cert_idx = -1; base_idx = 1; certs_used = 0; need_station_rec = false; rec_done = true; allow_bad_calls = false; allow_dupes = true; //by default, don't change existing behavior (also helps with commit) memset(&rec, 0, sizeof rec); memset(&start, 0, sizeof start); memset(&end, 0, sizeof end); seendb = NULL; dbpath = NULL; dbenv = NULL; txn = NULL; cursor = NULL; errfile = NULL; memset(&serial, 0, sizeof serial); appName = NULL; need_ident_rec = true; // Init the band data const char *val; int n = 0; tqsl_getNumBand(&n); for (int i = 0; i < n; i++) { val = 0; tqsl_getBand(i, &val, 0, 0, 0); if (val) bands.insert(val); } // Init the mode data n = 0; tqsl_getNumMode(&n); for (int i = 0; i < n; i++) { val = 0; tqsl_getMode(i, &val, 0); if (val) modes.insert(val); } // Init the propagation mode data n = 0; tqsl_getNumPropagationMode(&n); for (int i = 0; i < n; i++) { val = 0; tqsl_getPropagationMode(i, &val, 0); if (val) propmodes.insert(val); } // Init the satellite data n = 0; tqsl_getNumSatellite(&n); for (int i = 0; i < n; i++) { val = 0; tqsl_getSatellite(i, &val, 0, 0, 0); if (val) satellites.insert(val); } } inline TQSL_CONVERTER::~TQSL_CONVERTER() { clearRec(); // if (file) // fclose(file); tqsl_endADIF(&adif); if (certs_used) delete[] certs_used; sentinel = 0; } inline void TQSL_CONVERTER::clearRec() { memset(&rec, 0, sizeof rec); rec_text = ""; } #define CAST_TQSL_CONVERTER(x) ((tqsllib::TQSL_CONVERTER *)(x)) } // namespace tqsllib using namespace tqsllib; static char * tqsl_strtoupper(char *str) { for (char *cp = str; *cp != '\0'; cp++) *cp = toupper(*cp); return str; } static TQSL_CONVERTER * check_conv(tQSL_Converter conv) { if (tqsl_init()) return 0; if (conv == 0 || CAST_TQSL_CONVERTER(conv)->sentinel != 0x4445) return 0; return CAST_TQSL_CONVERTER(conv); } static tqsl_adifFieldDefinitions adif_qso_record_fields[] = { { "CALL", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_CALLSIGN_MAX, 0, 0, NULL }, { "BAND", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_BAND_MAX, 0, 0, NULL }, { "MODE", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_MODE_MAX, 0, 0, NULL }, { "QSO_DATE", "", TQSL_ADIF_RANGE_TYPE_NONE, 10, 0, 0, NULL }, { "TIME_ON", "", TQSL_ADIF_RANGE_TYPE_NONE, 10, 0, 0, NULL }, { "FREQ", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_FREQ_MAX, 0, 0, NULL }, { "FREQ_RX", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_FREQ_MAX, 0, 0, NULL }, { "BAND_RX", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_BAND_MAX, 0, 0, NULL }, { "SAT_NAME", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_SATNAME_MAX, 0, 0, NULL }, { "PROP_MODE", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_PROPMODE_MAX, 0, 0, NULL }, { "eor", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, NULL }, }; DLLEXPORT int CALLCONVENTION tqsl_beginConverter(tQSL_Converter *convp) { if (tqsl_init()) return 0; if (!convp) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_CONVERTER *conv = new TQSL_CONVERTER(); *convp = conv; return 0; } DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter(tQSL_Converter *convp, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc) { if (tqsl_init()) return 0; if (!convp || !filename) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tQSL_ADIF adif; if (tqsl_beginADIF(&adif, filename)) return 1; TQSL_CONVERTER *conv = new TQSL_CONVERTER(); conv->adif = adif; conv->certs = certs; conv->ncerts = ncerts; if (ncerts > 0) { conv->certs_used = new bool[ncerts]; for (int i = 0; i < ncerts; i++) conv->certs_used[i] = false; } conv->loc = loc; *convp = conv; return 0; } DLLEXPORT int CALLCONVENTION tqsl_beginCabrilloConverter(tQSL_Converter *convp, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc) { if (tqsl_init()) return 0; if (!convp || !filename) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tQSL_Cabrillo cab; if (tqsl_beginCabrillo(&cab, filename)) return 1; TQSL_CONVERTER *conv = new TQSL_CONVERTER(); conv->cab = cab; conv->certs = certs; conv->ncerts = ncerts; if (ncerts > 0) { conv->certs_used = new bool[ncerts]; for (int i = 0; i < ncerts; i++) conv->certs_used[i] = false; } conv->loc = loc; *convp = conv; return 0; } DLLEXPORT int CALLCONVENTION tqsl_endConverter(tQSL_Converter *convp) { if (!convp || CAST_TQSL_CONVERTER(*convp) == 0) return 0; TQSL_CONVERTER* conv; if ((conv = check_conv(*convp))) { if (conv->txn) conv->txn->abort(conv->txn); if (conv->seendb) conv->seendb->close(conv->seendb, 0); if (conv->dbenv) conv->dbenv->close(conv->dbenv, 0); // close files and clean up converters, if any if (conv->adif) tqsl_endADIF(&conv->adif); if (conv->cab) tqsl_endCabrillo(&conv->cab); if (conv->cursor) conv->cursor->c_close(conv->cursor); if (conv->dbpath) free(conv->dbpath); if (conv->errfile) fclose(conv->errfile); } if (conv->appName) free(conv->appName); if (CAST_TQSL_CONVERTER(*convp)->sentinel == 0x4445) delete CAST_TQSL_CONVERTER(*convp); *convp = 0; return 0; } static unsigned char * adif_allocate(size_t size) { return new unsigned char[size]; } static int find_matching_cert(TQSL_CONVERTER *conv) { int i; for (i = 0; i < conv->ncerts; i++) { tQSL_Date cdate; if (tqsl_getCertificateQSONotBeforeDate(conv->certs[i], &cdate)) return -1; if (tqsl_compareDates(&(conv->rec.date), &cdate) < 0) continue; if (tqsl_getCertificateQSONotAfterDate(conv->certs[i], &cdate)) return -1; if (tqsl_compareDates(&(conv->rec.date), &cdate) > 0) continue; return i; } return -1; } static const char *notypes[] = { "D","T","M","N","C","" }; static const char * tqsl_infer_band(const char* infreq) { setlocale(LC_NUMERIC, "C"); double freq = atof(infreq); double freq_khz = freq * 1000.0; int nband = 0; tqsl_getNumBand(&nband); for (int i = 0; i < nband; i++) { const char *name; const char *spectrum; int low, high; if (tqsl_getBand(i, &name, &spectrum, &low, &high)) break; bool match = false; if (!strcmp(spectrum, "HF")) { // Allow for cases where loggers that don't log the // real frequency. if (low == 10100) low = 10000; else if (low == 18068) low = 18000; else if (low == 24890) low = 24000; if (freq_khz >= low && freq_khz <= high) { match = true; } } else { if (freq >= low && freq <= high) match = true; } if (match) return name; } return ""; } DLLEXPORT int CALLCONVENTION tqsl_setADIFConverterDateFilter(tQSL_Converter convp, tQSL_Date *start, tQSL_Date *end) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (start == NULL) conv->start.year = conv->start.month = conv->start.day = 0; else conv->start = *start; if (end == NULL) conv->end.year = conv->end.month = conv->end.day = 0; else conv->end = *end; return 0; } // Open the duplicates database static bool open_db(TQSL_CONVERTER *conv) { bool dbinit_cleanup=false; int dbret; bool triedRemove=false; string fixedpath=tQSL_BaseDir; //must be first because of gotos size_t found=fixedpath.find('\\'); //bdb complains about \\s in path on windows... while (found!=string::npos) { fixedpath.replace(found, 1, "/"); found=fixedpath.find('\\'); } conv->dbpath = strdup(fixedpath.c_str()); #ifndef _WIN32 // Clean up junk in that directory DIR *dir = opendir(fixedpath.c_str()); if (dir != NULL) { struct dirent *ent; while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] == '.') continue; struct stat s; // If it's a symlink pointing to itself, remove it. string fname = fixedpath + "/" + ent->d_name; if (stat(fname.c_str(), &s)) { if (errno == ELOOP) { unlink(fname.c_str()); } } } } #endif fixedpath += "/dberr.log"; conv->errfile = fopen(fixedpath.c_str(), "wb"); while (true) { // Create the database environment handle if ((dbret = db_env_create(&conv->dbenv, 0))) { // can't make env handle dbinit_cleanup=true; goto dbinit_end; } if (conv->errfile) conv->dbenv->set_errfile(conv->dbenv, conv->errfile); if ((dbret = conv->dbenv->open(conv->dbenv, conv->dbpath, DB_INIT_TXN|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_CREATE|DB_RECOVER, 0600))) { if (conv->errfile) fprintf(conv->errfile, "opening DB %s returns status %d", conv->dbpath, dbret); // can't open environment - try to delete it and try again. if (!triedRemove) { conv->dbenv->remove(conv->dbenv, conv->dbpath, DB_FORCE); triedRemove = true; if (conv->errfile) fprintf(conv->errfile, "About to retry after removing the environment\n"); continue; } if (conv->errfile) fprintf(conv->errfile, "Retry attempt after removing the environment failed."); // can't open environment and cleanup efforts failed. conv->dbenv = NULL; // this can't be recovered dbinit_cleanup=true; goto dbinit_end; } break; // Opened OK. } if ((dbret = db_create(&conv->seendb, conv->dbenv, 0))) { // can't create db dbinit_cleanup=true; goto dbinit_end; } #ifndef DB_TXN_BULK #define DB_TXN_BULK 0 #endif if ((dbret = conv->dbenv->txn_begin(conv->dbenv, NULL, &conv->txn, DB_TXN_BULK))) { // can't start a txn dbinit_cleanup=true; goto dbinit_end; } if ((dbret = conv->seendb->open(conv->seendb, conv->txn, "duplicates.db", NULL, DB_BTREE, DB_CREATE, 0600))) { // can't open the db dbinit_cleanup=true; goto dbinit_end; } dbinit_end: if (dbinit_cleanup) { tQSL_Error = TQSL_DB_ERROR; tQSL_Errno = errno; strcpy(tQSL_CustomError, db_strerror(dbret)); if (conv->txn) conv->txn->abort(conv->txn); if (conv->seendb) conv->seendb->close(conv->seendb, 0); if (conv->dbenv) { if (conv->dbpath) { conv->dbenv->remove(conv->dbenv, conv->dbpath, DB_FORCE); free(conv->dbpath); conv->dbpath = NULL; } conv->dbenv->close(conv->dbenv, 0); } if (conv->cursor) conv->cursor->c_close(conv->cursor); if (conv->errfile) fclose(conv->errfile); conv->txn = NULL; conv->dbenv = NULL; conv->cursor = NULL; conv->seendb = NULL; conv->errfile = NULL; return false; } return true; } DLLEXPORT const char* CALLCONVENTION tqsl_getConverterGABBI(tQSL_Converter convp) { TQSL_CONVERTER *conv; char signdata[1024]; if (!(conv = check_conv(convp))) return 0; if (conv->need_ident_rec) { int major = 0, minor = 0, config_major = 0, config_minor = 0; tqsl_getVersion(&major, &minor); tqsl_getConfigVersion(&config_major, &config_minor); char temp[512]; static char ident[512]; snprintf(temp, sizeof temp, "%s Lib: V%d.%d Config: V%d.%d AllowDupes: %s", conv->appName ? conv->appName : "Unknown", major, minor, config_major, config_minor, conv->allow_dupes ? "true" : "false"); temp[sizeof temp - 1] = '\0'; snprintf(ident, sizeof ident, "%s\n", (int)strlen(temp), temp); ident[sizeof ident - 1] = '\0'; conv->need_ident_rec = false; return ident; } if (conv->need_station_rec) { int uid = conv->cert_idx + conv->base_idx; conv->need_station_rec = false; const char *tStation = tqsl_getGABBItSTATION(conv->loc, uid, uid); tqsl_getCertificateSerialExt(conv->certs[conv->cert_idx], conv->serial, sizeof(conv->serial)); return tStation; } if (!conv->allow_dupes && !conv->seendb) { if (!open_db(conv)) { // If can't open dupes DB return 0; } } TQSL_ADIF_GET_FIELD_ERROR stat; if (conv->rec_done) { //cerr << "Getting rec" << endl; conv->rec_done = false; conv->clearRec(); int cstat = 0; int saveErr = 0; if (conv->adif) { while (1) { tqsl_adifFieldResults result; if (tqsl_getADIFField(conv->adif, &result, &stat, adif_qso_record_fields, notypes, adif_allocate)) break; if (stat != TQSL_ADIF_GET_FIELD_SUCCESS && stat != TQSL_ADIF_GET_FIELD_NO_NAME_MATCH) break; if (!strcasecmp(result.name, "eor")) break; if (!strcasecmp(result.name, "CALL") && result.data) { strncpy(conv->rec.callsign, (char *)(result.data), sizeof conv->rec.callsign); } else if (!strcasecmp(result.name, "BAND") && result.data) { strncpy(conv->rec.band, (char *)(result.data), sizeof conv->rec.band); } else if (!strcasecmp(result.name, "MODE") && result.data) { strncpy(conv->rec.mode, (char *)(result.data), sizeof conv->rec.mode); } else if (!strcasecmp(result.name, "FREQ") && result.data) { strncpy(conv->rec.freq, (char *)(result.data), sizeof conv->rec.freq); if (atof(conv->rec.freq) == 0.0) conv->rec.freq[0] = '\0'; } else if (!strcasecmp(result.name, "FREQ_RX") && result.data) { strncpy(conv->rec.rxfreq, (char *)(result.data), sizeof conv->rec.rxfreq); if (atof(conv->rec.rxfreq) == 0.0) conv->rec.rxfreq[0] = '\0'; } else if (!strcasecmp(result.name, "BAND_RX") && result.data) { strncpy(conv->rec.rxband, (char *)(result.data), sizeof conv->rec.rxband); } else if (!strcasecmp(result.name, "SAT_NAME") && result.data) { strncpy(conv->rec.satname, (char *)(result.data), sizeof conv->rec.satname); } else if (!strcasecmp(result.name, "PROP_MODE") && result.data) { strncpy(conv->rec.propmode, (char *)(result.data), sizeof conv->rec.propmode); } else if (!strcasecmp(result.name, "QSO_DATE") && result.data) { cstat = tqsl_initDate(&(conv->rec.date), (const char *)result.data); } else if (!strcasecmp(result.name, "TIME_ON") && result.data) { cstat = tqsl_initTime(&(conv->rec.time), (const char *)result.data); } if (stat == TQSL_ADIF_GET_FIELD_SUCCESS) { conv->rec_text += string((char *)result.name) + ": "; if (result.data) conv->rec_text += string((char *)result.data); conv->rec_text += "\n"; } if (result.data) delete[] result.data; if (cstat) saveErr = tQSL_Error; } if (saveErr) { tQSL_Error = saveErr; conv->rec_done = true; return 0; } if (stat == TQSL_ADIF_GET_FIELD_EOF) return 0; if (stat != TQSL_ADIF_GET_FIELD_SUCCESS) { tQSL_ADIF_Error = stat; tQSL_Error = TQSL_ADIF_ERROR; return 0; } // ADIF record is complete. See if we need to infer the BAND fields. if (conv->rec.band[0] == 0) strncpy(conv->rec.band, tqsl_infer_band(conv->rec.freq), sizeof conv->rec.band); if (conv->rec.rxband[0] == 0) strncpy(conv->rec.rxband, tqsl_infer_band(conv->rec.rxfreq), sizeof conv->rec.rxband); } else if (conv->cab) { TQSL_CABRILLO_ERROR_TYPE stat; do { tqsl_cabrilloField field; if (tqsl_getCabrilloField(conv->cab, &field, &stat)) return 0; if (stat == TQSL_CABRILLO_NO_ERROR || stat == TQSL_CABRILLO_EOR) { // Field found if (!strcasecmp(field.name, "CALL")) { strncpy(conv->rec.callsign, field.value, sizeof conv->rec.callsign); } else if (!strcasecmp(field.name, "BAND")) { strncpy(conv->rec.band, field.value, sizeof conv->rec.band); } else if (!strcasecmp(field.name, "MODE")) { strncpy(conv->rec.mode, field.value, sizeof conv->rec.mode); } else if (!strcasecmp(field.name, "FREQ")) { strncpy(conv->rec.freq, field.value, sizeof conv->rec.freq); } else if (!strcasecmp(field.name, "QSO_DATE")) { cstat = tqsl_initDate(&(conv->rec.date), field.value); } else if (!strcasecmp(field.name, "TIME_ON")) { cstat = tqsl_initTime(&(conv->rec.time), field.value); } if (conv->rec_text != "") conv->rec_text += "\n"; conv->rec_text += string(field.name) + ": " + field.value; if (cstat) saveErr = tQSL_Error; } } while (stat == TQSL_CABRILLO_NO_ERROR); if (saveErr) tQSL_Error = saveErr; if (saveErr || stat != TQSL_CABRILLO_EOR) { conv->rec_done = true; return 0; } } else { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "Converter not initialized"); return 0; } } // Check QSO date against user-specified date range. if (tqsl_isDateValid(&(conv->rec.date))) { if (tqsl_isDateValid(&(conv->start)) && tqsl_compareDates(&(conv->rec.date), &(conv->start)) < 0) { conv->rec_done = true; tQSL_Error = TQSL_DATE_OUT_OF_RANGE; return 0; } if (tqsl_isDateValid(&(conv->end)) && tqsl_compareDates(&(conv->rec.date), &(conv->end)) > 0) { conv->rec_done = true; tQSL_Error = TQSL_DATE_OUT_OF_RANGE; return 0; } } // Do field value mapping tqsl_strtoupper(conv->rec.callsign); if (!conv->allow_bad_calls) { if (!checkCallSign(conv->rec.callsign)) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid amateur CALL (%s)", conv->rec.callsign); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } } tqsl_strtoupper(conv->rec.band); tqsl_strtoupper(conv->rec.rxband); tqsl_strtoupper(conv->rec.mode); char val[256] = ""; tqsl_getADIFMode(conv->rec.mode, val, sizeof val); if (val[0] != '\0') strncpy(conv->rec.mode, val, sizeof conv->rec.mode); // Check field validities if (conv->modes.find(conv->rec.mode) == conv->modes.end()) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid MODE (%s)", conv->rec.mode); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->bands.find(conv->rec.band) == conv->bands.end()) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid BAND (%s)", conv->rec.band); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->rec.rxband[0] && (conv->bands.find(conv->rec.rxband) == conv->bands.end())) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid RX BAND (%s)", conv->rec.rxband); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->rec.freq[0] && strcmp(conv->rec.band, tqsl_infer_band(conv->rec.freq))) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Frequency %s is out of range for band %s", conv->rec.freq, conv->rec.band); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->rec.rxfreq[0] && strcmp(conv->rec.rxband, tqsl_infer_band(conv->rec.rxfreq))) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "RX Frequency %s is out of range for band %s", conv->rec.rxfreq, conv->rec.band); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->rec.propmode[0] != '\0' && conv->propmodes.find(conv->rec.propmode) == conv->propmodes.end()) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid PROP_MODE (%s)", conv->rec.propmode); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (conv->rec.satname[0] != '\0' && conv->satellites.find(conv->rec.satname) == conv->satellites.end()) { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Invalid SAT_NAME (%s)", conv->rec.satname); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (!strcmp(conv->rec.propmode, "SAT") && conv->rec.satname[0] == '\0') { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "PROP_MODE = 'SAT' but no SAT_NAME"); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } if (strcmp(conv->rec.propmode, "SAT") && conv->rec.satname[0] != '\0') { conv->rec_done = true; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "SAT_NAME set but PROP_MODE is not 'SAT'"); tQSL_Error = TQSL_CUSTOM_ERROR; return 0; } // Check cert if (conv->ncerts <= 0) { conv->rec_done = true; tQSL_Error = TQSL_CERT_NOT_FOUND; return 0; } int cidx = find_matching_cert(conv); if (cidx < 0) { conv->rec_done = true; tQSL_Error = TQSL_CERT_DATE_MISMATCH; return 0; } if (cidx != conv->cert_idx) { // Switching certs conv->cert_idx = cidx; if (!conv->certs_used[conv->cert_idx]) { // Need to output tCERT, tSTATION conv->need_station_rec = true; conv->certs_used[conv->cert_idx] = true; return tqsl_getGABBItCERT(conv->certs[conv->cert_idx], conv->cert_idx + conv->base_idx); } } const char *grec = tqsl_getGABBItCONTACTData(conv->certs[conv->cert_idx], conv->loc, &(conv->rec), conv->cert_idx + conv->base_idx, signdata, sizeof(signdata)); if (grec) { conv->rec_done = true; if (!conv->allow_dupes) { // Lookup uses signdata and cert serial number DBT dbkey, dbdata; char temp[2]; memset(&dbkey, 0, sizeof dbkey); memset(&dbdata, 0, sizeof dbdata); // append signing key serial strncat(signdata, conv->serial, sizeof(signdata) - strlen(signdata)-1); dbkey.size = strlen(signdata); dbkey.data = signdata; dbdata.size = sizeof(temp); dbdata.data = temp; int dbget_err = conv->seendb->get(conv->seendb, conv->txn, &dbkey, &dbdata, 0); if (0 == dbget_err) { //lookup was successful; thus duplicate tQSL_Error = TQSL_DUPLICATE_QSO; return 0; } else if (dbget_err != DB_NOTFOUND) { //non-zero return, but not "not found" - thus error strcpy(tQSL_CustomError, db_strerror(dbget_err)); tQSL_Error = TQSL_DB_ERROR; return 0; // could be more specific but there's very little the user can do at this point anyway } temp[0] = 'D'; dbdata.size = 1; int dbput_err; dbput_err = conv->seendb->put(conv->seendb, conv->txn, &dbkey, &dbdata, 0); if (0 != dbput_err) { strcpy(tQSL_CustomError, db_strerror(dbput_err)); tQSL_Error = TQSL_DB_ERROR; return 0; } } } return grec; } DLLEXPORT int CALLCONVENTION tqsl_getConverterCert(tQSL_Converter convp, tQSL_Cert *certp) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (certp == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *certp = conv->certs[conv->cert_idx]; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getConverterLine(tQSL_Converter convp, int *lineno) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (lineno == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (conv->cab) return tqsl_getCabrilloLine(conv->cab, lineno); else if (conv->adif) return tqsl_getADIFLine(conv->adif, lineno); *lineno = 0; return 0; } DLLEXPORT const char* CALLCONVENTION tqsl_getConverterRecordText(tQSL_Converter convp) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 0; return conv->rec_text.c_str(); } DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowBadCall(tQSL_Converter convp, int allow) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; conv->allow_bad_calls = (allow != 0); return 0; } DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowDuplicates(tQSL_Converter convp, int allow) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; conv->allow_dupes = (allow != 0); return 0; } DLLEXPORT int CALLCONVENTION tqsl_setConverterAppName(tQSL_Converter convp, const char *app) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (!app) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } conv->appName = strdup(app); return 0; } DLLEXPORT int CALLCONVENTION tqsl_converterRollBack(tQSL_Converter convp) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (!conv->seendb) return 1; if (conv->txn) conv->txn->abort(conv->txn); conv->txn = NULL; return 0; } DLLEXPORT int CALLCONVENTION tqsl_converterCommit(tQSL_Converter convp) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (!conv->seendb) return 1; if (conv->txn) conv->txn->commit(conv->txn, 0); conv->txn=NULL; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getDuplicateRecords(tQSL_Converter convp, char *key, char *data, int keylen) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 1; if (!conv->seendb) { if (!open_db(conv)) { // If can't open dupes DB return 1; } } #ifndef DB_CURSOR_BULK #define DB_CURSOR_BULK 0 #endif if (!conv->cursor) { int err = conv->seendb->cursor(conv->seendb, conv->txn, &conv->cursor, DB_CURSOR_BULK); if (err) { strcpy(tQSL_CustomError, db_strerror(err)); tQSL_Error = TQSL_DB_ERROR; tQSL_Errno = errno; return 1; } } DBT dbkey, dbdata; memset(&dbkey, 0, sizeof dbkey); memset(&dbdata, 0, sizeof dbdata); int status = conv->cursor->c_get(conv->cursor, &dbkey, &dbdata, DB_NEXT); if (DB_NOTFOUND == status) { return -1; // No more records } if (status != 0) { strcpy(tQSL_CustomError, db_strerror(status)); tQSL_Error = TQSL_DB_ERROR; tQSL_Errno = errno; return 1; } memcpy(key, dbkey.data, dbkey.size); key[dbkey.size] = '\0'; memcpy(data, dbdata.data, dbdata.size); data[dbdata.size] = '\0'; return 0; } DLLEXPORT int CALLCONVENTION tqsl_putDuplicateRecord(tQSL_Converter convp, const char *key, const char *data, int keylen) { TQSL_CONVERTER *conv; if (!(conv = check_conv(convp))) return 0; if (!conv->seendb) { if (!open_db(conv)) { // If can't open dupes DB return 0; } } DBT dbkey, dbdata; memset(&dbkey, 0, sizeof dbkey); memset(&dbdata, 0, sizeof dbdata); dbkey.size = keylen; dbkey.data = (char *)key; dbdata.size = 2; dbdata.data = (char *)data; int status = conv->seendb->put(conv->seendb, conv->txn, &dbkey, &dbdata, 0); if (DB_KEYEXIST == status) { return -1; // OK, but already there } if (status != 0) { strcpy(tQSL_CustomError, db_strerror(status)); tQSL_Error = TQSL_DB_ERROR; tQSL_Errno = errno; return 1; } return 0; } static bool hasValidCallSignChars(const string& call) { // Check for invalid characters if (call.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/") != string::npos) return false; // Need at least one letter if (call.find_first_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ") == string::npos) return false; // Need at least one number if (call.find_first_of("0123456789") == string::npos) return false; return true; } static bool checkCallSign(const string& call) { if (!hasValidCallSignChars(call)) return false; if (call.length() < 3) return false; string::size_type idx, newidx; for (idx = 0; idx != string::npos; idx = newidx+1) { string s; newidx = call.find('/', idx); if (newidx == string::npos) s = call.substr(idx); else s = call.substr(idx, newidx - idx); if (s.length() == 0) return false; // Leading or trailing '/' is bad, bad! if (newidx == string::npos) break; } return true; } tqsl-2.0/src/station_loc.cpp0000664000076400007640000000537712231073120016162 0ustar rmurphyrmurphy/*************************************************************************** station_loc.cpp - description ------------------- begin : Sat Dec 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include #include #include #include "tqsllib.h" #include "tqslexc.h" using namespace std; int usage() { cerr << "Usage: station_loc callsign [dxcc]" << endl; exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { try { string call, dxcc; if (argc < 2) usage(); call = argv[1]; if (argc > 2) dxcc = argv[2]; if (tqsl_init()) throw tqslexc(); tQSL_Location loc; if (tqsl_initStationLocationCapture(&loc)) throw tqslexc(); if (tqsl_setStationLocationCapturePage(loc, 1)) throw tqslexc(); // We know that the first field of page 1 is always call and the 2nd is DXCC int nfield; tqsl_getNumLocationFieldListItems(loc, 0, &nfield); int i; for (i = 0; i < nfield; i++) { char buf[256]; if (tqsl_getLocationFieldListItem(loc, 0, i, buf, sizeof buf)) throw tqslexc(); if (!strcasecmp(buf, call.c_str())) break; } if (i == nfield) throw myexc(string("Can't init station location for call = ") + call); if (tqsl_setLocationFieldIndex(loc, 0, i)) throw tqslexc(); if (tqsl_updateStationLocationCapture(loc)) throw tqslexc(); if (dxcc != "") { int nfield; tqsl_getNumLocationFieldListItems(loc, 1, &nfield); //cerr << nfield << endl; for (i = 0; i < nfield; i++) { char buf[256]; if (tqsl_setLocationFieldIndex(loc, 1, i)) throw tqslexc(); if (tqsl_getLocationFieldCharData(loc, 1, buf, sizeof buf)) throw tqslexc(); //cerr << buf << endl; if (!strcasecmp(buf, dxcc.c_str())) break; } if (i == nfield) throw myexc(string("Can't init location for DXCC = ") + dxcc); if (tqsl_setLocationFieldIndex(loc, 1, i)) throw tqslexc(); } int dxcc_idx; if (tqsl_getLocationFieldIndex(loc, 1, &dxcc_idx)) throw tqslexc(); char buf[256]; if (tqsl_getLocationFieldListItem(loc, 1, dxcc_idx, buf, sizeof buf)) throw tqslexc(); string lname = call + "_auto"; if (tqsl_setStationLocationCaptureName(loc, lname.c_str())) throw tqslexc(); if (tqsl_saveStationLocationCapture(loc, 1)) throw tqslexc(); tqsl_endStationLocationCapture(&loc); cout << "Wrote station location for " << call << " - " << buf << endl; } catch (exception& x) { cerr << "Aborted: " << x.what() << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } tqsl-2.0/src/openssl_cert.h0000664000076400007640000001336312231073120016003 0ustar rmurphyrmurphy/*************************************************************************** openssl_cert.h - description ------------------- begin : Tue May 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef OPENSSL_CERT_H #define OPENSSL_CERT_H /** \file * OpenSSL X509 certificate interface functions. */ #include #if (OPENSSL_VERSION_NUMBER == 0x10000003L) /* broken header file - fix by override */ #define i2d_ASN1_SET i2d_ASN1_SET_buggy #define d2i_ASN1_SET d2i_ASN1_SET_buggy #define ASN1_seq_unpack ASN1_seq_unpack_buggy #define ASN1_seq_pack ASN1_seq_pack_buggy #include #undef i2d_ASN1_SET #undef d2i_ASN1_SET #undef ASN1_seq_unpack #undef ASN1_seq_pack #ifdef __cplusplus extern "C" { #endif int i2d_ASN1_SET(void *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); void *d2i_ASN1_SET(void *a, const unsigned char **pp, long length, d2i_of_void *d2i, void (*free_func)(void*), int ex_tag, int ex_class); void *ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i, void (*free_func)(void*)); unsigned char *ASN1_seq_pack(void *safes, i2d_of_void *i2d, unsigned char **buf, int *len ); #ifdef __cplusplus } #endif #endif /* buggy openssl header */ #include #undef CLIENT_STATIC #ifndef LOTW_SERVER #define CLIENT_STATIC static #else #define CLIENT_STATIC #endif typedef STACK_OF(X509) TQSL_X509_STACK; typedef struct { char *name_buf; int name_buf_size; char *value_buf; int value_buf_size; } TQSL_X509_NAME_ITEM; namespace tqsllib { typedef enum { ROOTCERT = 0, CACERT, USERCERT } certtype; int tqsl_import_cert(const char *cert, certtype type, int(*cb)(int, const char *, void *), void *); int tqsl_get_pem_serial(const char *pem, long *serial); } // namespace #if defined(LOTW_SERVER) || defined(OPENSSL_CERT_SOURCE) #ifdef __cplusplus extern "C" { #endif /// Loads a stack of certificates from the caller-supplied BIO /** See the OpenSSL documentation for background on BIO operations. * * Returns a pointer to an OpenSSL X509 stack, as used by * tqsl_ssl_verify_cert() */ CLIENT_STATIC TQSL_X509_STACK *tqsl_ssl_load_certs_from_BIO(BIO *in); /// Loads a stack of certificates from a file /** See tqsl_ssl_load_certs_from_BIO() */ CLIENT_STATIC TQSL_X509_STACK *tqsl_ssl_load_certs_from_file(const char *filename); /// Verifies a certificate using stacks of certificates /** The user supplies the X509 certificate to verify (the test certificate) * along with two stacks of certificates. The \c cacerts stack is a list * of certificates, one of which was used to sign the test certificate. * The \c rootcerts are considered "trusted." One of them must have been used * to sign either the test certificate itself or the CA cert that signed * the test certificate. * * Returns NULL if the test certificate is valid, othewise returns an error message. */ CLIENT_STATIC const char *tqsl_ssl_verify_cert(X509 *cert, TQSL_X509_STACK *cacerts, TQSL_X509_STACK *rootcerts, int purpose, int (*cb)(int ok, X509_STORE_CTX *ctx), TQSL_X509_STACK **chain = 0); #if 0 /* unused */ /// Get the number of name entries in an X509 name object CLIENT_STATIC int tqsl_get_name_count(X509_NAME *name); /// Retrieve a name entry from an X509 name object by index CLIENT_STATIC int tqsl_get_name_index(X509_NAME *name, int index, TQSL_X509_NAME_ITEM *name_item); #endif /// Retrieve a name entry from an X509 name object by name CLIENT_STATIC int tqsl_get_name_entry(X509_NAME *name, const char *obj_name, TQSL_X509_NAME_ITEM *name_item); #if 0 /* unused */ /// Get the number of name entries in an X509 cert's subject name CLIENT_STATIC int tqsl_cert_get_subject_name_count(X509 *cert); /// Retrieve a name entry from an X509 cert's subject name by index CLIENT_STATIC int tqsl_cert_get_subject_name_index(X509 *cert, int index, TQSL_X509_NAME_ITEM *name_item); #endif /// Retrieve a name entry from an X509 cert's subject name by name CLIENT_STATIC int tqsl_cert_get_subject_name_entry(X509 *cert, const char *obj_name, TQSL_X509_NAME_ITEM *name_item); #if 0 /* unused */ /// Retrieve a name entry date from an X509 cert's subject name by name CLIENT_STATIC int tqsl_cert_get_subject_date(X509 *cert, const char *obj_name, tQSL_Date *date); #endif /// Convert an ASN date CLIENT_STATIC int tqsl_get_asn1_date(ASN1_TIME *tm, tQSL_Date *date); /// Filter a list (stack) of certs based on (optional) call sign, qso date and issuer criteria /** Returns a (possibly empty) stack of certificates that match the criteria. Returns NULL * on error. * * The returned stack contains \em copies of the certs from the input stack. The input * stack is not altered. */ CLIENT_STATIC TQSL_X509_STACK *tqsl_filter_cert_list(TQSL_X509_STACK *sk, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int isvalid); CLIENT_STATIC EVP_PKEY *tqsl_new_rsa_key(int nbits); CLIENT_STATIC int tqsl_store_cert(const char *pem, X509 *cert, const char *certfile, int type, bool force, int (*cb)(int, const char *, void *), void *); CLIENT_STATIC int tqsl_write_adif_field(FILE *fp, const char *fieldname, char type, const unsigned char *value, int len); CLIENT_STATIC int tqsl_bio_write_adif_field(BIO *bio, const char *fieldname, char type, const unsigned char *value, int len); #ifdef __cplusplus } #endif #endif /* defined(LOTW_SERVER) || defined(OPENSSL_CERT_SOURCE) */ #endif /* OPENSSL_CERT_H */ tqsl-2.0/src/openssl_cert.cpp0000664000076400007640000035545412231073120016350 0ustar rmurphyrmurphy/*************************************************************************** openssl_cert.c - description ------------------- begin : Tue May 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ /* Routines to massage X.509 certs for tQSL. See openssl_cert.h for overview */ /* 2004-04-10 Fixed tqsl_add_bag_attribute error for OpenSSL > 0.96 (Thanks to Kenji, JJ1BDX for the fix) */ /* Portions liberally copied from OpenSSL's apps source code */ /* ==================================================================== * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * openssl-core@openssl.org. * * 5. Products derived from this software may not be called "OpenSSL" * nor may "OpenSSL" appear in their names without prior written * permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the OpenSSL Project * for use in the OpenSSL Toolkit (http://www.openssl.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This product includes cryptographic software written by Eric Young * (eay@cryptsoft.com). This product includes software written by Tim * Hudson (tjh@cryptsoft.com). * */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * "This product includes cryptographic software written by * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */ #define OPENSSL_CERT_SOURCE #define TQSLLIB_DEF #include "tqsllib.h" #include "tqslerrno.h" #include #include #include #include #include #include #include #include #include #include #ifdef _WIN32 #include #define MKDIR(x,y) _mkdir(x) #else #define MKDIR(x,y) mkdir(x,y) #include #include #endif #include "winstrdefs.h" #ifdef _MSC_VER //is a visual studio compiler #include "windirent.h" #endif #define tqsl_malloc malloc #define tqsl_calloc calloc #define tqsl_free free #define TQSL_OBJ_TO_API(x) ((void *)(x)) #define TQSL_API_TO_OBJ(x,type) ((type)(x)) #define TQSL_API_TO_CERT(x) TQSL_API_TO_OBJ((x), tqsl_cert *) #include "openssl_cert.h" #include #include #include #undef X509_NAME //http://www.mail-archive.com/openssl-users@openssl.org/msg59116.html #include #include #include #include /* Ugly workaround for Openssl 1.0 bug per: * http://rt.openssl.org/Ticket/Display.html?user=guest&pass=guest&id=2123 */ #if (OPENSSL_VERSION_NUMBER == 0x10000003L) #define i2d_ASN1_SET i2d_ASN1_SET_buggy #define d2i_ASN1_SET d2i_ASN1_SET_buggy #define ASN1_seq_unpack ASN1_seq_unpack_buggy #define ASN1_seq_pack ASN1_seq_pack_buggy #include #undef i2d_ASN1_SET #undef d2i_ASN1_SET #undef ASN1_seq_unpack #undef ASN1_seq_pack #ifdef __cplusplus extern "C" { #endif int i2d_ASN1_SET(void *a, unsigned char **pp, i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); void *d2i_ASN1_SET(void *a, const unsigned char **pp, long length, d2i_of_void *d2i, void (*free_func)(void*), int ex_tag, int ex_class); void *ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i, void (*free_func)(void*)); unsigned char *ASN1_seq_pack(void *safes, i2d_of_void *i2d, unsigned char **buf, int *len ); #ifdef __cplusplus } #endif #endif // OpenSSL v1.0 #ifdef _WIN32 #define TQSL_OPEN_READ "rb" #define TQSL_OPEN_WRITE "wb" #define TQSL_OPEN_APPEND "ab" #else #define TQSL_OPEN_READ "r" #define TQSL_OPEN_WRITE "w" #define TQSL_OPEN_APPEND "a" #endif #if (OPENSSL_VERSION_NUMBER & 0xfffff000) >= 0x10000000L #define uni2asc OPENSSL_uni2asc #define asc2uni OPENSSL_asc2uni #endif using namespace std; using namespace tqsllib; static char *tqsl_trim(char *buf); static int tqsl_check_parm(const char *p, const char *parmName); static TQSL_CERT_REQ *tqsl_copy_cert_req(TQSL_CERT_REQ *userreq); static TQSL_CERT_REQ *tqsl_free_cert_req(TQSL_CERT_REQ *req, int seterr); static char *tqsl_make_key_path(const char *callsign, char *path, int size); static int tqsl_make_key_list(vector< map > & keys); static int tqsl_find_matching_key(X509 *cert, EVP_PKEY **keyp, TQSL_CERT_REQ **crq, const char *password, int (*cb)(char *,int,void *),void *); static char *tqsl_make_cert_path(const char *filename, char *path, int size); static int tqsl_get_cert_ext(X509 *cert, const char *ext, unsigned char *userbuf, int *buflen, int *crit); CLIENT_STATIC int tqsl_get_asn1_date(ASN1_TIME *tm, tQSL_Date *date); static char *tqsl_sign_base64_data(tQSL_Cert cert, char *b64data); static int fixed_password_callback(char *buf, int bufsiz, int verify, void *userdata); static int prompted_password_callback(char *buf, int bufsiz, int verify, void *userfunc); static int tqsl_check_crq_field(tQSL_Cert cert, char *buf, int bufsiz); static bool safe_strncpy(char *dest, const char *src, int size); static int tqsl_ssl_error_is_nofile(); static int tqsl_unlock_key(const char *pem, EVP_PKEY **keyp, const char *password, int (*cb)(char *,int,void *),void *); static int tqsl_replace_key(const char *callsign, const char *path, map& newfields, int (*cb)(int, const char *,void *),void *); static int tqsl_self_signed_is_ok(int ok, X509_STORE_CTX *ctx); static int tqsl_expired_is_ok(int ok, X509_STORE_CTX *ctx); /* Private data structures */ typedef struct { long id; X509 *cert; EVP_PKEY *key; TQSL_CERT_REQ *crq; char *pubkey; char *privkey; unsigned char keyonly; } tqsl_cert; typedef struct { long id; X509 *cert; } tqsl_crq; static tqsl_cert * tqsl_cert_new(); static void tqsl_cert_free(tqsl_cert *p); static int tqsl_cert_check(tqsl_cert *p, bool needcert = true); struct tqsl_loadcert_handler { int type; int (*func)(const char *pem, X509 *x, int(*cb)(int type, const char *,void *),void *); }; static int tqsl_handle_root_cert(const char *, X509 *, int (*cb)(int, const char *,void *),void *); static int tqsl_handle_ca_cert(const char *, X509 *, int (*cb)(int, const char *,void *),void *); static int tqsl_handle_user_cert(const char *, X509 *, int (*cb)(int, const char *,void *),void *); static struct tqsl_loadcert_handler tqsl_loadcert_handlers[] = { { TQSL_CERT_CB_ROOT, &tqsl_handle_root_cert }, { TQSL_CERT_CB_CA, &tqsl_handle_ca_cert }, { TQSL_CERT_CB_USER, &tqsl_handle_user_cert } }; static const char *notypes[] = { "" }; /* static tqsl_adifFieldDefinitions tqsl_cert_file_fields[] = { { "TQSL_CERT", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, NULL, NULL }, { "TQSL_CERT_USER", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, &tqsl_load_user_cert }, { "TQSL_CERT_CA", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, &tqsl_load_ca_cert }, { "TQSL_CERT_ROOT", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, &tqsl_load_root_cert }, }; */ static unsigned char tqsl_static_buf[2001]; static unsigned char * tqsl_static_alloc(size_t size) { if (size > sizeof tqsl_static_buf) return NULL; strcpy((char *)tqsl_static_buf, ""); return tqsl_static_buf; } namespace tqsllib { int tqsl_import_cert(const char *data, certtype type, int(*cb)(int, const char *,void *),void *userdata) { BIO *bio; X509 *cert; int stat; struct tqsl_loadcert_handler *handler = &(tqsl_loadcert_handlers[type]); /* This is a certificate, supposedly. Let's make sure */ bio = BIO_new_mem_buf((void *)data, strlen(data)); if (bio == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (cert == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } /* It's a certificate. Let's try to add it. Any errors will be * reported via the callback (if any) but will not be fatal unless * the callback says so. */ tQSL_ImportCall[0] = '\0'; stat = (*(handler->func))(data, cert, cb, userdata); X509_free(cert); if (stat) { if (cb != NULL) { stat = (*cb)(handler->type | TQSL_CERT_CB_RESULT | TQSL_CERT_CB_ERROR, tqsl_getErrorString_v(tQSL_Error), userdata); if (stat) return 1; } else /* No callback -- any errors are fatal */ return 1; } return 0; } int tqsl_get_pem_serial(const char *pem, long *serial) { BIO *bio; X509 *cert; if (tqsl_init()) return 1; if (pem == NULL || serial == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } bio = BIO_new_mem_buf((void *)pem, strlen(pem)); if (bio == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (cert == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } *serial = ASN1_INTEGER_get(X509_get_serialNumber(cert)); return 0; } } // namespace /********** PUBLIC API FUNCTIONS ***********/ DLLEXPORT int CALLCONVENTION tqsl_createCertRequest(const char *filename, TQSL_CERT_REQ *userreq, int (*pwcb)(char *pwbuf, int pwsize,void *),void *userdata) { TQSL_CERT_REQ *req = NULL; EVP_PKEY *key = NULL; X509_REQ *xr = NULL; X509_NAME *subj = NULL; int nid, len; int rval = 1; FILE *out = NULL; BIO *bio = NULL; const EVP_MD *digest = NULL; char buf[200]; char path[256]; char *cp; const EVP_CIPHER *cipher = NULL; RSA *rsa; char *password; const char *type; if (tqsl_init()) return 1; if (filename == NULL || userreq == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (userreq->signer != NULL && (!tqsl_cert_check(TQSL_API_TO_CERT(userreq->signer)) || TQSL_API_TO_CERT(userreq->signer)->key == NULL)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if ((req = tqsl_copy_cert_req(userreq)) == NULL) goto end; /* Check parameters for validity */ tqsl_trim(req->providerName); tqsl_trim(req->providerUnit); tqsl_trim(req->name); if (tqsl_check_parm(req->name, "Name")) goto end; tqsl_trim(req->callSign); if (tqsl_check_parm(req->callSign, "Call Sign")) goto end; tqsl_trim(req->address1); if (tqsl_check_parm(req->address1, "Address")) goto end; tqsl_trim(req->address2); tqsl_trim(req->city); if (tqsl_check_parm(req->city, "City")) goto end; tqsl_trim(req->state); tqsl_trim(req->country); if (tqsl_check_parm(req->country, "Country")) goto end; tqsl_trim(req->postalCode); tqsl_trim(req->emailAddress); if (tqsl_check_parm(req->emailAddress, "Email address")) goto end; if ((cp = strchr(req->emailAddress, '@')) == NULL || strchr(cp, '.') == NULL) { strncpy(tQSL_CustomError, "Invalid email address", sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; goto end; } if (!tqsl_isDateValid(&(req->qsoNotBefore))) { strncpy(tQSL_CustomError, "Invalid date (qsoNotBefore)", sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; goto end; } if (!tqsl_isDateNull(&(req->qsoNotAfter))) { if (!tqsl_isDateValid(&(req->qsoNotAfter))) { strncpy(tQSL_CustomError, "Invalid date (qsoNotAfter)", sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; goto end; } if (tqsl_compareDates(&(req->qsoNotAfter), &(req->qsoNotBefore)) < 0) { strncpy(tQSL_CustomError, "qsoNotAfter date is earlier than qsoNotBefore", sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; goto end; } } /* Try opening the output stream */ if ((out = fopen(filename, TQSL_OPEN_WRITE)) == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto end; } fputs("\ntQSL certificate request\n\n", out); tqsl_write_adif_field(out, "eoh", 0, NULL, 0); type = (req->signer != NULL) ? (req->renew ? "TQSL_CRQ_RENEWAL" : "TQSL_CRQ_ADDITIONAL") : "TQSL_CRQ_NEW"; int libmaj, libmin, configmaj, configmin; tqsl_getVersion(&libmaj, &libmin); tqsl_getConfigVersion(&configmaj, &configmin); snprintf(buf, sizeof buf, "Lib: V%d.%d, Config: %d, %d", libmaj, libmin, configmaj, configmin); tqsl_write_adif_field(out, "TQSL_IDENT", 0, (unsigned char *)buf, -1); tqsl_write_adif_field(out, type, 0, NULL, 0); tqsl_write_adif_field(out, "TQSL_CRQ_PROVIDER", 0, (unsigned char *)req->providerName, -1); tqsl_write_adif_field(out, "TQSL_CRQ_PROVIDER_UNIT", 0, (unsigned char *)req->providerUnit, -1); tqsl_write_adif_field(out, "TQSL_CRQ_EMAIL", 0, (unsigned char *)req->emailAddress, -1); tqsl_write_adif_field(out, "TQSL_CRQ_ADDRESS1", 0, (unsigned char *)req->address1, -1); tqsl_write_adif_field(out, "TQSL_CRQ_ADDRESS2", 0, (unsigned char *)req->address2, -1); tqsl_write_adif_field(out, "TQSL_CRQ_CITY", 0, (unsigned char *)req->city, -1); tqsl_write_adif_field(out, "TQSL_CRQ_STATE", 0, (unsigned char *)req->state, -1); tqsl_write_adif_field(out, "TQSL_CRQ_POSTAL", 0, (unsigned char *)req->postalCode, -1); tqsl_write_adif_field(out, "TQSL_CRQ_COUNTRY", 0, (unsigned char *)req->country, -1); snprintf(buf, sizeof buf, "%d", req->dxccEntity); tqsl_write_adif_field(out, "TQSL_CRQ_DXCC_ENTITY", 0, (unsigned char *)buf, -1); tqsl_convertDateToText(&(req->qsoNotBefore), buf, sizeof buf); tqsl_write_adif_field(out, "TQSL_CRQ_QSO_NOT_BEFORE", 0, (unsigned char *)buf, -1); if (!tqsl_isDateNull(&(req->qsoNotAfter))) { tqsl_convertDateToText(&(req->qsoNotAfter), buf, sizeof buf); tqsl_write_adif_field(out, "TQSL_CRQ_QSO_NOT_AFTER", 0, (unsigned char *)buf, -1); } /* Generate a new key pair */ if ((key = tqsl_new_rsa_key(1024)) == NULL) goto end; /* Make the X.509 certificate request */ if ((xr = X509_REQ_new()) == NULL) goto err; if (!X509_REQ_set_version(xr, 0L)) goto err; subj = X509_REQ_get_subject_name(xr); nid = OBJ_txt2nid("AROcallsign"); if (nid != NID_undef) X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, (unsigned char *)req->callSign, -1, -1, 0); nid = OBJ_txt2nid("commonName"); if (nid != NID_undef) X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, (unsigned char *)req->name, -1, -1, 0); nid = OBJ_txt2nid("emailAddress"); if (nid != NID_undef) X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_ASC, (unsigned char *)req->emailAddress, -1, -1, 0); X509_REQ_set_pubkey(xr, key); if ((digest = EVP_md5()) == NULL) goto err; if (!X509_REQ_sign(xr, key, digest)) goto err; if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err; if (!PEM_write_bio_X509_REQ(bio, xr)) goto err; len = (int)BIO_get_mem_data(bio, &cp); tqsl_write_adif_field(out, "TQSL_CRQ_REQUEST", 0, (unsigned char *)cp, len); if (req->signer != NULL) { char *b64; char ibuf[256]; if ((b64 = tqsl_sign_base64_data(req->signer, cp)) == NULL) { fclose(out); goto end; } tqsl_write_adif_field(out, "TQSL_CRQ_SIGNATURE", 0, (unsigned char *)b64, -1); tqsl_getCertificateIssuer(req->signer, ibuf, sizeof ibuf); tqsl_write_adif_field(out, "TQSL_CRQ_SIGNATURE_CERT_ISSUER", 0, (unsigned char *)ibuf, -1); snprintf(ibuf, sizeof ibuf, "%ld", ASN1_INTEGER_get(X509_get_serialNumber(TQSL_API_TO_CERT(req->signer)->cert))); tqsl_write_adif_field(out, "TQSL_CRQ_SIGNATURE_CERT_SERIAL", 0, (unsigned char *)ibuf, -1); } BIO_free(bio); bio = NULL; tqsl_write_adif_field(out, "eor", 0, NULL, 0); if (fclose(out) == EOF) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto end; } out = NULL; /* Write the key to the key store */ if (!tqsl_make_key_path(req->callSign, path, sizeof path)) goto end; if ((out = fopen(path, TQSL_OPEN_APPEND)) == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto end; } tqsl_write_adif_field(out, "TQSL_CRQ_PROVIDER", 0, (unsigned char *)req->providerName, -1); tqsl_write_adif_field(out, "TQSL_CRQ_PROVIDER_UNIT", 0, (unsigned char *)req->providerUnit, -1); tqsl_write_adif_field(out, "TQSL_CRQ_EMAIL", 0, (unsigned char *)req->emailAddress, -1); tqsl_write_adif_field(out, "TQSL_CRQ_ADDRESS1", 0, (unsigned char *)req->address1, -1); tqsl_write_adif_field(out, "TQSL_CRQ_ADDRESS2", 0, (unsigned char *)req->address2, -1); tqsl_write_adif_field(out, "TQSL_CRQ_CITY", 0, (unsigned char *)req->city, -1); tqsl_write_adif_field(out, "TQSL_CRQ_STATE", 0, (unsigned char *)req->state, -1); tqsl_write_adif_field(out, "TQSL_CRQ_POSTAL", 0, (unsigned char *)req->postalCode, -1); tqsl_write_adif_field(out, "TQSL_CRQ_COUNTRY", 0, (unsigned char *)req->country, -1); tqsl_write_adif_field(out, "CALLSIGN", 0, (unsigned char *)req->callSign, -1); snprintf(buf, sizeof buf, "%d", req->dxccEntity); tqsl_write_adif_field(out, "TQSL_CRQ_DXCC_ENTITY", 0, (unsigned char *)buf, -1); tqsl_convertDateToText(&(req->qsoNotBefore), buf, sizeof buf); tqsl_write_adif_field(out, "TQSL_CRQ_QSO_NOT_BEFORE", 0, (unsigned char *)buf, -1); if (!tqsl_isDateNull(&(req->qsoNotAfter))) { tqsl_convertDateToText(&(req->qsoNotAfter), buf, sizeof buf); tqsl_write_adif_field(out, "TQSL_CRQ_QSO_NOT_AFTER", 0, (unsigned char *)buf, -1); } if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err; password = (char *)req->password; if (password == NULL && pwcb != NULL) { if ((*pwcb)(buf, TQSL_MAX_PW_LENGTH, userdata)) { tQSL_Error = TQSL_OPERATOR_ABORT; goto end; } password = buf; } if (password != NULL && *password != '\0') { if ((cipher = EVP_des_ede3_cbc()) == NULL) goto err; len = strlen(password); } else { password = NULL; len = 0; } if (!PEM_write_bio_PrivateKey(bio, key, cipher, (unsigned char *)password, len, NULL, NULL)) goto err; len = (int)BIO_get_mem_data(bio, &cp); tqsl_write_adif_field(out, "PRIVATE_KEY", 0, (unsigned char *)cp, len); BIO_free(bio); if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err; rsa = key->pkey.rsa; /* Assume RSA */ if (!PEM_write_bio_RSA_PUBKEY(bio, rsa)) goto err; len = (int)BIO_get_mem_data(bio, &cp); tqsl_write_adif_field(out, "PUBLIC_KEY", 0, (unsigned char *)cp, len); BIO_free(bio); bio = NULL; tqsl_write_adif_field(out, "eor", 0, NULL, 0); if (fclose(out) == EOF) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto end; } out = NULL; rval = 0; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: if (bio != NULL) BIO_free(bio); if (out != NULL) fclose(out); if (xr != NULL) X509_REQ_free(xr); if (key != NULL) EVP_PKEY_free(key); if (req != NULL) tqsl_free_cert_req(req, 0); return rval; } DLLEXPORT int CALLCONVENTION tqsl_getSelectedCertificate(tQSL_Cert *cert, const tQSL_Cert **certlist, int idx) { if (tqsl_init()) return 1; if (certlist == NULL || cert == NULL || idx < 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *cert = (*certlist)[idx]; return 0; } DLLEXPORT int CALLCONVENTION tqsl_isCertificateExpired(tQSL_Cert cert, int *status) { if (tqsl_init()) return 1; if (cert == NULL || status == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), true)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *status = false; /* Check for expired */ time_t t = time(0); struct tm *tm = gmtime(&t); tQSL_Date d; d.year = tm->tm_year + 1900; d.month = tm->tm_mon + 1; d.day = tm->tm_mday; ASN1_TIME *ctm; if ((ctm = X509_get_notAfter(TQSL_API_TO_CERT(cert)->cert)) == NULL) { *status = true; return 0; } else { tQSL_Date cert_na; tqsl_get_asn1_date(ctm, &cert_na); if (tqsl_compareDates(&cert_na, &d) < 0) { *status = true; return 0; } } return 0; } DLLEXPORT int CALLCONVENTION tqsl_isCertificateSuperceded(tQSL_Cert cert, int *status) { TQSL_X509_STACK *xcerts = NULL; char path[256]; int i; X509 *x = NULL; char *cp; vector< map > keylist; vector< map >::iterator it; set superceded_certs; int len; bool superceded = false; char buf[256]; if (tqsl_init()) return 1; if (cert == NULL || status == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert),true)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *status = false; /* Get the certs from the cert store */ tqsl_make_cert_path("user", path, sizeof path); xcerts = tqsl_ssl_load_certs_from_file(path); if (xcerts == NULL) { if (tQSL_Error == TQSL_OPENSSL_ERROR) return 1; } /* Make a list of superceded certs */ for (i = 0; i < sk_X509_num(xcerts); i++) { x = sk_X509_value(xcerts, i); len = sizeof buf-1; if (!tqsl_get_cert_ext(x, "supercededCertificate", (unsigned char *)buf, &len, NULL)) { buf[len] = 0; string sup = buf; superceded_certs.insert(sup); /* Fix - the extension as inserted by ARRL * reads ".../Email=lotw@arrl.org", not * the expected ".../emailAddress=". * save both forms in case this gets * changed at the LoTW site */ size_t pos = sup.find("/Email"); if (pos != string::npos) { sup.replace(pos, 6, "/emailAddress"); superceded_certs.insert(sup); } } } // Done with the original cert list now if (xcerts != NULL) { sk_X509_free(xcerts); xcerts = NULL; } // "supercededCertificate" extension is ; cp = X509_NAME_oneline(X509_get_issuer_name(TQSL_API_TO_CERT(cert)->cert), buf, sizeof(buf)); if (cp == NULL) superceded = false; else { string sup = buf; sup += ";"; long serial = 0; tqsl_getCertificateSerial(cert, &serial); snprintf(buf, sizeof buf, "%ld", serial); sup += buf; set::iterator it; for (it = superceded_certs.begin(); it != superceded_certs.end(); it++) { if (*it == sup) superceded = true; } if (superceded_certs.find(sup) != superceded_certs.end()) superceded = true; } *status = superceded; return 0; } DLLEXPORT int CALLCONVENTION tqsl_selectCertificates(tQSL_Cert **certlist, int *ncerts, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flags) { int withkeys = flags & TQSL_SELECT_CERT_WITHKEYS; TQSL_X509_STACK *xcerts = NULL, *selcerts = NULL; char path[256]; int i; X509 *x; int rval = 1; tqsl_cert *cp; TQSL_CERT_REQ *crq; BIO *bio = NULL; EVP_PKEY *pubkey = NULL; RSA *rsa = NULL; vector< map > keylist; vector< map >::iterator it; if (tqsl_init()) return 1; if (certlist == NULL || ncerts == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *ncerts = 0; *certlist = NULL; /* Convert the dates to tQSL_Date objects */ if (date && !tqsl_isDateNull(date) && !tqsl_isDateValid(date)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } /* Get the certs from the cert store */ tqsl_make_cert_path("user", path, sizeof path); xcerts = tqsl_ssl_load_certs_from_file(path); if (xcerts == NULL) { if (tQSL_Error == TQSL_OPENSSL_ERROR) return 1; else if (tQSL_Error == TQSL_SYSTEM_ERROR && tQSL_Errno == ENOENT) // No file return 0; } else selcerts = tqsl_filter_cert_list(xcerts, callsign, dxcc, date, issuer, flags); // Get a list of keys and find any unmatched (no cert) ones if (withkeys) { if (tqsl_make_key_list(keylist)) goto end; if (xcerts != NULL) { for (i = 0; i < sk_X509_num(xcerts); i++) { x = sk_X509_value(xcerts, i); if ((pubkey = X509_get_pubkey(x)) == NULL) goto err; for (it = keylist.begin(); it != keylist.end(); it++) { int match = 0; /* Compare the keys */ string& keystr = (*it)["PUBLIC_KEY"]; if ((bio = BIO_new_mem_buf((void *)(keystr.c_str()), keystr.length())) == NULL) goto err; if ((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) goto err; BIO_free(bio); bio = NULL; if (BN_cmp(rsa->n, pubkey->pkey.rsa->n) == 0) if (BN_cmp(rsa->e, pubkey->pkey.rsa->e) == 0) match = 1; RSA_free(rsa); rsa = NULL; if (match) { // Remove matched key from list keylist.erase(it); break; } } EVP_PKEY_free(pubkey); pubkey = NULL; } } // Filter keylist for (it = keylist.begin(); it != keylist.end(); ) { if ((*it)["TQSL_CRQ_PROVIDER"] == "") it = keylist.erase(it); else if (callsign && (*it)["CALLSIGN"] != callsign) it = keylist.erase(it); else if (dxcc && strtol((*it)["TQSL_CRQ_DXCC_ENTITY"].c_str(), NULL, 10) != dxcc) it = keylist.erase(it); else if (issuer && (*it)["TQSL_CRQ_PROVIDER"] != issuer->organizationName) it = keylist.erase(it); else if (issuer && (*it)["TQSL_CRQ_PROVIDER_UNIT"] != issuer->organizationalUnitName) it = keylist.erase(it); else it++; } } // Done with the original cert list now if (xcerts != NULL) { sk_X509_free(xcerts); xcerts = NULL; } //cerr << keylist.size() << " unmatched keys" << endl; *ncerts = (selcerts ? sk_X509_num(selcerts) : 0) + keylist.size(); *certlist = (tQSL_Cert *)tqsl_calloc(*ncerts, sizeof (tQSL_Cert)); if (selcerts != NULL) { for (i = 0; i < sk_X509_num(selcerts); i++) { x = sk_X509_value(selcerts, i); if ((cp = tqsl_cert_new()) == NULL) goto end; cp->cert = X509_dup(x); (*certlist)[i] = TQSL_OBJ_TO_API(cp); } } else i = 0; for (it = keylist.begin(); it != keylist.end(); it++) { if ((cp = tqsl_cert_new()) == NULL) goto end; crq = (TQSL_CERT_REQ *)tqsl_calloc(1, sizeof (TQSL_CERT_REQ)); if (crq != NULL) { tQSL_Error = TQSL_BUFFER_ERROR; if (!safe_strncpy(crq->providerName, (*it)["TQSL_CRQ_PROVIDER"].c_str(), sizeof crq->providerName)) goto end; if (!safe_strncpy(crq->providerUnit, (*it)["TQSL_CRQ_PROVIDER_UNIT"].c_str(), sizeof crq->providerUnit)) goto end; if (!safe_strncpy(crq->callSign, (*it)["CALLSIGN"].c_str(), sizeof crq->callSign)) goto end; if (!safe_strncpy(crq->emailAddress, (*it)["TQSL_CRQ_EMAIL"].c_str(), sizeof crq->emailAddress)) goto end; if (!safe_strncpy(crq->address1, (*it)["TQSL_CRQ_ADDRESS1"].c_str(), sizeof crq->address1)) goto end; if (!safe_strncpy(crq->address2, (*it)["TQSL_CRQ_ADDRESS2"].c_str(), sizeof crq->address2)) goto end; if (!safe_strncpy(crq->city, (*it)["TQSL_CRQ_CITY"].c_str(), sizeof crq->city)) goto end; if (!safe_strncpy(crq->state, (*it)["TQSL_CRQ_STATE"].c_str(), sizeof crq->state)) goto end; if (!safe_strncpy(crq->postalCode, (*it)["TQSL_CRQ_POSTAL"].c_str(), sizeof crq->postalCode)) goto end; if (!safe_strncpy(crq->country, (*it)["TQSL_CRQ_COUNTRY"].c_str(), sizeof crq->country)) goto end; crq->dxccEntity = strtol((*it)["TQSL_CRQ_DXCC_ENTITY"].c_str(), NULL, 10); tqsl_initDate(&(crq->qsoNotBefore), (*it)["TQSL_CRQ_QSO_NOT_BEFORE"].c_str()); tqsl_initDate(&(crq->qsoNotAfter), (*it)["TQSL_CRQ_QSO_NOT_AFTER"].c_str()); tQSL_Error = 0; } cp->crq = crq; int len = strlen((*it)["PUBLIC_KEY"].c_str()); if (len) { cp->pubkey = new char[len+1]; strcpy(cp->pubkey, (*it)["PUBLIC_KEY"].c_str()); } len = strlen((*it)["PRIVATE_KEY"].c_str()); if (len) { cp->privkey = new char[len+1]; strcpy(cp->privkey, (*it)["PRIVATE_KEY"].c_str()); } cp->keyonly = 1; (*certlist)[i++] = TQSL_OBJ_TO_API(cp); } rval = 0; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: if (xcerts != NULL) sk_X509_free(xcerts); if (selcerts != NULL) sk_X509_free(selcerts); if (bio != NULL) BIO_free(bio); if (pubkey != NULL) EVP_PKEY_free(pubkey); if (rsa != NULL) RSA_free(rsa); return rval; } DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates(tQSL_Cert **certlist, int *ncerts, const char *type) { TQSL_X509_STACK *xcerts = NULL; int rval = 1; char path[256]; int i; X509 *x; tqsl_cert *cp; vector< map > keylist; vector< map >::iterator it; if (tqsl_init()) return 1; if (certlist == NULL || ncerts == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } /* Get the certs from the cert store */ tqsl_make_cert_path(type, path, sizeof path); xcerts = tqsl_ssl_load_certs_from_file(path); if (xcerts == NULL) if (tQSL_Error == TQSL_OPENSSL_ERROR) return 1; *ncerts = (xcerts ? sk_X509_num(xcerts) : 0) + keylist.size(); *certlist = (tQSL_Cert *)tqsl_calloc(*ncerts, sizeof (tQSL_Cert)); if (xcerts != NULL) { for (i = 0; i < sk_X509_num(xcerts); i++) { x = sk_X509_value(xcerts, i); if ((cp = tqsl_cert_new()) == NULL) goto end; cp->cert = X509_dup(x); (*certlist)[i] = TQSL_OBJ_TO_API(cp); } } rval = 0; end: if (xcerts != NULL) sk_X509_free(xcerts); return rval; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateKeyOnly(tQSL_Cert cert, int *keyonly) { if (tqsl_init()) return 1; if (cert == NULL || keyonly == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *keyonly = TQSL_API_TO_CERT(cert)->keyonly; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded(tQSL_Cert cert, char *buf, int bufsiz) { BIO *bio = NULL; int len; char *cp; int rval = 1; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if ((bio = BIO_new(BIO_s_mem())) == NULL) goto err; if (!PEM_write_bio_X509(bio, TQSL_API_TO_CERT(cert)->cert)) goto err; len = (int)BIO_get_mem_data(bio, &cp); if (len < bufsiz) { memcpy(buf, cp, len); buf[len] = 0; } else { tQSL_Error = TQSL_BUFFER_ERROR; goto end; } rval = 0; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: if (bio != NULL) BIO_free(bio); return rval; } DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded(tQSL_Cert cert, char *buf, int bufsiz) { BIO *b64 = NULL; BIO *bio = NULL; BIO *out = NULL; char callsign[40]; long len; char *cp; vector< map > keylist; vector< map >::iterator it; EVP_PKEY *pubkey = NULL; RSA *rsa = NULL; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert),false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tQSL_Error = TQSL_OPENSSL_ERROR; // If it's 'keyonly', then there's no public key - use the one in the cert. if (TQSL_API_TO_CERT(cert)->keyonly) { if (TQSL_API_TO_CERT(cert)->privkey == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(callsign, TQSL_API_TO_CERT(cert)->crq->callSign, sizeof callsign); b64 = BIO_new(BIO_f_base64()); out = BIO_new(BIO_s_mem()); out = BIO_push(b64, out); tQSL_Error = TQSL_SYSTEM_ERROR; if (tqsl_bio_write_adif_field(out, "CALLSIGN", 0, (const unsigned char *)callsign, -1)) return 1; if (tqsl_bio_write_adif_field(out, "PRIVATE_KEY", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->privkey, -1)) return 1; if (tqsl_bio_write_adif_field(out, "PUBLIC_KEY", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->pubkey, -1)) return 1; char numbuf[10]; snprintf(numbuf, sizeof numbuf, "%d", TQSL_API_TO_CERT(cert)->crq->dxccEntity); if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_DXCC_ENTITY", 0, (const unsigned char *)numbuf, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_PROVIDER", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->providerName, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_PROVIDER_UNIT", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->providerUnit, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_EMAIL", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->emailAddress, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_ADDRESS1", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->address1, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_ADDRESS2", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->address2, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_CITY", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->city, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_STATE", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->state, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_POSTAL", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->postalCode, -1)) return 1; if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_COUNTRY", 0, (const unsigned char *)TQSL_API_TO_CERT(cert)->crq->country, -1)) return 1; char datebuf[20]; tqsl_convertDateToText(&(TQSL_API_TO_CERT(cert)->crq->qsoNotAfter), datebuf, sizeof datebuf); if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_QSO_NOT_AFTER", 0, (const unsigned char *)datebuf, -1)) return 1; tqsl_convertDateToText(&(TQSL_API_TO_CERT(cert)->crq->qsoNotBefore), datebuf, sizeof datebuf); if (tqsl_bio_write_adif_field(out, "TQSL_CRQ_QSO_NOT_BEFORE", 0, (const unsigned char *)datebuf, -1)) return 1; tqsl_bio_write_adif_field(out, "eor", 0, NULL, 0); if (BIO_flush(out) != 1) { tQSL_Error = TQSL_SYSTEM_ERROR; strncpy(tQSL_CustomError, "Error encoding certificate", sizeof tQSL_CustomError); BIO_free_all(out); return 1; } len = BIO_get_mem_data(out, &cp); if (len > bufsiz) { tQSL_Error = TQSL_SYSTEM_ERROR; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Private key buffer size %d is too small - %ld needed", bufsiz, len); BIO_free_all(out); return 1; } memcpy(buf, cp, len); buf[len] = '\0'; BIO_free_all(out); return 0; } if (tqsl_getCertificateCallSign(cert, callsign, sizeof callsign)) return 1; if (tqsl_make_key_list(keylist)) return 1; if ((pubkey = X509_get_pubkey(TQSL_API_TO_CERT(cert)->cert)) == 0) return 1; // Find the matching private key for (it = keylist.begin(); it != keylist.end(); it++) { string& keystr = (*it)["PUBLIC_KEY"]; if ((bio = BIO_new_mem_buf((void *)(keystr.c_str()), keystr.length())) == NULL) return 1; if ((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) { BIO_free(bio); return 1; } BIO_free (bio); bio = NULL; if (BN_cmp(rsa->n, pubkey->pkey.rsa->n) == 0) { if (BN_cmp(rsa->e, pubkey->pkey.rsa->e) == 0) { // This is the matching private key. Let's feed it back. RSA_free(rsa); EVP_PKEY_free(pubkey); b64 = BIO_new(BIO_f_base64()); out = BIO_new(BIO_s_mem()); out = BIO_push(b64, out); map::iterator mit; for (mit = it->begin(); mit != it->end(); mit++) { if (tqsl_bio_write_adif_field(out, mit->first.c_str(), 0, (const unsigned char *)mit->second.c_str(), -1)) { tQSL_Error = TQSL_SYSTEM_ERROR; return 1; } } tqsl_bio_write_adif_field(out, "eor", 0, NULL, 0); if (BIO_flush(out) != 1) { tQSL_Error = TQSL_SYSTEM_ERROR; strncpy(tQSL_CustomError, "Error encoding certificate", sizeof tQSL_CustomError); BIO_free_all(out); return 1; } len = BIO_get_mem_data(out, &cp); if (len > bufsiz) { tQSL_Error = TQSL_SYSTEM_ERROR; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Private key buffer size %d is too small - %ld needed", bufsiz, len); BIO_free_all(out); return 1; } memcpy(buf, cp, len); buf[len] = '\0'; BIO_free_all(out); return 0; } else { RSA_free(rsa); EVP_PKEY_free(pubkey); } } } return 1; // Private key not found } DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded(const char *callsign, const char *type, const char *keybuf, const char *certbuf) { BIO *in = NULL; BIO *b64 = NULL; BIO *out = NULL; X509 *cert; char path[256]; char biobuf[4096]; int len; int cb = 0; if (tqsl_init()) return 1; if (certbuf == NULL || type == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (strcmp(type, "user") == 0) { if (keybuf == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } cb = TQSL_CERT_CB_USER; } else if (strcmp(type, "root") == 0) { cb = TQSL_CERT_CB_ROOT; } else if (strcmp(type, "authorities") == 0) { cb = TQSL_CERT_CB_CA; } else { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (keybuf) { if (!tqsl_make_key_path(callsign, path, sizeof path)) return 1; in = BIO_new_mem_buf((void *)keybuf, strlen(keybuf)); if (in == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } b64 = BIO_new(BIO_f_base64()); in = BIO_push(b64, in); out = BIO_new_file(path, "a"); if (!out) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Unable to open private key %s: %s", path, strerror(errno)); return 1; } while ((len = BIO_read(in, biobuf, sizeof biobuf)) > 0) BIO_write(out, biobuf, len); BIO_free_all(in); BIO_free_all(out); } // Import of private key if (strlen(certbuf) == 0) // Keyonly 'certificates' return 0; // Now process the certificate in = BIO_new_mem_buf((void *)certbuf, strlen(certbuf)); if (in == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } cert = PEM_read_bio_X509(in, NULL, NULL, NULL); BIO_free(in); if (cert == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return tqsl_store_cert(certbuf, cert, type, cb, true, NULL, NULL); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign(tQSL_Cert cert, char *buf, int bufsiz) { char nbuf[40]; TQSL_X509_NAME_ITEM item; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case if (bufsiz <= (int)strlen(TQSL_API_TO_CERT(cert)->crq->callSign)) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(buf, TQSL_API_TO_CERT(cert)->crq->callSign); return 0; } item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = buf; item.value_buf_size = bufsiz; return !tqsl_cert_get_subject_name_entry(TQSL_API_TO_CERT(cert)->cert, "AROcallsign", &item); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName(tQSL_Cert cert, char *buf, int bufsiz) { char nbuf[40]; TQSL_X509_NAME_ITEM item; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = buf; item.value_buf_size = bufsiz; return !tqsl_cert_get_subject_name_entry(TQSL_API_TO_CERT(cert)->cert, "commonName", &item); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress(tQSL_Cert cert, char *buf, int bufsiz) { char nbuf[40]; TQSL_X509_NAME_ITEM item; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = buf; item.value_buf_size = bufsiz; return !tqsl_cert_get_subject_name_entry(TQSL_API_TO_CERT(cert)->cert, "emailAddress", &item); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerial(tQSL_Cert cert, long *serial) { if (tqsl_init()) return 1; if (cert == NULL || serial == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *serial = ASN1_INTEGER_get(X509_get_serialNumber(TQSL_API_TO_CERT(cert)->cert)); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt(tQSL_Cert cert, char *serial, int serialsiz) { if (tqsl_init()) return 1; if (cert == NULL || serial == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert)) || serialsiz < 1) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } BIGNUM *bn = BN_new(); ASN1_INTEGER_to_BN(X509_get_serialNumber(TQSL_API_TO_CERT(cert)->cert), bn); char *s = BN_bn2hex(bn); strncpy(serial, s, serialsiz); serial[serialsiz-1] = 0; OPENSSL_free(s); BN_free(bn); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialLength(tQSL_Cert cert) { int rval; if (tqsl_init()) return 1; if (cert == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } BIGNUM *bn = BN_new(); ASN1_INTEGER_to_BN(X509_get_serialNumber(TQSL_API_TO_CERT(cert)->cert), bn); char *s = BN_bn2hex(bn); rval = strlen(s); OPENSSL_free(s); BN_free(bn); return rval; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer(tQSL_Cert cert, char *buf, int bufsiz) { char *cp; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } cp = X509_NAME_oneline(X509_get_issuer_name(TQSL_API_TO_CERT(cert)->cert), buf, bufsiz); if (cp == NULL) tQSL_Error = TQSL_OPENSSL_ERROR; return (cp == NULL); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganization(tQSL_Cert cert, char *buf, int bufsiz) { char nbuf[40]; TQSL_X509_NAME_ITEM item; X509_NAME *iss; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case if (bufsiz <= (int)strlen(TQSL_API_TO_CERT(cert)->crq->providerName)) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(buf, TQSL_API_TO_CERT(cert)->crq->providerName); return 0; } item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = buf; item.value_buf_size = bufsiz; if ((iss = X509_get_issuer_name(TQSL_API_TO_CERT(cert)->cert)) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return !tqsl_get_name_entry(iss, "organizationName", &item); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganizationalUnit(tQSL_Cert cert, char *buf, int bufsiz) { char nbuf[40]; TQSL_X509_NAME_ITEM item; X509_NAME *iss; if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case if (bufsiz <= (int)strlen(TQSL_API_TO_CERT(cert)->crq->providerUnit)) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(buf, TQSL_API_TO_CERT(cert)->crq->providerUnit); return 0; } item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = buf; item.value_buf_size = bufsiz; if ((iss = X509_get_issuer_name(TQSL_API_TO_CERT(cert)->cert)) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return !tqsl_get_name_entry(iss, "organizationalUnitName", &item); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotBeforeDate(tQSL_Cert cert, tQSL_Date *date) { char datebuf[40]; int len = (sizeof datebuf) -1; if (tqsl_init()) return 1; if (cert == NULL || date == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case *date = TQSL_API_TO_CERT(cert)->crq->qsoNotBefore; return 0; } if (tqsl_get_cert_ext(TQSL_API_TO_CERT(cert)->cert, "QSONotBeforeDate", (unsigned char *)datebuf, &len, NULL)) return 1; datebuf[len] = 0; return tqsl_initDate(date, (char *)datebuf); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotAfterDate(tQSL_Cert cert, tQSL_Date *date) { char datebuf[40]; int len = (sizeof datebuf) -1; if (tqsl_init()) return 1; if (cert == NULL || date == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case *date = TQSL_API_TO_CERT(cert)->crq->qsoNotAfter; return 0; } if (tqsl_get_cert_ext(TQSL_API_TO_CERT(cert)->cert, "QSONotAfterDate", (unsigned char *)datebuf, &len, NULL)) return 1; datebuf[len] = 0; return tqsl_initDate(date, (char *)datebuf); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotBeforeDate(tQSL_Cert cert, tQSL_Date *date) { ASN1_TIME *tm; if (tqsl_init()) return 1; if (cert == NULL || date == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly) { tQSL_Error = TQSL_CERT_KEY_ONLY; return 1; } if ((tm = X509_get_notBefore(TQSL_API_TO_CERT(cert)->cert)) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return tqsl_get_asn1_date(tm, date); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotAfterDate(tQSL_Cert cert, tQSL_Date *date) { ASN1_TIME *tm; if (tqsl_init()) return 1; if (cert == NULL || date == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if ((tm = X509_get_notAfter(TQSL_API_TO_CERT(cert)->cert)) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return tqsl_get_asn1_date(tm, date); } DLLEXPORT int CALLCONVENTION tqsl_getCertificateDXCCEntity(tQSL_Cert cert, int *dxcc) { char buf[40]; int len = sizeof buf; if (tqsl_init()) return 1; if (cert == NULL || dxcc == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->keyonly && TQSL_API_TO_CERT(cert)->crq) { // Handle the key-only case *dxcc = TQSL_API_TO_CERT(cert)->crq->dxccEntity; return 0; } if (tqsl_get_cert_ext(TQSL_API_TO_CERT(cert)->cert, "dxccEntity", (unsigned char *)buf, &len, NULL)) return 1; *dxcc = strtol(buf, NULL, 10); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificatePrivateKeyType(tQSL_Cert cert) { if (tqsl_init()) return 1; if (!tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (tqsl_beginSigning(cert, (char *) "", 0, 0)) { // Try to unlock the key using no password if (tQSL_Error == TQSL_PASSWORD_ERROR) { tqsl_getErrorString(); // Clear the error return TQSL_PK_TYPE_ENC; } return TQSL_PK_TYPE_ERR; } return TQSL_PK_TYPE_UNENC; } /* tqsl_cert *tc = TQSL_API_TO_CERT(cert); // if (!tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { if (!tqsl_cert_check(tc, false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (!tqsl_find_matching_key(TQSL_API_TO_CERT(cert)->cert, &key, NULL, "", NULL, NULL)) { if (tQSL_Error == TQSL_PASSWORD_ERROR) { tqsl_getErrorString(); // Clear the error return TQSL_PK_TYPE_ENC; } return TQSL_PK_TYPE_ERR; } return TQSL_PK_TYPE_UNENC; } */ DLLEXPORT void CALLCONVENTION tqsl_freeCertificate(tQSL_Cert cert) { tqsl_cert_free(TQSL_API_TO_CERT(cert)); } DLLEXPORT int CALLCONVENTION tqsl_beginSigning(tQSL_Cert cert, char *password, int(*pwcb)(char *, int,void *),void *userdata) { if (tqsl_init()) return 1; if (cert == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key != NULL) return 0; if (TQSL_API_TO_CERT(cert)->keyonly) { if (TQSL_API_TO_CERT(cert)->privkey == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } return tqsl_unlock_key(TQSL_API_TO_CERT(cert)->privkey, &(TQSL_API_TO_CERT(cert)->key), password, pwcb, userdata); } return !tqsl_find_matching_key(TQSL_API_TO_CERT(cert)->cert, &(TQSL_API_TO_CERT(cert)->key), &(TQSL_API_TO_CERT(cert)->crq), password, pwcb, userdata); } DLLEXPORT int CALLCONVENTION tqsl_getMaxSignatureSize(tQSL_Cert cert, int *sigsize) { if (tqsl_init()) return 1; if (cert == NULL || sigsize == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key == NULL) { tQSL_Error = TQSL_SIGNINIT_ERROR; return 1; } *sigsize = EVP_PKEY_size(TQSL_API_TO_CERT(cert)->key); return 0; } DLLEXPORT int CALLCONVENTION tqsl_checkSigningStatus(tQSL_Cert cert) { if (tqsl_init()) return 1; if (cert == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key == NULL) { tQSL_Error = TQSL_SIGNINIT_ERROR; return 1; } return 0; } DLLEXPORT int CALLCONVENTION tqsl_signDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int *siglen) { EVP_MD_CTX ctx; unsigned int slen = *siglen; if (tqsl_init()) return 1; if (cert == NULL || data == NULL || sig == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key == NULL) { tQSL_Error = TQSL_SIGNINIT_ERROR; return 1; } EVP_SignInit(&ctx, EVP_sha1()); EVP_SignUpdate(&ctx, data, datalen); if (!EVP_SignFinal(&ctx, sig, &slen, TQSL_API_TO_CERT(cert)->key)) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } *siglen = slen; return 0; } DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int siglen) { EVP_MD_CTX ctx; unsigned int slen = siglen; if (tqsl_init()) return 1; if (cert == NULL || data == NULL || sig == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key == NULL) { tQSL_Error = TQSL_SIGNINIT_ERROR; return 1; } EVP_VerifyInit(&ctx, EVP_sha1()); EVP_VerifyUpdate(&ctx, data, datalen); if (EVP_VerifyFinal(&ctx, sig, slen, TQSL_API_TO_CERT(cert)->key) <= 0) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } return 0; } DLLEXPORT int CALLCONVENTION tqsl_endSigning(tQSL_Cert cert) { if (tqsl_init()) return 1; if (cert == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->key != NULL) { EVP_PKEY_free(TQSL_API_TO_CERT(cert)->key); TQSL_API_TO_CERT(cert)->key = NULL; } return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress1(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->address1) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->address1), bufsiz); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress2(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->address2) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->address2), bufsiz); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->city) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->city), bufsiz); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->state) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->state), bufsiz); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestPostalCode(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->postalCode) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->postalCode), bufsiz); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCountry(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_check_crq_field(cert, buf, bufsiz)) return 1; strncpy(buf, (((TQSL_API_TO_CERT(cert)->crq)->country) == NULL ? "" : (TQSL_API_TO_CERT(cert)->crq)->country), bufsiz); return 0; } static int tqsl_add_bag_attribute(PKCS12_SAFEBAG *bag, const char *oidname, const string& value) { int nid; nid = OBJ_txt2nid((char *)oidname); if (nid == NID_undef) return 1; unsigned char *uni; int unilen; if (asc2uni(value.c_str(), value.length(), &uni, &unilen)) { ASN1_TYPE *val; ASN1_BMPSTRING *bmp; X509_ATTRIBUTE *attrib; if (!uni[unilen - 1] && !uni[unilen - 2]) unilen -= 2; if ((val = ASN1_TYPE_new()) != 0) { val->type = V_ASN1_BMPSTRING; if ((bmp = M_ASN1_BMPSTRING_new()) != 0) { bmp->data = (unsigned char *)OPENSSL_malloc(unilen); if (bmp->data) { memcpy(bmp->data, uni, unilen); bmp->length = unilen; val->value.bmpstring = bmp; if ((attrib = X509_ATTRIBUTE_new()) != 0) { attrib->object = OBJ_nid2obj(nid); if ((attrib->value.set = sk_ASN1_TYPE_new_null()) != 0) { sk_ASN1_TYPE_push(attrib->value.set, val); #if (OPENSSL_VERSION_NUMBER & 0xfffff000) == 0x00906000 attrib->set = 1; #elif (OPENSSL_VERSION_NUMBER & 0xfffff000) >= 0x00907000 attrib->single = 0; #else #error "Unexpected OpenSSL version; check X509_ATTRIBUTE struct compatibility" #endif if (bag->attrib) { sk_X509_ATTRIBUTE_push(bag->attrib, attrib); //cerr << "Added " << oidname << endl; } else return 1; } else return 1; } else return 1; } else return 1; } else return 1; } else return 1; } else // asc2uni ok return 1; return 0; } static int tqsl_exportPKCS12(tQSL_Cert cert, bool returnB64, const char *filename, char *base64, int b64len, const char *p12password) { STACK_OF(X509) *root_sk = 0, *ca_sk = 0, *chain = 0; const char *cp; char rootpath[256], capath[256]; char buf[256]; unsigned char keyid[EVP_MAX_MD_SIZE]; unsigned int keyidlen = 0; STACK_OF(PKCS12_SAFEBAG) *bags = 0; PKCS12_SAFEBAG *bag = 0; STACK_OF(PKCS7) *safes = 0; PKCS7 *authsafe = 0; int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC; int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; PKCS8_PRIV_KEY_INFO *p8 = 0; PKCS12 *p12 = 0; BIO *out = 0, *b64 = 0; string callSign, issuerOrganization, issuerOrganizationalUnit; tQSL_Date date; string QSONotBeforeDate, QSONotAfterDate, dxccEntity, Email, Address1, Address2, City, State, Postal, Country; int dxcc = 0; int rval = 1; if (cert == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if ((returnB64 && base64 == NULL) || (!returnB64 && filename == NULL)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } /* Get parameters for key bag attributes */ if (tqsl_getCertificateCallSign(cert, buf, sizeof buf)) return 1; callSign = buf; if (tqsl_getCertificateIssuerOrganization(cert, buf, sizeof buf)) return 1; issuerOrganization = buf; if (tqsl_getCertificateIssuerOrganizationalUnit(cert, buf, sizeof buf)) return 1; issuerOrganizationalUnit = buf; if (tqsl_getCertificateEmailAddress(cert, buf, sizeof buf)) return 1; Email = buf; if (tqsl_getCertificateRequestAddress1(cert, buf, sizeof buf)) return 1; Address1 = buf; if (tqsl_getCertificateRequestAddress2(cert, buf, sizeof buf)) return 1; Address2 = buf; if (tqsl_getCertificateRequestCity(cert, buf, sizeof buf)) return 1; City = buf; if (tqsl_getCertificateRequestState(cert, buf, sizeof buf)) return 1; State = buf; if (tqsl_getCertificateRequestPostalCode(cert, buf, sizeof buf)) return 1; Postal = buf; if (tqsl_getCertificateRequestCountry(cert, buf, sizeof buf)) return 1; Country = buf; if (tqsl_getCertificateQSONotBeforeDate(cert, &date)) return 1; if (!tqsl_convertDateToText(&date, buf, sizeof buf)) return 1; QSONotBeforeDate = buf; if (tqsl_getCertificateQSONotAfterDate(cert, &date)) return 1; if (!tqsl_isDateNull(&date)) { if (!tqsl_convertDateToText(&date, buf, sizeof buf)) return 1; QSONotAfterDate = buf; } if (tqsl_getCertificateDXCCEntity(cert, &dxcc)) return 1; snprintf(buf, sizeof buf, "%d", dxcc); dxccEntity = buf; if (TQSL_API_TO_CERT(cert)->key == NULL) { tQSL_Error = TQSL_SIGNINIT_ERROR; return 1; } if (!TQSL_API_TO_CERT(cert)->keyonly) { /* Generate local key ID to tie key to cert */ X509_digest(TQSL_API_TO_CERT(cert)->cert, EVP_sha1(), keyid, &keyidlen); /* Check the chain of authority back to a trusted root */ tqsl_make_cert_path("root", rootpath, sizeof rootpath); if ((root_sk = tqsl_ssl_load_certs_from_file(rootpath)) == NULL) { if (!tqsl_ssl_error_is_nofile()) goto p12_end; } tqsl_make_cert_path("authorities", capath, sizeof capath); if ((ca_sk = tqsl_ssl_load_certs_from_file(capath)) == NULL) { if (!tqsl_ssl_error_is_nofile()) goto p12_end; } /* tqsl_ssl_verify_cert will collect the certificates in the chain, back to the * root certificate, verify them and return a stack containing copies of just * those certificates (including the user certificate). */ cp = tqsl_ssl_verify_cert(TQSL_API_TO_CERT(cert)->cert, ca_sk, root_sk, 0, &tqsl_expired_is_ok, &chain); if (cp) { if (chain) sk_X509_free(chain); tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, cp, sizeof tQSL_CustomError); return 1; } } // !keyonly tQSL_Error = TQSL_OPENSSL_ERROR; // Assume error /* Open the output file */ if (!returnB64) { out = BIO_new_file(filename, "wb"); } else { b64 = BIO_new(BIO_f_base64()); out = BIO_new(BIO_s_mem()); out = BIO_push(b64, out); } if (!out) goto p12_end; safes = sk_PKCS7_new_null(); if (!TQSL_API_TO_CERT(cert)->keyonly) { /* Create a safebag stack and fill it with the needed certs */ bags = sk_PKCS12_SAFEBAG_new_null(); for (int i = 0; i < sk_X509_num(chain); i++) { X509 *x = sk_X509_value(chain, i); #if (OPENSSL_VERSION_NUMBER & 0xfffff000) == 0x00906000 bag = PKCS12_pack_safebag((char *)(x), (int (*)())i2d_X509, NID_x509Certificate, NID_certBag); #else bag = PKCS12_x5092certbag(x); #endif if (!bag) goto p12_end; if (x == TQSL_API_TO_CERT(cert)->cert) { PKCS12_add_friendlyname(bag, "TrustedQSL user certificate", -1); PKCS12_add_localkeyid(bag, keyid, keyidlen); } sk_PKCS12_SAFEBAG_push(bags, bag); } /* Convert stack of safebags into an authsafe */ authsafe = PKCS12_pack_p7encdata(cert_pbe, p12password, -1, 0, 0, PKCS12_DEFAULT_ITER, bags); if (!authsafe) goto p12_end; sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = 0; /* Add to stack of authsafes */ sk_PKCS7_push(safes, authsafe); } // !keyonly /* Make a shrouded key bag */ p8 = EVP_PKEY2PKCS8(TQSL_API_TO_CERT(cert)->key); if (!p8) goto p12_end; bag = PKCS12_MAKE_SHKEYBAG(key_pbe, p12password, -1, 0, 0, PKCS12_DEFAULT_ITER, p8); if (!bag) goto p12_end; PKCS8_PRIV_KEY_INFO_free(p8); p8 = 0; PKCS12_add_friendlyname(bag, "TrustedQSL user certificate", -1); if (!TQSL_API_TO_CERT(cert)->keyonly) PKCS12_add_localkeyid(bag, keyid, keyidlen); /* Add the attributes to the private key bag */ tqsl_add_bag_attribute(bag, "AROcallsign", callSign); tqsl_add_bag_attribute(bag, "QSONotBeforeDate", QSONotBeforeDate); if (QSONotAfterDate != "") tqsl_add_bag_attribute(bag, "QSONotAfterDate", QSONotAfterDate); tqsl_add_bag_attribute(bag, "tqslCRQIssuerOrganization", issuerOrganization); tqsl_add_bag_attribute(bag, "tqslCRQIssuerOrganizationalUnit", issuerOrganizationalUnit); tqsl_add_bag_attribute(bag, "dxccEntity", dxccEntity); tqsl_add_bag_attribute(bag, "tqslCRQEmail", Email); tqsl_add_bag_attribute(bag, "tqslCRQAddress1", Address1); tqsl_add_bag_attribute(bag, "tqslCRQAddress2", Address2); tqsl_add_bag_attribute(bag, "tqslCRQCity", City); tqsl_add_bag_attribute(bag, "tqslCRQState", State); tqsl_add_bag_attribute(bag, "tqslCRQPostal", Postal); tqsl_add_bag_attribute(bag, "tqslCRQCountry", Country); bags = sk_PKCS12_SAFEBAG_new_null(); if (!bags) goto p12_end; sk_PKCS12_SAFEBAG_push(bags, bag); /* Turn shrouded key bag into unencrypted safe bag and add to safes stack */ authsafe = PKCS12_pack_p7data(bags); sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = 0; sk_PKCS7_push(safes, authsafe); /* Form into PKCS12 data */ p12 = PKCS12_init(NID_pkcs7_data); #if OPENSSL_VERSION_NUMBER >= 0x10000000L //from http://www.redhat.com/archives/fedora-extras-commits/2009-August/msg08568.html ASN1_seq_pack((STACK_OF(OPENSSL_BLOCK)*)safes, (int(*)(void*, unsigned char**))i2d_PKCS7, &(p12)->authsafes->d.data->data, #else #if (OPENSSL_VERSION_NUMBER & 0xfffff000) >= 0x00908000 ASN1_seq_pack_PKCS7(safes, (int(*)(PKCS7*, unsigned char**))i2d_PKCS7, &(p12)->authsafes->d.data->data, #else ASN1_seq_pack_PKCS7(safes, (int(*)())i2d_PKCS7, &(p12)->authsafes->d.data->data, #endif #endif &(p12)->authsafes->d.data->length); sk_PKCS7_pop_free(safes, PKCS7_free); safes = 0; PKCS12_set_mac(p12, p12password, -1, 0, 0, PKCS12_DEFAULT_ITER, 0); /* Write the PKCS12 data */ i2d_PKCS12_bio(out, p12); if (BIO_flush(out) != 1) { rval = 1; goto p12_end; } if (returnB64) { char *encoded; int len; len = BIO_get_mem_data(out, &encoded); encoded[len - 1] = '\0'; strncpy(base64, encoded, b64len); } rval = 0; tQSL_Error = TQSL_NO_ERROR; p12_end: if (out) { BIO_free(out); if (rval && !returnB64) unlink(filename); } if (chain) sk_X509_free(chain); if (root_sk) sk_X509_free(root_sk); if (ca_sk) sk_X509_free(ca_sk); if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); if (p8) PKCS8_PRIV_KEY_INFO_free(p8); return rval; } DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File(tQSL_Cert cert, const char *filename, const char *p12password) { return tqsl_exportPKCS12(cert, false, filename, NULL, 0, p12password); } DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64(tQSL_Cert cert, char *base64, int b64len, const char *p12password) { return tqsl_exportPKCS12(cert, true, NULL, base64, b64len, p12password); } static string tqsl_asn1_octet_string_to_hex(ASN1_OCTET_STRING *os) { string str; for (int k = 0; k < os->length; k++) { char hex[3] = " "; hex[0] = ((os->data[k] >> 4) & 0xf) + '0'; if (hex[0] > '9') hex[0] += 'A' - '9' - 1; hex[1] = (os->data[k] & 0xf) + '0'; if (hex[1] > '9') hex[1] += 'A' - '9' - 1; if (str.size()) str += " "; str += hex; } return str; } struct tqsl_imported_cert { string pem; string keyid; string callsign; }; static int tqsl_get_bag_attribute(PKCS12_SAFEBAG *bag, const char *oidname, string& str) { ASN1_TYPE *attr; str = ""; if ((attr = PKCS12_get_attr(bag, OBJ_txt2nid((char *)oidname))) != 0) { if (attr->type != V_ASN1_BMPSTRING) { tQSL_Error = TQSL_CERT_TYPE_ERROR; return 1; } char *c = uni2asc(attr->value.bmpstring->data, attr->value.bmpstring->length); str = c; OPENSSL_free(c); } return 0; } static int tqsl_importPKCS12(bool importB64, const char *filename, const char *base64, const char *p12password, const char *password, int (*pwcb)(char *,int, void *), int(*cb)(int, const char *,void *), void *userdata) { PKCS12 *p12 = 0; PKCS12_SAFEBAG *bag; PKCS8_PRIV_KEY_INFO *p8 = 0; EVP_PKEY *pkey = 0; BIO *in = 0, *bio = 0 , *b64 = 0; STACK_OF(PKCS7) *safes = 0; STACK_OF(PKCS12_SAFEBAG) *bags = 0; PKCS7 *p7; X509 *x; BASIC_CONSTRAINTS *bs = 0; ASN1_OBJECT *callobj = 0, *obj = 0; ASN1_TYPE *attr = 0; const EVP_CIPHER *cipher; unsigned char *cp; int i, j, bagnid, len; vector rootcerts; vector cacerts; vector usercerts; vector *certlist; vector::iterator it; bool is_cacert; string public_key, private_key, private_keyid, key_callsign, str; map key_attr; map newrecord; map::iterator mit; char path[256], pw[256]; int rval = 1; if (tqsl_init()) return 1; if ((!importB64 && filename == NULL) || (importB64 && base64 == NULL)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tQSL_Error = TQSL_OPENSSL_ERROR; /* Read in the PKCS#12 file */ if (importB64) { b64 = BIO_new(BIO_f_base64()); in = BIO_new_mem_buf((char *)base64, strlen(base64)); in = BIO_push(b64, in); } else { in = BIO_new_file(filename, "rb"); } if (in == 0) goto imp_end; if ((p12 = d2i_PKCS12_bio(in, 0)) == 0) goto imp_end; BIO_free(in); in = 0; /* Verify MAC */ if (!PKCS12_verify_mac(p12, p12password, -1)) { tQSL_Error = TQSL_PASSWORD_ERROR; goto imp_end; } /* Loop through the authsafes */ if ((safes = M_PKCS12_unpack_authsafes(p12)) == 0) goto imp_end; callobj = OBJ_txt2obj("AROcallsign", 0); for (i = 0; i < sk_PKCS7_num(safes); i++) { tqsl_imported_cert imported_cert; p7 = sk_PKCS7_value(safes, i); bagnid = OBJ_obj2nid(p7->type); if (bagnid == NID_pkcs7_data) { bags = M_PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { bags = M_PKCS12_unpack_p7encdata(p7, p12password, strlen(p12password)); } else continue; // Not something we understand if (!bags) { tQSL_Error = TQSL_PKCS12_ERROR; goto imp_end; } /* Loop through safebags */ for (j = 0; j < sk_PKCS12_SAFEBAG_num(bags); j++) { tqsl_imported_cert imported_cert; bag = sk_PKCS12_SAFEBAG_value(bags, j); switch (M_PKCS12_bag_type(bag)) { case NID_certBag: if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) break; // Can't handle anything else if ((x = M_PKCS12_certbag2x509(bag)) == 0) goto imp_end; if ((bio = BIO_new(BIO_s_mem())) == NULL) goto imp_end; if (!PEM_write_bio_X509(bio, x)) goto imp_end; len = (int)BIO_get_mem_data(bio, &cp); imported_cert.pem = string((const char *)cp, len); if ((attr = PKCS12_get_attr(bag, NID_localKeyID)) != 0) { if (attr->type != V_ASN1_OCTET_STRING) { tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } imported_cert.keyid = tqsl_asn1_octet_string_to_hex(attr->value.octet_string); } BIO_free(bio); bio = 0; is_cacert = false; if ((bs = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(x, NID_basic_constraints, 0, 0)) != 0) { if (bs->ca) is_cacert = true; BASIC_CONSTRAINTS_free(bs); bs = 0; } certlist = &usercerts; if (is_cacert) { if (X509_check_issued(x, x) == X509_V_OK) // Self signed must be trusted certlist = &rootcerts; else certlist = &cacerts; } else { /* Make sure the cert is TQSL compatible */ TQSL_X509_NAME_ITEM item; char nbuf[40]; char callbuf[256]; item.name_buf = nbuf; item.name_buf_size = sizeof nbuf; item.value_buf = callbuf; item.value_buf_size = sizeof callbuf; if (!tqsl_cert_get_subject_name_entry(x, "AROcallsign", &item)) { tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } imported_cert.callsign = callbuf; } (*certlist).push_back(imported_cert); break; case NID_pkcs8ShroudedKeyBag: if ((attr = PKCS12_get_attr(bag, NID_localKeyID)) != 0) { if (attr->type != V_ASN1_OCTET_STRING) { tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } private_keyid = tqsl_asn1_octet_string_to_hex(attr->value.octet_string); } if (tqsl_get_bag_attribute(bag, "AROcallsign", key_callsign)) goto imp_end; if (tqsl_get_bag_attribute(bag, "dxccEntity", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_DXCC_ENTITY"] = str; if (tqsl_get_bag_attribute(bag, "QSONotBeforeDate", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_QSO_NOT_BEFORE"] = str; if (tqsl_get_bag_attribute(bag, "QSONotAfterDate", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_QSO_NOT_AFTER"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQIssuerOrganization", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_PROVIDER"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQIssuerOrganizationalUnit", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_PROVIDER_UNIT"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQEmail", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_EMAIL"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQAddress1", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_ADDRESS1"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQAddress2", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_ADDRESS2"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQCity", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_CITY"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQState", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_STATE"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQPostal", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_POSTAL"] = str; if (tqsl_get_bag_attribute(bag, "tqslCRQCountry", str)) goto imp_end; if (str != "") key_attr["TQSL_CRQ_COUNTRY"] = str; if ((p8 = M_PKCS12_decrypt_skey(bag, p12password, strlen(p12password))) == 0) goto imp_end; if ((pkey = EVP_PKCS82PKEY(p8)) == 0) goto imp_end; if ((bio = BIO_new(BIO_s_mem())) == NULL) goto imp_end; if (password == 0) { if (pwcb) { if ((*pwcb)(pw, sizeof pw -1, userdata)) { tQSL_Error = TQSL_OPERATOR_ABORT; goto imp_end; } password = pw; } else { password = NULL; } } if (password && *password != '\0') { cipher = EVP_des_ede3_cbc(); len = strlen(password); } else { cipher = 0; len = 0; } if (!PEM_write_bio_PrivateKey(bio, pkey, cipher, (unsigned char *)password, len, 0, 0)) goto imp_end; len = (int)BIO_get_mem_data(bio, &cp); private_key = string((const char *)cp, len); BIO_free(bio); if ((bio = BIO_new(BIO_s_mem())) == NULL) goto imp_end; if (!PEM_write_bio_RSA_PUBKEY(bio, pkey->pkey.rsa)) goto imp_end; len = (int)BIO_get_mem_data(bio, &cp); public_key = string((const char *)cp, len); BIO_free(bio); bio = 0; EVP_PKEY_free(pkey); pkey = 0; PKCS8_PRIV_KEY_INFO_free(p8); p8 = 0; break; case NID_keyBag: tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } // bag type switch } // safebags loop sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); bags = 0; } sk_PKCS7_pop_free(safes, PKCS7_free); safes = 0; /* Now we have the certificates and key pair, so add them to the local store */ if (key_callsign == "") { /* Need to get call sign from cert. The tQSL_exportKeys function puts the * call sign in a safebag attribute that should have been read already, * but if some other software created the PKCS#12 file that may not have * happened. There should, however, be a localKeyID attribute that matches * the key to the certificate. If not, it's an error. */ if (private_keyid == "") { // No key ID, can't find cert tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } for (it = usercerts.begin(); it != usercerts.end(); it++) { if ((*it).keyid == private_keyid) { key_callsign = (*it).callsign; break; } } if (key_callsign == "") { // Can't find cert or callsign tQSL_Error = TQSL_CERT_TYPE_ERROR; goto imp_end; } } if (!tqsl_make_key_path(key_callsign.c_str(), path, sizeof path)) goto imp_end; newrecord["PUBLIC_KEY"] = public_key; newrecord["PRIVATE_KEY"] = private_key; newrecord["CALLSIGN"] = key_callsign; for (mit = key_attr.begin(); mit != key_attr.end(); mit++) newrecord[mit->first] = mit->second; if (tqsl_replace_key(key_callsign.c_str(), path, newrecord, cb, userdata)) goto imp_end; for (it = rootcerts.begin(); it != rootcerts.end(); it++) if (tqsl_import_cert(it->pem.c_str(), ROOTCERT, cb, userdata)) goto imp_end; for (it = cacerts.begin(); it != cacerts.end(); it++) if (tqsl_import_cert(it->pem.c_str(), CACERT, cb, userdata)) goto imp_end; for (it = usercerts.begin(); it != usercerts.end(); it++) if (tqsl_import_cert(it->pem.c_str(), USERCERT, cb, userdata)) { char savepath[1024], badpath[1024]; strncpy(badpath, path, sizeof(badpath)); strncat(badpath, ".bad", sizeof(badpath)-strlen(badpath)-1); badpath[sizeof(badpath)-1] = '\0'; if (!rename(path, badpath)) { strncpy(savepath, path, sizeof(savepath)); strncat(savepath, ".save", sizeof(savepath)-strlen(savepath)-1); savepath[sizeof(savepath)-1] = '\0'; if (rename(savepath, path)) // didn't work rename(badpath, path); else unlink(badpath); } goto imp_end; } tQSL_Error = TQSL_NO_ERROR; rval = 0; imp_end: if (p12) PKCS12_free(p12); if (in) BIO_free(in); if (bags) sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); if (safes) sk_PKCS7_pop_free(safes, PKCS7_free); if (obj) ASN1_OBJECT_free(obj); if (callobj) ASN1_OBJECT_free(callobj); if (bs) BASIC_CONSTRAINTS_free(bs); if (p8) PKCS8_PRIV_KEY_INFO_free(p8); if (pkey) EVP_PKEY_free(pkey); return rval; } DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File(const char *filename, const char *p12password, const char *password, int (*pwcb)(char *,int, void *), int(*cb)(int, const char *,void *), void *userdata) { return tqsl_importPKCS12(false, filename, NULL, p12password, password, pwcb, cb, userdata); } DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64(const char *base64, const char *p12password, const char *password, int (*pwcb)(char *,int, void *), int(*cb)(int, const char *,void *), void *userdata) { return tqsl_importPKCS12(true, NULL, base64, p12password, password, pwcb, cb, userdata); } DLLEXPORT int CALLCONVENTION tqsl_deleteCertificate(tQSL_Cert cert) { if (tqsl_init()) return 1; if (cert == NULL || !tqsl_cert_check(TQSL_API_TO_CERT(cert), false)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } char callsign[256], path[256], newpath[256]; if (tqsl_getCertificateCallSign(cert, callsign, sizeof callsign)) return 1; int rval = 1; EVP_PKEY *key = 0; TQSL_X509_STACK *xcerts = 0, *ncerts = 0; BIO *bio = 0; tQSL_Error = TQSL_OPENSSL_ERROR; // Delete private key map rec; if (TQSL_API_TO_CERT(cert)->pubkey) rec["PUBLIC_KEY"] = TQSL_API_TO_CERT(cert)->pubkey; else { // Get public key from cert if ((key = X509_get_pubkey(TQSL_API_TO_CERT(cert)->cert)) == 0) goto dc_end; if ((bio = BIO_new(BIO_s_mem())) == NULL) goto dc_end; if (!PEM_write_bio_RSA_PUBKEY(bio, key->pkey.rsa)) goto dc_end; char *cp; int len = (int)BIO_get_mem_data(bio, &cp); rec["PUBLIC_KEY"] = string(cp, len); BIO_free(bio); bio = 0; EVP_PKEY_free(key); key = 0; } rec["CALLSIGN"] = callsign; if (!tqsl_make_key_path(callsign, path, sizeof path)) goto dc_end; // Since there is no private key in "rec," tqsl_replace_key will just remove the // existing private key. tqsl_replace_key(callsign, path, rec, 0, 0); if (TQSL_API_TO_CERT(cert)->keyonly) goto dc_ok; // Now the certificate tqsl_make_cert_path("user", path, sizeof path); tqsl_make_cert_path("user.new", newpath, sizeof newpath); if ((xcerts = tqsl_ssl_load_certs_from_file(path)) == 0) goto dc_end; if ((bio = BIO_new_file(newpath, "wb")) == 0) goto dc_end; X509 *x; while ((x = sk_X509_shift(xcerts)) != 0) { if (X509_issuer_and_serial_cmp(x, TQSL_API_TO_CERT(cert)->cert)) if (!PEM_write_bio_X509(bio, x)) // No match -- keep this one goto dc_end; } BIO_free(bio); bio = 0; // Looks like the new file is okay, commit it if (unlink(path) && errno != ENOENT) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto dc_end; } if (rename(newpath, path)) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto dc_end; } dc_ok: rval = 0; tQSL_Error = TQSL_NO_ERROR; dc_end: if (xcerts) sk_X509_free(xcerts); if (ncerts) sk_X509_free(ncerts); if (key) EVP_PKEY_free(key); if (bio) BIO_free(bio); return rval; } /********** END OF PUBLIC API FUNCTIONS **********/ /* Utility functions to manage private data structures */ static int tqsl_check_crq_field(tQSL_Cert cert, char *buf, int bufsiz) { if (tqsl_init()) return 1; if (cert == NULL || buf == NULL || bufsiz < 0 || !tqsl_cert_check(TQSL_API_TO_CERT(cert))) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (TQSL_API_TO_CERT(cert)->crq == NULL) { if (!tqsl_find_matching_key(TQSL_API_TO_CERT(cert)->cert, NULL, &(TQSL_API_TO_CERT(cert)->crq), "", NULL, NULL) && tQSL_Error != TQSL_PASSWORD_ERROR) return 1; } return 0; } static int tqsl_cert_check(tqsl_cert *p, bool needcert) { if (p != NULL && p->id == 0xCE && (!needcert || p->cert != NULL)) return 1; tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } static tqsl_cert * tqsl_cert_new() { tqsl_cert *p; p = (tqsl_cert *)tqsl_calloc(1, sizeof(tqsl_cert)); if (p != NULL) p->id = 0xCE; return p; } static void tqsl_cert_free(tqsl_cert *p) { if (p == NULL || p->id != 0xCE) return; p->id = 0; if (p->cert != NULL) X509_free(p->cert); if (p->key != NULL) EVP_PKEY_free(p->key); if (p->crq != NULL) tqsl_free_cert_req(p->crq, 0); if (p->pubkey != NULL) delete[] p->pubkey; if (p->privkey != NULL) delete[] p->privkey; tqsl_free(p); } static TQSL_CERT_REQ * tqsl_free_cert_req(TQSL_CERT_REQ *req, int seterr) { if (req == NULL) return NULL; tqsl_free(req); if (seterr) tQSL_Error = seterr; return NULL; } static TQSL_CERT_REQ * tqsl_copy_cert_req(TQSL_CERT_REQ *userreq) { TQSL_CERT_REQ *req; if ((req = (TQSL_CERT_REQ *)tqsl_calloc(1, sizeof (TQSL_CERT_REQ))) == NULL) { errno = ENOMEM; return NULL; } *req = *userreq; return req; } static int tqsl_check_parm(const char *p, const char *parmName) { if (strlen(p) == 0) { tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, "Missing parameter: ", sizeof tQSL_CustomError); strncat(tQSL_CustomError, parmName, sizeof tQSL_CustomError - strlen(tQSL_CustomError)-1); return 1; } return 0; } static char * tqsl_trim(char *buf) { char lastc; char *cp, *op; /* Trim white space off end of string */ cp = buf + strlen(buf); while (cp != buf) { cp--; if (!isspace(*cp)) break; *cp = 0; } /* Skip past leading whitespace */ for (cp = buf; isspace(*cp); cp++) ; /* Fold runs of white space into single space */ lastc = 0; op = buf; for (; *cp != '\0'; cp++) { if (isspace(*cp)) *cp = ' '; if (*cp != ' ' || lastc != ' ') *op++ = *cp; lastc = *cp; } *op = '\0'; return cp; } /* Filter a list (stack) of X509 certs based on call sign, QSO date and/or * issuer. * * Returns a new stack of matching certs without altering the original stack. * * Note that you don't have to supply any of the criteria. If you supply * none, you;ll just get back an exact copy of the stack. */ CLIENT_STATIC STACK_OF(X509) * tqsl_filter_cert_list(STACK_OF(X509) *sk, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flags) { set superceded_certs; const char *cp; char buf[256], name_buf[256]; TQSL_X509_NAME_ITEM item; X509 *x; STACK_OF(X509) *newsk; int i, ok, len; tQSL_Date qso_date; if (tqsl_init()) return NULL; if ((newsk = sk_X509_new_null()) == NULL) return NULL; if (!(flags & TQSL_SELECT_CERT_SUPERCEDED)) { /* Make a list of superceded certs */ for (i = 0; i < sk_X509_num(sk); i++) { x = sk_X509_value(sk, i); len = sizeof buf-1; if (!tqsl_get_cert_ext(x, "supercededCertificate", (unsigned char *)buf, &len, NULL)) { buf[len] = 0; string sup = buf; superceded_certs.insert(sup); /* Fix - the extension as inserted by ARRL * reads ".../Email=lotw@arrl.org", not * the expected ".../emailAddress=". * save both forms in case this gets * changed at the LoTW site */ size_t pos = sup.find("/Email"); if (pos != string::npos) { sup.replace(pos, 6, "/emailAddress"); superceded_certs.insert(sup); } } } } /* Loop through the list of certs */ for (i = 0; i < sk_X509_num(sk); i++) { ok = 1; /* Certificate is selected unless some check says otherwise */ x = sk_X509_value(sk, i); /* Check for expired unless asked not to */ if (ok && !(flags & TQSL_SELECT_CERT_EXPIRED)) { time_t t = time(0); struct tm *tm = gmtime(&t); tQSL_Date d; d.year = tm->tm_year + 1900; d.month = tm->tm_mon + 1; d.day = tm->tm_mday; ASN1_TIME *ctm; if ((ctm = X509_get_notAfter(x)) == NULL) { ok = 0; } else { tQSL_Date cert_na; tqsl_get_asn1_date(ctm, &cert_na); if (tqsl_compareDates(&cert_na, &d) < 0) ok = 0; } } /* Check for superceded unless asked not to */ if (ok && !(flags & TQSL_SELECT_CERT_SUPERCEDED)) { // "supercededCertificate" extension is ; cp = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof(buf)); if (cp == NULL) ok = 0; else { string sup = buf; sup += ";"; snprintf(buf, sizeof buf, "%ld", ASN1_INTEGER_get(X509_get_serialNumber(x))); sup += buf; set::iterator it; for (it = superceded_certs.begin(); it != superceded_certs.end(); it++) { if (*it == sup) ok = 0; } if (superceded_certs.find(sup) != superceded_certs.end()) ok = 0; } } /* Compare issuer if asked to */ if (ok && issuer != NULL) { X509_NAME *iss; if ((iss = X509_get_issuer_name(x)) == NULL) ok = 0; if (ok) { item.name_buf = name_buf; item.name_buf_size = sizeof name_buf; item.value_buf = buf; item.value_buf_size = sizeof buf; tqsl_get_name_entry(iss, "organizationName", &item); ok = !strcmp(issuer->organizationName, item.value_buf); } if (ok) { item.name_buf = name_buf; item.name_buf_size = sizeof name_buf; item.value_buf = buf; item.value_buf_size = sizeof buf; tqsl_get_name_entry(iss, "organizationalUnitName", &item); ok = !strcmp(issuer->organizationalUnitName, item.value_buf); } } /* Check call sign if asked */ if (ok && callsign != NULL) { item.name_buf = name_buf; item.name_buf_size = sizeof name_buf; item.value_buf = buf; item.value_buf_size = sizeof buf; if (!tqsl_cert_get_subject_name_entry(x, "AROcallsign", &item)) ok = 0; else ok = !strcmp(callsign, item.value_buf); } /* Check DXCC entity if asked */ if (ok && dxcc > 0) { len = sizeof buf-1; if (tqsl_get_cert_ext(x, "dxccEntity", (unsigned char *)buf, &len, NULL)) ok = 0; else { buf[len] = 0; if (dxcc != strtol(buf, NULL, 10)) ok = 0; } } /* Check QSO date if asked */ if (ok && date != NULL && !tqsl_isDateNull(date)) { len = sizeof buf-1; if (tqsl_get_cert_ext(x, "QSONotBeforeDate", (unsigned char *)buf, &len, NULL)) ok = 0; else if (tqsl_initDate(&qso_date, buf)) ok = 0; else if (tqsl_compareDates(date, &qso_date) < 0) ok = 0; } if (ok && date != NULL && !tqsl_isDateNull(date)) { len = sizeof buf-1; if (tqsl_get_cert_ext(x, "QSONotAfterDate", (unsigned char *)buf, &len, NULL)) ok = 0; else if (tqsl_initDate(&qso_date, buf)) ok = 0; else if (tqsl_compareDates(date, &qso_date) > 0) ok = 0; } /* If no check failed, copy this cert onto the new stack */ if (ok) sk_X509_push(newsk, X509_dup(x)); } return newsk; } /* Set up a read-only BIO from the given file and pass to * tqsl_ssl_load_certs_from_BIO. */ CLIENT_STATIC STACK_OF(X509) * tqsl_ssl_load_certs_from_file(const char *filename) { BIO *in; STACK_OF(X509) *sk; FILE *cfile; if ((cfile = fopen(filename, "r")) == NULL) { strncpy(tQSL_ErrorFile, filename, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return NULL; } if ((in = BIO_new_fp(cfile, 0)) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return NULL; } sk = tqsl_ssl_load_certs_from_BIO(in); BIO_free(in); fclose(cfile); return sk; } /* Load a set of certs from a file into a stack. The file may contain * other X509 objects (e.g., CRLs), but we'll ignore those. * * Return NULL if there are no certs in the file or on error. */ CLIENT_STATIC STACK_OF(X509) * tqsl_ssl_load_certs_from_BIO(BIO *in) { STACK_OF(X509_INFO) *sk = NULL; STACK_OF(X509) *stack = NULL; X509_INFO *xi; if (tqsl_init()) return NULL; if (!(stack = sk_X509_new_null())) { tQSL_Error = TQSL_OPENSSL_ERROR; return NULL; } if (!(sk = PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) { sk_X509_free(stack); tQSL_Error = TQSL_OPENSSL_ERROR; return NULL; } /* Extract the certs from the X509_INFO objects and put them on a stack */ while (sk_X509_INFO_num(sk)) { xi=sk_X509_INFO_shift(sk); if (xi->x509 != NULL) { sk_X509_push(stack,xi->x509); xi->x509 = NULL; } X509_INFO_free(xi); } /* Empty file isn't really an error, is it? if(!sk_X509_num(stack)) { sk_X509_free(stack); stack = NULL; strcpy(tQSL_CustomError, "No certificates found"); tQSL_Error = TQSL_CUSTOM_ERROR; } */ sk_X509_INFO_free(sk); return stack; } /* Chain-verify a cert against a set of CA and a set of trusted root certs. * * Returns NULL if cert verifies, an error message if it does not. */ CLIENT_STATIC const char * tqsl_ssl_verify_cert(X509 *cert, STACK_OF(X509) *cacerts, STACK_OF(X509) *rootcerts, int purpose, int (*cb)(int ok, X509_STORE_CTX *ctx), STACK_OF(X509) **chain) { X509_STORE *store; X509_STORE_CTX *ctx; int rval; const char *errm; if (cert == NULL) return "No certificate to verify"; if (tqsl_init()) return NULL; store = X509_STORE_new(); if (store == NULL) return "Out of memory"; if (cb != NULL) X509_STORE_set_verify_cb_func(store,cb); ctx = X509_STORE_CTX_new(); if (ctx == NULL) { X509_STORE_free(store); return "Out of memory"; } X509_STORE_CTX_init(ctx, store, cert, cacerts); if (cb != NULL) X509_STORE_CTX_set_verify_cb(ctx,cb); if (rootcerts) X509_STORE_CTX_trusted_stack(ctx, rootcerts); if (purpose >= 0) X509_STORE_CTX_set_purpose(ctx, purpose); X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_CB_ISSUER_CHECK); rval = X509_verify_cert(ctx); errm = X509_verify_cert_error_string(ctx->error); if (chain) { if (rval && ctx->chain) *chain = sk_X509_dup(ctx->chain); else *chain = 0; } X509_STORE_CTX_free(ctx); if (rval) return NULL; if (errm != NULL) return errm; return "Verification failed"; } /* [static] - Grab the data from an X509_NAME_ENTRY and put it into * a TQSL_X509_NAME_ITEM object, checking buffer sizes. * * Returns 0 on error, 1 if okay. * * It's okay for the name_buf or value_buf item of the object to * be NULL; it'll just be skipped. */ static int tqsl_get_name_stuff(X509_NAME_ENTRY *entry, TQSL_X509_NAME_ITEM *name_item) { ASN1_OBJECT *obj; ASN1_STRING *value; const char *val; unsigned int len; if (entry == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } obj = X509_NAME_ENTRY_get_object(entry); if (obj == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 0; } if (name_item->name_buf != NULL) { len = i2t_ASN1_OBJECT(name_item->name_buf, name_item->name_buf_size, obj); if (len <= 0 || len > strlen(name_item->name_buf)) { tQSL_Error = TQSL_OPENSSL_ERROR; return 0; } } if (name_item->value_buf != NULL) { value = X509_NAME_ENTRY_get_data(entry); val = (const char *)ASN1_STRING_data(value); strncpy(name_item->value_buf, val, name_item->value_buf_size); name_item->value_buf[name_item->value_buf_size-1] = '\0'; if (strlen(val) > strlen(name_item->value_buf)) { tQSL_Error = TQSL_OPENSSL_ERROR; return 0; } } return 1; } #if 0 /* unused */ /* Get a name entry from an X509_NAME by its index. */ CLIENT_STATIC int tqsl_get_name_index(X509_NAME *name, int index, TQSL_X509_NAME_ITEM *name_item) { X509_NAME_ENTRY *entry; int num_entries; if (tqsl_init()) return 0; if (name == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } num_entries = X509_NAME_entry_count(name); if (num_entries <= 0 || index >= num_entries) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } entry = X509_NAME_get_entry(name, index); return tqsl_get_name_stuff(entry, name_item); } #endif /* Get a name entry from an X509_NAME by its name. */ CLIENT_STATIC int tqsl_get_name_entry(X509_NAME *name, const char *obj_name, TQSL_X509_NAME_ITEM *name_item) { X509_NAME_ENTRY *entry; int num_entries, i; if (tqsl_init()) return 0; num_entries = X509_NAME_entry_count(name); if (num_entries <= 0) return 0; /* Loop through the name entries */ for (i = 0; i < num_entries; i++) { entry = X509_NAME_get_entry(name, i); if (!tqsl_get_name_stuff(entry, name_item)) continue; if (name_item->name_buf != NULL && !strcmp(name_item->name_buf, obj_name)) { /* Found the wanted entry */ return 1; } } return 0; } #if 0 /* unused */ /* Get the number of name entries in an X509_NAME */ CLIENT_STATIC int tqsl_get_name_count(X509_NAME *name) { if (name == NULL) return 0; return X509_NAME_entry_count(name); } /* Get the number of name entries in the cert's subject DN */ CLIENT_STATIC int tqsl_cert_get_subject_name_count(X509 *cert) { if (cert == NULL) return 0; return tqsl_get_name_count(X509_get_subject_name(cert)); } /* Get a name entry from a cert's subject name by its index. */ CLIENT_STATIC int tqsl_cert_get_subject_name_index(X509 *cert, int index, TQSL_X509_NAME_ITEM *name_item) { if (cert == NULL) return 0; if (tqsl_init()) return 0; return tqsl_get_name_index(X509_get_subject_name(cert), index, name_item); } #endif /* Get a name entry from a cert's subject name by its name. */ CLIENT_STATIC int tqsl_cert_get_subject_name_entry(X509 *cert, const char *obj_name, TQSL_X509_NAME_ITEM *name_item) { X509_NAME *name; if (cert == NULL) return 0; if (tqsl_init()) return 0; if ((name = X509_get_subject_name(cert)) == NULL) return 0; return tqsl_get_name_entry(name, obj_name, name_item); } #if 0 /* unused */ /* Get a date entry from a cert's subject DN into a tQSL_Date object. */ CLIENT_STATIC int tqsl_cert_get_subject_date(X509 *cert, const char *obj_name, tQSL_Date *date) { char buf[256], name_buf[256]; TQSL_X509_NAME_ITEM item; if (tqsl_init()) return 0; item.name_buf = name_buf; item.name_buf_size = sizeof name_buf; item.value_buf = buf; item.value_buf_size = sizeof buf; if (!tqsl_cert_get_subject_name_entry(cert, obj_name, &item)) return 0; return !tqsl_initDate(date, buf); } #endif /* Initialize the tQSL (really OpenSSL) random number generator * Return 0 on error. */ CLIENT_STATIC int tqsl_init_random() { char fname[256]; static int initialized = 0; if (initialized) return 1; if (RAND_file_name(fname, sizeof fname) != NULL) RAND_load_file(fname, -1); initialized = RAND_status(); if (!initialized) tQSL_Error = TQSL_RANDOM_ERROR; return initialized; } /* Generate an RSA key of at least 1024 bits length */ CLIENT_STATIC EVP_PKEY * tqsl_new_rsa_key(int nbits) { EVP_PKEY *pkey; if (nbits < 1024) { tQSL_Error = TQSL_ARGUMENT_ERROR; return NULL; } if ((pkey = EVP_PKEY_new()) == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return NULL; } if (!tqsl_init_random()) /* Unable to init RN generator */ return NULL; if (!EVP_PKEY_assign_RSA(pkey, RSA_generate_key(nbits, 0x10001, NULL, NULL))) { EVP_PKEY_free(pkey); tQSL_Error = TQSL_OPENSSL_ERROR; return NULL; } return pkey; } /* Output an ADIF field to a file descriptor. */ CLIENT_STATIC int tqsl_write_adif_field(FILE *fp, const char *fieldname, char type, const unsigned char *value, int len) { if (fieldname == NULL) /* Silly caller */ return 0; if (fputc('<', fp) == EOF) return 1; if (fputs(fieldname, fp) == EOF) return 1; if (type && type != ' ' && type != '\0') { if (fputc(':', fp) == EOF) return 1; if (fputc(type, fp) == EOF) return 1; } if (value != NULL && len != 0) { if (len < 0) len = strlen((const char *)value); if (fputc(':', fp) == EOF) return 1; fprintf(fp, "%d>", len); if (fwrite(value, 1, len, fp) != (unsigned int) len) return 1; } else if (fputc('>', fp) == EOF) return 1; if (fputs("\n\n", fp) == EOF) return 1; return 0; } /* Output an ADIF field to a BIO */ CLIENT_STATIC int tqsl_bio_write_adif_field(BIO *bio, const char *fieldname, char type, const unsigned char *value, int len) { int bret; if (fieldname == NULL) /* Silly caller */ return 0; if ((bret = BIO_write(bio, "<", 1)) <= 0) return 1; if ((bret = BIO_write(bio, fieldname, strlen(fieldname))) <= 0) return 1; if (type && type != ' ' && type != '\0') { if ((bret = BIO_write(bio, ":", 1)) <= 0) return 1; if ((bret = BIO_write(bio, &type, 1)) <= 0) return 1; } if (value != NULL && len != 0) { if (len < 0) len = strlen((const char *)value); if ((bret = BIO_write(bio, ":", 1)) <= 0) return 1; char numbuf[20]; snprintf(numbuf, sizeof numbuf, "%d>", len); if ((bret = BIO_write(bio, numbuf, strlen(numbuf))) <= 0) return 1; if ((bret = BIO_write(bio, value, len)) != len) return 1; } else if ((bret = BIO_write(bio, ">", 1)) <= 0) return 1; if ((bret = BIO_write(bio, "\n\n", 2)) <= 0) return 1; return 0; } static int tqsl_self_signed_is_ok(int ok, X509_STORE_CTX *ctx) { if (ctx->error == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) return 1; if (ctx->error == X509_V_ERR_CERT_UNTRUSTED) return 1; return ok; } static int tqsl_expired_is_ok(int ok, X509_STORE_CTX *ctx) { if (ctx->error == X509_V_ERR_CERT_HAS_EXPIRED || ctx->error == X509_V_ERR_CERT_UNTRUSTED) return 1; return ok; } static char * tqsl_make_cert_path(const char *filename, char *path, int size) { strncpy(path, tQSL_BaseDir, size); #ifdef _WIN32 strncat(path, "\\certs", size - strlen(path)); #else strncat(path, "/certs", size - strlen(path)); #endif if (MKDIR(path, 0700) && errno != EEXIST) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return NULL; } #ifdef _WIN32 strncat(path, "\\", size - strlen(path)); #else strncat(path, "/", size - strlen(path)); #endif strncat(path, filename, size - strlen(path)); return path; } static int tqsl_clean_call(const char *callsign, char *buf, int size) { if ((int)strlen(callsign) > size-1) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } const char *cp; for (cp = callsign; *cp; cp++) { if (!isdigit(*cp) && !isalpha(*cp)) *buf = '_'; else *buf = *cp; ++buf; } *buf = 0; return 0; } static char * tqsl_make_key_path(const char *callsign, char *path, int size) { char fixcall[256]; tqsl_clean_call(callsign, fixcall, sizeof fixcall); strncpy(path, tQSL_BaseDir, size); #ifdef _WIN32 strncat(path, "\\keys", size - strlen(path)); #else strncat(path, "/keys", size - strlen(path)); #endif if (MKDIR(path, 0700) && errno != EEXIST) { strncpy(tQSL_ErrorFile, path, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return 0; } #ifdef _WIN32 strncat(path, "\\", size - strlen(path)); #else strncat(path, "/", size - strlen(path)); #endif strncat(path, fixcall, size - strlen(path)); return path; } static int tqsl_handle_root_cert(const char *pem, X509 *x, int (*cb)(int, const char *, void *), void *userdata) { const char *cp; /* Verify self-signature on the root certificate */ if ((cp = tqsl_ssl_verify_cert(x, NULL, NULL, 0, &tqsl_self_signed_is_ok)) != NULL) { strncpy(tQSL_CustomError, cp, sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; return 1; } return tqsl_store_cert(pem, x, "root", TQSL_CERT_CB_ROOT, false, cb, userdata); } static int tqsl_ssl_error_is_nofile() { unsigned long l = ERR_peek_error(); if (tQSL_Error == TQSL_OPENSSL_ERROR && ERR_GET_LIB(l) == ERR_LIB_SYS && ERR_GET_FUNC(l) == SYS_F_FOPEN) return 1; if (tQSL_Error == TQSL_SYSTEM_ERROR && tQSL_Errno == ENOENT) return 1; return 0; } static int tqsl_handle_ca_cert(const char *pem, X509 *x, int (*cb)(int, const char *, void *), void *userdata) { STACK_OF(X509) *root_sk; char rootpath[256]; const char *cp; tqsl_make_cert_path("root", rootpath, sizeof rootpath); if ((root_sk = tqsl_ssl_load_certs_from_file(rootpath)) == NULL) { if (!tqsl_ssl_error_is_nofile()) return 1; } cp = tqsl_ssl_verify_cert(x, NULL, root_sk, 0, &tqsl_expired_is_ok); sk_X509_free(root_sk); if (cp) { strncpy(tQSL_CustomError, cp, sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; return 1; } return tqsl_store_cert(pem, x, "authorities", TQSL_CERT_CB_CA, false, cb, userdata); } static int tqsl_handle_user_cert(const char *cpem, X509 *x, int (*cb)(int, const char *, void *), void *userdata) { STACK_OF(X509) *root_sk, *ca_sk; char rootpath[256], capath[256]; char pem[sizeof tqsl_static_buf]; const char *cp; strncpy(pem, cpem, sizeof pem); /* Match the public key in the supplied certificate with a * private key in the key store. */ if (!tqsl_find_matching_key(x, NULL, NULL, "", NULL, NULL)) { if (tQSL_Error != TQSL_PASSWORD_ERROR) return 1; tQSL_Error = TQSL_NO_ERROR; /* clear error */ } /* Check the chain of authority back to a trusted root */ tqsl_make_cert_path("root", rootpath, sizeof rootpath); if ((root_sk = tqsl_ssl_load_certs_from_file(rootpath)) == NULL) { if (!tqsl_ssl_error_is_nofile()) return 1; } tqsl_make_cert_path("authorities", capath, sizeof capath); if ((ca_sk = tqsl_ssl_load_certs_from_file(capath)) == NULL) { if (!tqsl_ssl_error_is_nofile()) { sk_X509_free(root_sk); return 1; } } cp = tqsl_ssl_verify_cert(x, ca_sk, root_sk, 0, &tqsl_expired_is_ok); sk_X509_free(ca_sk); sk_X509_free(root_sk); if (cp) { strncpy(tQSL_CustomError, cp, sizeof tQSL_CustomError); tQSL_Error = TQSL_CUSTOM_ERROR; return 1; } return tqsl_store_cert(pem, x, "user", TQSL_CERT_CB_USER, false, cb, userdata); } CLIENT_STATIC int tqsl_store_cert(const char *pem, X509 *cert, const char *certfile, int type, bool force, int (*cb)(int, const char *, void *), void *userdata) { STACK_OF(X509) *sk; char path[256]; char issuer[256]; char name[256]; char value[256]; FILE *out; BIGNUM *bserial, *oldserial; string subjid, msg, callsign; TQSL_X509_NAME_ITEM item; int len, rval; tQSL_Date newExpires; string stype = "Unknown"; ASN1_TIME *tm; if (type == TQSL_CERT_CB_ROOT) stype = "Trusted Root Authority"; else if (type == TQSL_CERT_CB_CA) stype = "Certificate Authority"; else if (type == TQSL_CERT_CB_USER) stype = "Callsign"; tqsl_make_cert_path(certfile, path, sizeof path); item.name_buf = name; item.name_buf_size = sizeof name; item.value_buf = value; item.value_buf_size = sizeof value; if (tqsl_cert_get_subject_name_entry(cert, "AROcallsign", &item)) { // Subject contains a call sign (probably a user cert) callsign = value; strncpy(tQSL_ImportCall, callsign.c_str(), sizeof(tQSL_ImportCall)); subjid = string(" ") + value; tm = X509_get_notAfter(cert); if (tm) tqsl_get_asn1_date(tm, &newExpires); else { newExpires.year = 9999; newExpires.month = 1; newExpires.day = 1; } if (tqsl_cert_get_subject_name_entry(cert, "commonName", &item)) subjid += string(" (") + value + ")"; len = sizeof value-1; if (!tqsl_get_cert_ext(cert, "dxccEntity", (unsigned char *)value, &len, NULL)) { value[len] = 0; subjid += string(" DXCC = ") + value; } } else if (tqsl_cert_get_subject_name_entry(cert, "organizationName", &item)) { // Subject contains an organization (probably a CA or root CA cert) subjid = string(" ") + value; if (tqsl_cert_get_subject_name_entry(cert, "organizationalUnitName", &item)) subjid += string(" ") + value; } if (subjid == "") { // If haven't found a displayable subject name we undertand, use the raw DN X509_NAME_oneline(X509_get_subject_name(cert), issuer, sizeof issuer); subjid = string(" ") + issuer; } X509_NAME_oneline(X509_get_issuer_name(cert), issuer, sizeof issuer); /* Check for dupes */ if ((sk = tqsl_ssl_load_certs_from_file(path)) == NULL) { if (!tqsl_ssl_error_is_nofile()) return 1; /* Unexpected OpenSSL error */ } /* Check each certificate */ if (sk != NULL) { int i, n; tQSL_Date expires; bserial = BN_new(); ASN1_INTEGER_to_BN(X509_get_serialNumber(cert), bserial); n = sk_X509_num(sk); for (i = 0; i < n; i++) { char buf[256]; X509 *x; const char *cp; x = sk_X509_value(sk, i); cp = X509_NAME_oneline(X509_get_issuer_name(x), buf, sizeof buf); if (cp != NULL && !strcmp(cp, issuer)) { oldserial = BN_new(); ASN1_INTEGER_to_BN(X509_get_serialNumber(x), oldserial); int result = BN_ucmp(bserial, oldserial); BN_free(oldserial); if (result == 0) break; /* We have a match */ } if (!force && type == TQSL_CERT_CB_USER) { // Don't check for newer certs on restore item.name_buf = name; item.name_buf_size = sizeof name; item.value_buf = value; item.value_buf_size = sizeof value; if (tqsl_cert_get_subject_name_entry(x, "AROcallsign", &item)) { if (value == callsign) { /* * If it's another cert for * this call, is it older? */ tm = X509_get_notAfter(x); if (tm) tqsl_get_asn1_date(tm, &expires); else { expires.year = 0; expires.month = 0; expires.day = 0; } if (tqsl_compareDates(&newExpires, &expires) < 0) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "A newer certificate for this callsign is already installed"); BN_free(bserial); sk_X509_free(sk); return 1; } } } } } BN_free(bserial); sk_X509_free(sk); if (i < n) { /* Have a match -- cert is already in the file */ if (cb != NULL) { int rval; string msg = "Duplicate " + stype + " certificate: " + subjid; rval = (*cb)(TQSL_CERT_CB_RESULT | type | TQSL_CERT_CB_DUPLICATE, msg.c_str(), userdata); if (rval) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "Duplicate Callsign certificate"); return 1; } } return 0; } } /* Cert is not a duplicate. Append it to the certificate file */ if (cb != NULL) { msg = "Adding " + stype + " Certificate for: " + subjid; rval = (*cb)(TQSL_CERT_CB_MILESTONE | type | TQSL_CERT_CB_PROMPT, msg.c_str(), userdata); if (rval) { tQSL_Error = TQSL_OPERATOR_ABORT; return 1; } } if ((out = fopen(path, "a")) == NULL) { strncpy(tQSL_ErrorFile, path, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return 1; } fwrite(pem, 1, strlen(pem), out); if (fclose(out) == EOF) { strncpy(tQSL_ErrorFile, certfile, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return 1; } msg = "Loaded: " + subjid; if (cb) rval = (*cb)(TQSL_CERT_CB_RESULT | type | TQSL_CERT_CB_LOADED, msg.c_str(), userdata); else rval = 0; if (rval) { tQSL_Error = TQSL_OPERATOR_ABORT; return 1; } return 0; } static int pw_aborted; static int fixed_password_callback(char *buf, int bufsiz, int verify, void *userdata) { pw_aborted = 0; if (userdata != NULL) strncpy(buf, (char *)userdata, bufsiz); else buf[0] = 0; return strlen(buf); } static void *prompt_userdata; static int prompted_password_callback(char *buf, int bufsiz, int verify, void *userfunc) { pw_aborted = 0; if (userfunc != NULL) { int (*cb)(char *, int, void *) = (int (*)(char *, int, void *))userfunc; if ((*cb)(buf, bufsiz, prompt_userdata)) { pw_aborted = 1; return 0; } } else buf[0] = 0; return strlen(buf); } static tQSL_ADIF keyf_adif = 0; static int tqsl_open_key_file(const char *path) { if (keyf_adif) tqsl_endADIF(&keyf_adif); return tqsl_beginADIF(&keyf_adif, path); } static int tqsl_read_key(map& fields) { TQSL_ADIF_GET_FIELD_ERROR adif_status; tqsl_adifFieldResults field; static tqsl_adifFieldDefinitions adif_fields[] = { { "PUBLIC_KEY", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "PRIVATE_KEY", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "CALLSIGN", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_PROVIDER", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_PROVIDER_UNIT", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_ADDRESS1", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_ADDRESS2", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_CITY", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_STATE", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_POSTAL", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_COUNTRY", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_DXCC_ENTITY", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_QSO_NOT_BEFORE", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "TQSL_CRQ_QSO_NOT_AFTER", "", TQSL_ADIF_RANGE_TYPE_NONE, 2000, 0, 0, NULL, NULL }, { "eor", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, NULL, NULL }, { "", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, NULL, NULL }, }; fields.clear(); do { if (tqsl_getADIFField(keyf_adif, &field, &adif_status, adif_fields, notypes, &tqsl_static_alloc)) return 1; if (adif_status == TQSL_ADIF_GET_FIELD_EOF) return 1; if (!strcasecmp(field.name, "eor")) return 0; if (adif_status == TQSL_ADIF_GET_FIELD_SUCCESS) { char *cp; for (cp = field.name; *cp; cp++) *cp = toupper(*cp); fields[field.name] = (char *)field.data; } } while (adif_status == TQSL_ADIF_GET_FIELD_SUCCESS || adif_status == TQSL_ADIF_GET_FIELD_NO_NAME_MATCH); tQSL_Error = TQSL_ADIF_ERROR; return 1; } static void tqsl_close_key_file(void) { tqsl_endADIF(&keyf_adif); } static int tqsl_replace_key(const char *callsign, const char *path, map& newfields, int (*cb)(int, const char *, void *), void *userdata) { char newpath[300]; char savepath[300]; map fields; vector< map > records; vector< map >::iterator it; EVP_PKEY *new_key = 0; BIO *bio = 0; RSA *new_rsa = 0, *rsa = 0; FILE *out = 0; int rval = 1; if ((bio = BIO_new_mem_buf((void *)(newfields["PUBLIC_KEY"].c_str()), newfields["PUBLIC_KEY"].length())) == NULL) goto trk_end; if ((new_rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) goto trk_end; BIO_free(bio); bio = 0; if (tqsl_open_key_file(path)) { if (tQSL_Error != TQSL_SYSTEM_ERROR || tQSL_Errno != ENOENT) return 1; tQSL_Error = TQSL_NO_ERROR; } while (tqsl_read_key(fields) == 0) { if ((bio = BIO_new_mem_buf((void *)(fields["PUBLIC_KEY"].c_str()), fields["PUBLIC_KEY"].length())) == NULL) goto trk_end; if ((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) goto trk_end; BIO_free(bio); bio = 0; if (BN_cmp(rsa->n, new_rsa->n) == 0) if (BN_cmp(rsa->e, new_rsa->e) == 0) continue; // Skip record with matching public key records.push_back(fields); } tqsl_close_key_file(); if (tQSL_Error != TQSL_NO_ERROR) goto trk_end; if (newfields["PRIVATE_KEY"] != "") records.push_back(newfields); strcpy(newpath, path); strncat(newpath, ".new", sizeof newpath - strlen(newpath)-1); strcpy(savepath, path); strncat(savepath, ".save", sizeof savepath - strlen(savepath)-1); if ((out = fopen(newpath, TQSL_OPEN_WRITE)) == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto trk_end; } for (it = records.begin(); it != records.end(); it++) { map::iterator mit; for (mit = it->begin(); mit != it->end(); mit++) { if (tqsl_write_adif_field(out, mit->first.c_str(), 0, (const unsigned char *)mit->second.c_str(), -1)) goto trk_end; } tqsl_write_adif_field(out, "eor", 0, NULL, 0); } if (fclose(out) == EOF) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto trk_end; } out = 0; /* Output file looks okay. Replace the old file with the new one. */ if (unlink(savepath) && errno != ENOENT) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto trk_end; } if (rename(path, savepath) && errno != ENOENT) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto trk_end; } if (rename(newpath, path)) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto trk_end; } if (cb) { string msg = string("Loaded private key for: ") + callsign; (*cb)(TQSL_CERT_CB_RESULT + TQSL_CERT_CB_PKEY + TQSL_CERT_CB_LOADED, msg.c_str(), userdata); } rval = 0; trk_end: tqsl_close_key_file(); if (out) fclose(out); if (new_key) EVP_PKEY_free(new_key); if (bio) BIO_free(bio); if (new_rsa) RSA_free(new_rsa); if (rsa) RSA_free(rsa); return rval; } static int tqsl_unlock_key(const char *pem, EVP_PKEY **keyp, const char *password, int (*cb)(char *,int, void *), void *userdata) { RSA *prsa = NULL; BIO *bio; int (*ssl_cb)(char *, int, int, void *) = NULL; void *cb_user = NULL; long e; int rval = 1; if ((bio = BIO_new_mem_buf((void *)pem, strlen(pem))) == NULL) goto err; if (password != NULL) { ssl_cb = &fixed_password_callback; cb_user = (void *)password; } else if (cb != NULL) { prompt_userdata = userdata; ssl_cb = &prompted_password_callback; cb_user = (void *)cb; } if ((prsa = PEM_read_bio_RSAPrivateKey(bio, NULL, ssl_cb, cb_user)) == NULL) goto err; if (keyp != NULL) { if ((*keyp = EVP_PKEY_new()) == NULL) goto err; EVP_PKEY_assign_RSA(*keyp, prsa); prsa = NULL; } rval = 0; goto end; err: e = ERR_peek_error(); if ((ERR_GET_LIB(e) == ERR_LIB_EVP && ERR_GET_REASON(e) == EVP_R_BAD_DECRYPT) || (ERR_GET_LIB(e) == ERR_LIB_PEM && ERR_GET_REASON(e) == PEM_R_BAD_PASSWORD_READ)) { tqsl_getErrorString(); /* clear error */ tQSL_Error = pw_aborted ? TQSL_OPERATOR_ABORT : TQSL_PASSWORD_ERROR; ERR_clear_error(); } else tQSL_Error = TQSL_OPENSSL_ERROR; end: if (prsa != NULL) RSA_free(prsa); if (bio != NULL) BIO_free(bio); return rval; } static int tqsl_find_matching_key(X509 *cert, EVP_PKEY **keyp, TQSL_CERT_REQ **crq, const char *password, int (*cb)(char *,int, void *), void *userdata) { char path[256]; char aro[256]; TQSL_X509_NAME_ITEM item = { path, sizeof path, aro, sizeof aro }; EVP_PKEY *cert_key = NULL; RSA *rsa = NULL, *prsa = NULL; int rval = 0; int match = 0; BIO *bio = NULL; map fields; if (keyp != NULL) *keyp = NULL; if (!tqsl_cert_get_subject_name_entry(cert, "AROcallsign", &item)) return rval; strncpy(tQSL_ImportCall, aro, sizeof tQSL_ImportCall); if (!tqsl_make_key_path(aro, path, sizeof path)) goto end_nokey; if (tqsl_open_key_file(path)) { /* Friendly error for file not found */ if (tQSL_Error == TQSL_SYSTEM_ERROR) { if (tQSL_Errno == ENOENT) { snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "You can only open this callsign certificate by running TQSL on the computer where you created the certificate request for %s.", aro); } else { snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Can't open %s: %s\nThis file is needed to open this callsign certificate.", aro, strerror(tQSL_Errno)); } tQSL_Error = TQSL_CUSTOM_ERROR; } return rval; } if ((cert_key = X509_get_pubkey(cert)) == NULL) goto err; if (crq != NULL) { if (*crq != NULL) tqsl_free_cert_req(*crq, 0); *crq = (TQSL_CERT_REQ *)tqsl_calloc(1, sizeof (TQSL_CERT_REQ)); } while (!tqsl_read_key(fields)) { /* Compare the keys */ if ((bio = BIO_new_mem_buf((void *)(fields["PUBLIC_KEY"].c_str()), fields["PUBLIC_KEY"].length())) == NULL) goto err; if ((rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL)) == NULL) goto err; BIO_free(bio); bio = NULL; if (BN_cmp(rsa->n, cert_key->pkey.rsa->n) == 0) if (BN_cmp(rsa->e, cert_key->pkey.rsa->e) == 0) match = 1; if (match) { /* We have a winner */ if (tqsl_unlock_key(fields["PRIVATE_KEY"].c_str(), keyp, password, cb, userdata)) goto end; if (crq != NULL) { tQSL_Error = TQSL_BUFFER_ERROR; if (!safe_strncpy((*crq)->providerName, fields["TQSL_CRQ_PROVIDER"].c_str(), sizeof (*crq)->providerName)) goto end; if (!safe_strncpy((*crq)->providerUnit, fields["TQSL_CRQ_PROVIDER_UNIT"].c_str(), sizeof (*crq)->providerUnit)) goto end; if (!safe_strncpy((*crq)->address1, fields["TQSL_CRQ_ADDRESS1"].c_str(), sizeof (*crq)->address1)) goto end; if (!safe_strncpy((*crq)->address2, fields["TQSL_CRQ_ADDRESS2"].c_str(), sizeof (*crq)->address2)) goto end; if (!safe_strncpy((*crq)->city, fields["TQSL_CRQ_CITY"].c_str(), sizeof (*crq)->city)) goto end; if (!safe_strncpy((*crq)->state, fields["TQSL_CRQ_STATE"].c_str(), sizeof (*crq)->state)) goto end; if (!safe_strncpy((*crq)->postalCode, fields["TQSL_CRQ_POSTAL"].c_str(), sizeof (*crq)->postalCode)) goto end; if (!safe_strncpy((*crq)->country, fields["TQSL_CRQ_COUNTRY"].c_str(), sizeof (*crq)->country)) goto end; tQSL_Error = 0; } rval = 1; break; } } tQSL_Error = TQSL_CERT_NOT_FOUND; goto end; err: tQSL_Error = TQSL_OPENSSL_ERROR; end: tqsl_close_key_file(); end_nokey: if (prsa != NULL) RSA_free(prsa); if (rsa != NULL) RSA_free(rsa); if (bio != NULL) BIO_free(bio); if (cert_key != NULL) EVP_PKEY_free(cert_key); // if (in != NULL) // fclose(in); return rval; } static int tqsl_make_key_list(vector< map > & keys) { keys.clear(); string path = tQSL_BaseDir; #ifdef _WIN32 path += "\\keys"; #else path += "/keys"; #endif MKDIR(path.c_str(), 0700); DIR *dir = opendir(path.c_str()); if (dir == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; return 1; } struct dirent *ent; int rval = 0; while ((ent = readdir(dir)) != NULL) { char fixcall[256]; if (ent->d_name[0] == '.') continue; #ifdef _WIN32 string filename = path + "\\" + ent->d_name; #else string filename = path + "/" + ent->d_name; #endif if (!tqsl_open_key_file(filename.c_str())) { map fields; while (!tqsl_read_key(fields)) { if (tqsl_clean_call(fields["CALLSIGN"].c_str(), fixcall, sizeof fixcall)) { rval = 1; break; } if (strcmp(fixcall, ent->d_name)) continue; keys.push_back(fields); } tqsl_close_key_file(); } } closedir(dir); return rval; } static int tqsl_get_cert_ext(X509 *cert, const char *ext, unsigned char *userbuf, int *buflen, int *crit) { int i, n, datasiz; X509_EXTENSION *xe; char buf[256]; ASN1_OBJECT *obj; ASN1_OCTET_STRING *data; if (tqsl_init()) return 1; if (cert == NULL || ext == NULL || userbuf == NULL || buflen == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } n = X509_get_ext_count(cert); for (i = 0; i < n; i++) { xe = X509_get_ext(cert, i); if (xe == NULL) { tQSL_Error = TQSL_OPENSSL_ERROR; return 1; } buf[0] = '\0'; obj = X509_EXTENSION_get_object(xe); if (obj) OBJ_obj2txt(buf, sizeof buf, obj, 0); if (strcmp(buf, ext)) continue; /* This is the desired extension */ data = X509_EXTENSION_get_data(xe); if (data != NULL) { datasiz = ASN1_STRING_length(data); if (datasiz > *buflen-1) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } *buflen = datasiz; if (datasiz) memcpy(userbuf, ASN1_STRING_data(data), datasiz); userbuf[datasiz] = '\0'; } if (crit != NULL) *crit = X509_EXTENSION_get_critical(xe); return 0; } strncpy(tQSL_CustomError, "Certificate Extension not found: ", sizeof tQSL_CustomError); strncat(tQSL_CustomError + strlen(tQSL_CustomError), ext, (sizeof tQSL_CustomError) - strlen(tQSL_CustomError)); tQSL_Error = TQSL_CUSTOM_ERROR; return 1; } CLIENT_STATIC int tqsl_get_asn1_date(ASN1_TIME *tm, tQSL_Date *date) { char *v; int i; i=tm->length; v=(char *)tm->data; if (i >= 14) { for (i=0; i<12; i++) if ((v[i] > '9') || (v[i] < '0')) goto err; date->year = (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0'); date->month = (v[4]-'0')*10+(v[5]-'0'); if ((date->month > 12) || (date->month < 1)) goto err; date->day = (v[6]-'0')*10+(v[7]-'0'); } else if (i < 12) { goto err; } else { for (i=0; i<10; i++) if ((v[i] > '9') || (v[i] < '0')) goto err; date->year = (v[0]-'0')*10+(v[1]-'0'); if (date->year < 50) date->year+=100; date->year += 1900; date->month = (v[2]-'0')*10+(v[3]-'0'); if ((date->month > 12) || (date->month < 1)) goto err; date->day = (v[4]-'0')*10+(v[5]-'0'); } return 0; err: tQSL_Error = TQSL_INVALID_DATE; return 1; } static char * tqsl_sign_base64_data(tQSL_Cert cert, char *b64data) { int len; static unsigned char sig[256]; int siglen = sizeof sig; if (b64data && !strncmp(b64data, "-----", 5)) { b64data = strchr(b64data, '\n'); if (b64data == NULL) return NULL; b64data++; } len = sizeof tqsl_static_buf; if (tqsl_decodeBase64(b64data, tqsl_static_buf, &len)) return NULL; if (tqsl_signDataBlock(cert, tqsl_static_buf, len, sig, &siglen)) return NULL; if (tqsl_encodeBase64(sig, siglen, (char *)tqsl_static_buf, sizeof tqsl_static_buf)) return NULL; return (char *)tqsl_static_buf; } static bool safe_strncpy(char *dest, const char *src, int size) { strncpy(dest, src, size); dest[size-1] = 0; return ((int)strlen(src) < size); } tqsl-2.0/src/location.h0000664000076400007640000000123412231073120015105 0ustar rmurphyrmurphy/*************************************************************************** location.h - description ------------------- begin : Fri Nov 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __location_h #define __location_h // TQSL_LOCATION_FIELD flag bits #define TQSL_LOCATION_FIELD_UPPER 1 #define TQSL_LOCATION_FIELD_MUSTSEL 2 #define TQSL_LOCATION_FIELD_SELNXT 4 #endif // __location_h tqsl-2.0/src/location.cpp0000664000076400007640000024172512231073120015453 0ustar rmurphyrmurphy/*************************************************************************** location.cpp - description ------------------- begin : Wed Nov 6 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: location.cpp,v 1.14 2013/03/01 13:20:30 k1mu Exp $ ***************************************************************************/ #ifdef __APPLE__ #include #endif #define DXCC_TEST #define TQSLLIB_DEF #include "location.h" #include #include #include #include #include #include "tqsllib.h" #include "tqslerrno.h" #include "xml.h" #include "openssl_cert.h" #ifdef _WIN32 #include "windows.h" #endif #include "winstrdefs.h" #include #include #include #include using namespace std; namespace tqsllib { class TQSL_LOCATION_ITEM { public: TQSL_LOCATION_ITEM() : ivalue(0) {} std::string text; std::string label; std::string zonemap; int ivalue; }; class TQSL_LOCATION_FIELD { public: TQSL_LOCATION_FIELD() {} TQSL_LOCATION_FIELD(string i_gabbi_name, const char *i_label, int i_data_type, int i_data_len, int i_input_type, int i_flags = 0); std::string label; std::string gabbi_name; int data_type; int data_len; std::string cdata; std::vector items; int idx; int idata; int input_type; int flags; bool changed; std::string dependency; }; TQSL_LOCATION_FIELD::TQSL_LOCATION_FIELD(string i_gabbi_name, const char *i_label, int i_data_type, int i_data_len, int i_input_type, int i_flags) : data_type(i_data_type), data_len(i_data_len), cdata(""), input_type(i_input_type), flags(i_flags) { if (!i_gabbi_name.empty()) gabbi_name = i_gabbi_name; if (i_label) label = i_label; idx = idata = 0; } typedef std::vector TQSL_LOCATION_FIELDLIST; class TQSL_LOCATION_PAGE { public: TQSL_LOCATION_PAGE() : complete(false), prev(0), next(0) {} bool complete; int prev, next; string dependentOn, dependency; std::map > hash; TQSL_LOCATION_FIELDLIST fieldlist; }; typedef std::vector TQSL_LOCATION_PAGELIST; class TQSL_NAME { public: TQSL_NAME(string n = "", string c = "") : name(n), call(c) {} std::string name; std::string call; }; class TQSL_LOCATION { public: TQSL_LOCATION() : sentinel(0x5445), page(0), cansave(false), sign_clean(false), cert_flags(TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED), newflags(false) {} ~TQSL_LOCATION() { sentinel = 0; } int sentinel; int page; bool cansave; std::string name; TQSL_LOCATION_PAGELIST pagelist; std::vector names; std::string signdata; bool sign_clean; std::string tSTATION; std::string tCONTACT; std::string sigspec; char data_errors[512]; int cert_flags; bool newflags; }; class Band { public: string name, spectrum; int low, high; }; class Mode { public: string mode, group; }; class PropMode { public: string descrip, name; }; class Satellite { public: Satellite() { start.year = start.month = start.day = 0; end.year = end.month = end.day = 0; } string descrip, name; tQSL_Date start, end; }; bool operator< (const Band& o1, const Band& o2) { static const char *suffixes[] = { "M", "CM", "MM"}; static const char *prefix_chars = "0123456789."; // get suffixes string b1_suf = o1.name.substr(o1.name.find_first_not_of(prefix_chars)); string b2_suf = o2.name.substr(o2.name.find_first_not_of(prefix_chars)); if (b1_suf != b2_suf) { // Suffixes differ -- compare suffixes int b1_idx = (sizeof suffixes / sizeof suffixes[0]); int b2_idx = b1_idx; for (int i = 0; i < int(sizeof suffixes / sizeof suffixes[0]); i++) { if (b1_suf == suffixes[i]) b1_idx = i; if (b2_suf == suffixes[i]) b2_idx = i; } return b1_idx < b2_idx; } return atof(o1.name.c_str()) > atof(o2.name.c_str()); } bool operator< (const PropMode& o1, const PropMode& o2) { if (o1.descrip < o2.descrip) return true; if (o1.descrip == o2.descrip) return (o1.name < o2.name); return false; } bool operator< (const Satellite& o1, const Satellite& o2) { if (o1.descrip < o2.descrip) return true; if (o1.descrip == o2.descrip) return (o1.name < o2.name); return false; } bool operator< (const Mode& o1, const Mode& o2) { static const char *groups[] = { "CW", "PHONE", "IMAGE", "DATA" }; // m1 < m2 if m1 is a modegroup and m2 is not if (o1.mode == o1.group) { if (o2.mode != o2.group) return true; } else if (o2.mode == o2.group) return false; // If groups are same, compare modes if (o1.group == o2.group) return o1.mode < o2.mode; int m1_g = (sizeof groups / sizeof groups[0]); int m2_g = m1_g; for (int i = 0; i < int(sizeof groups / sizeof groups[0]); i++) { if (o1.group == groups[i]) m1_g = i; if (o2.group == groups[i]) m2_g = i; } return m1_g < m2_g; } } // namespace using namespace tqsllib; #define CAST_TQSL_LOCATION(x) ((tqsllib::TQSL_LOCATION *)(x)) typedef map IntMap; // config data static XMLElement tqsl_xml_config; static int tqsl_xml_config_major = -1; static int tqsl_xml_config_minor = 0; static IntMap DXCCMap; static IntMap DXCCZoneMap; static vector< pair > DXCCList; static vector BandList; static vector ModeList; static vector PropModeList; static vector SatelliteList; static map tqsl_page_map; static map tqsl_field_map; static map tqsl_adif_map; static map > tqsl_cabrillo_map; static map > tqsl_cabrillo_user_map; static char char_toupper(char c) { return toupper(c); } static string string_toupper(const string& in) { string out = in; transform(out.begin(), out.end(), out.begin(), char_toupper); return out; } // trim from start static inline std::string <rim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); return s; } // trim from end static inline std::string &rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); return s; } // trim from both ends static inline std::string &trim(std::string &s) { return ltrim(rtrim(s)); } #define TQSL_NPAGES 4 static TQSL_LOCATION * check_loc(tQSL_Location loc, bool unclean = true) { if (tqsl_init()) return 0; if (loc == 0) return 0; if (unclean) CAST_TQSL_LOCATION(loc)->sign_clean = false; return CAST_TQSL_LOCATION(loc); } static int tqsl_load_xml_config() { if (tqsl_xml_config.getElementList().size() > 0) // Already init'd return 0; XMLElement default_config; XMLElement user_config; string default_path; #ifdef _WIN32 HKEY hkey; DWORD dtype; char wpath[TQSL_MAX_PATH_LEN]; DWORD bsize = sizeof wpath; int wval; if ((wval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\TrustedQSL", 0, KEY_READ, &hkey)) == ERROR_SUCCESS) { wval = RegQueryValueEx(hkey, "InstallPath", 0, &dtype, (LPBYTE)wpath, &bsize); RegCloseKey(hkey); if (wval == ERROR_SUCCESS) default_path = string(wpath) + "\\config.xml"; } #elif defined(__APPLE__) // Get path to config.xml resource from bundle CFBundleRef tqslBundle = CFBundleGetMainBundle(); CFURLRef configXMLURL = CFBundleCopyResourceURL(tqslBundle, CFSTR("config"), CFSTR("xml"), NULL); if (configXMLURL) { CFStringRef pathString = CFURLCopyFileSystemPath(configXMLURL, kCFURLPOSIXPathStyle); CFRelease(configXMLURL); // Convert CFString path to config.xml to string object CFIndex maxStringLengthInBytes = CFStringGetMaximumSizeForEncoding(CFStringGetLength(pathString), kCFStringEncodingUTF8); char *pathCString = (char *)malloc(maxStringLengthInBytes); if (pathCString) { CFStringGetCString(pathString, pathCString, maxStringLengthInBytes, kCFStringEncodingASCII); CFRelease(pathString); default_path = string(pathCString); free(pathCString); } } #else default_path = CONFDIR "config.xml"; //KC2YWE: Removed temporarily. There's got to be a better way to do this #endif #ifdef _WIN32 string user_path = string(tQSL_BaseDir) + "\\config.xml"; #else string user_path = string(tQSL_BaseDir) + "/config.xml"; #endif int default_status = default_config.parseFile(default_path.c_str()); int user_status = user_config.parseFile(user_path.c_str()); if (default_status != XML_PARSE_NO_ERROR && user_status != XML_PARSE_NO_ERROR) { if (user_status == XML_PARSE_SYSTEM_ERROR) tQSL_Error = TQSL_CONFIG_ERROR; else tQSL_Error = TQSL_CONFIG_SYNTAX_ERROR; return 1; } int default_major = -1; int default_minor = 0; int user_major = -1; int user_minor = 0; XMLElement top; if (default_config.getFirstElement("tqslconfig", top)) { default_major = strtol(top.getAttribute("majorversion").first.c_str(), NULL, 10); default_minor = strtol(top.getAttribute("minorversion").first.c_str(), NULL, 10); } if (user_config.getFirstElement("tqslconfig", top)) { user_major = strtol(top.getAttribute("majorversion").first.c_str(), NULL, 10); user_minor = strtol(top.getAttribute("minorversion").first.c_str(), NULL, 10); } if (default_major > user_major || (default_major == user_major && default_minor > user_minor)) { tqsl_xml_config = default_config; tqsl_xml_config_major = default_major; tqsl_xml_config_minor = default_minor; return 0; } if (user_major < 0) { tQSL_Error = TQSL_CONFIG_SYNTAX_ERROR; return 1; } tqsl_xml_config = user_config; tqsl_xml_config_major = user_major; tqsl_xml_config_minor = user_minor; return 0; } static int tqsl_get_xml_config_section(const string& section, XMLElement& el) { if (tqsl_load_xml_config()) return 1; XMLElement top; if (!tqsl_xml_config.getFirstElement("tqslconfig", top)) { tqsl_xml_config.clear(); tQSL_Error = TQSL_CONFIG_SYNTAX_ERROR; return 1; } if (!top.getFirstElement(section, el)) { tQSL_Error = TQSL_CONFIG_SYNTAX_ERROR; return 1; } return 0; } static int tqsl_load_provider_list(vector &plist) { plist.clear(); XMLElement providers; if (tqsl_get_xml_config_section("providers", providers)) return 1; XMLElement provider; bool gotit = providers.getFirstElement("provider", provider); while (gotit) { TQSL_PROVIDER pdata; memset(&pdata, 0, sizeof pdata); pair rval = provider.getAttribute("organizationName"); if (!rval.second) { tQSL_Error = TQSL_PROVIDER_NOT_FOUND; return 1; } strncpy(pdata.organizationName, rval.first.c_str(), sizeof pdata.organizationName); XMLElement item; if (provider.getFirstElement("organizationalUnitName", item)) strncpy(pdata.organizationalUnitName, item.getText().c_str(), sizeof pdata.organizationalUnitName); if (provider.getFirstElement("emailAddress", item)) strncpy(pdata.emailAddress, item.getText().c_str(), sizeof pdata.emailAddress); if (provider.getFirstElement("url", item)) strncpy(pdata.url, item.getText().c_str(), sizeof pdata.url); plist.push_back(pdata); gotit = providers.getNextElement(provider); if (gotit && provider.getElementName() != "provider") break; } return 0; } static XMLElement tCONTACT_sign; static int make_sign_data(TQSL_LOCATION *loc) { map field_data; // Loop through the location pages, getting field data // int old_page = loc->page; tqsl_setStationLocationCapturePage(loc, 1); do { TQSL_LOCATION_PAGE& p = loc->pagelist[loc->page-1]; for (int i = 0; i < (int)p.fieldlist.size(); i++) { TQSL_LOCATION_FIELD& f = p.fieldlist[i]; string s; if (f.input_type == TQSL_LOCATION_FIELD_DDLIST || f.input_type == TQSL_LOCATION_FIELD_LIST) { if (f.idx < 0 || f.idx >= (int)f.items.size()) s = ""; else s = f.items[f.idx].text; } else if (f.data_type == TQSL_LOCATION_FIELD_INT) { char buf[20]; snprintf(buf, sizeof buf, "%d", f.idata); s = buf; } else s = f.cdata; field_data[f.gabbi_name] = s; } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; tqsl_nextStationLocationCapture(loc); } while (1); tqsl_setStationLocationCapturePage(loc, old_page); loc->signdata = ""; loc->sign_clean = false; XMLElement sigspecs; if (tqsl_get_xml_config_section("sigspecs", sigspecs)) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - it does not have a sigspecs section"); return 1; } XMLElement sigspec; if (!sigspecs.getFirstElement("sigspec", sigspec)) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - it does not have a sigspec section"); return 1; } loc->sigspec = "SIGN_"; loc->sigspec += sigspec.getAttribute("name").first; loc->sigspec += "_V"; loc->sigspec += sigspec.getAttribute("version").first; tCONTACT_sign.clear(); if (!sigspec.getFirstElement("tCONTACT", tCONTACT_sign)) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - missing sigspec.tCONTACT"); return 1; } if (tCONTACT_sign.getElementList().size() == 0) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - empty sigspec.tCONTACT"); return 1; } XMLElement tSTATION; if (!sigspec.getFirstElement("tSTATION", tSTATION)) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - missing sigspec.tSTATION"); return 1; } XMLElement specfield; bool ok; if (!(ok = tSTATION.getFirstElement(specfield))) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - missing tSTATION.specfield"); return 1; } do { string value = field_data[specfield.getElementName()]; value = trim(value); if (value == "") { pair attr = specfield.getAttribute("required"); if (attr.second && strtol(attr.first.c_str(), NULL, 10)){ string err = specfield.getElementName() + " field required by "; attr = sigspec.getAttribute("name"); if (attr.second) err += attr.first + " "; attr = sigspec.getAttribute("version"); if (attr.second) err += "V" + attr.first + " "; err += "signature specification not found"; tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, err.c_str(), sizeof tQSL_CustomError); return 1; } } else { loc->signdata += value; } ok = tSTATION.getNextElement(specfield); } while (ok); loc->sign_clean = true; return 0; } static int init_dxcc() { if (DXCCMap.size() > 0) return 0; XMLElement dxcc; if (tqsl_get_xml_config_section("dxcc", dxcc)) return 1; XMLElement dxcc_entity; bool ok = dxcc.getFirstElement("entity", dxcc_entity); while (ok) { pair rval = dxcc_entity.getAttribute("arrlId"); pair zval = dxcc_entity.getAttribute("zonemap"); if (rval.second) { int num = strtol(rval.first.c_str(), NULL, 10); DXCCMap[num] = dxcc_entity.getText(); if (zval.second) DXCCZoneMap[num] = zval.first; DXCCList.push_back(make_pair(num, dxcc_entity.getText())); } ok = dxcc.getNextElement(dxcc_entity); } return 0; } static int init_band() { if (BandList.size() > 0) return 0; XMLElement bands; if (tqsl_get_xml_config_section("bands", bands)) return 1; XMLElement config_band; bool ok = bands.getFirstElement("band", config_band); while (ok) { Band b; b.name = config_band.getText(); b.spectrum = config_band.getAttribute("spectrum").first; b.low = strtol(config_band.getAttribute("low").first.c_str(), NULL, 10); b.high = strtol(config_band.getAttribute("high").first.c_str(), NULL, 10); BandList.push_back(b); ok = bands.getNextElement(config_band); } sort(BandList.begin(), BandList.end()); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion(int *major, int *minor) { if (tqsl_init()) return 1; if (tqsl_load_xml_config()) return 1; if (major) *major = tqsl_xml_config_major; if (minor) *minor = tqsl_xml_config_minor; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumBand(int *number) { if (number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_band()) return 1; *number = BandList.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getBand(int index, const char **name, const char **spectrum, int *low, int *high) { if (index < 0 || name == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_band()) return 1; if (index >= (int)BandList.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *name = BandList[index].name.c_str(); if (spectrum) *spectrum = BandList[index].spectrum.c_str(); if (low) *low = BandList[index].low; if (high) *high = BandList[index].high; return 0; } static int init_mode() { if (ModeList.size() > 0) return 0; XMLElement modes; if (tqsl_get_xml_config_section("modes", modes)) return 1; XMLElement config_mode; bool ok = modes.getFirstElement("mode", config_mode); while (ok) { Mode m; m.mode = config_mode.getText(); m.group = config_mode.getAttribute("group").first; ModeList.push_back(m); ok = modes.getNextElement(config_mode); } sort(ModeList.begin(), ModeList.end()); return 0; } static int init_propmode() { if (PropModeList.size() > 0) return 0; XMLElement propmodes; if (tqsl_get_xml_config_section("propmodes", propmodes)) return 1; XMLElement config_mode; bool ok = propmodes.getFirstElement("propmode", config_mode); while (ok) { PropMode p; p.descrip = config_mode.getText(); p.name = config_mode.getAttribute("name").first; PropModeList.push_back(p); ok = propmodes.getNextElement(config_mode); } sort(PropModeList.begin(), PropModeList.end()); return 0; } static int init_satellite() { if (SatelliteList.size() > 0) return 0; XMLElement satellites; if (tqsl_get_xml_config_section("satellites", satellites)) return 1; XMLElement config_sat; bool ok = satellites.getFirstElement("satellite", config_sat); while (ok) { Satellite s; s.descrip = config_sat.getText(); s.name = config_sat.getAttribute("name").first; tQSL_Date d; if (!tqsl_initDate(&d, config_sat.getAttribute("startDate").first.c_str())) s.start = d; if (!tqsl_initDate(&d, config_sat.getAttribute("endDate").first.c_str())) s.end = d; SatelliteList.push_back(s); ok = satellites.getNextElement(config_sat); } sort(SatelliteList.begin(), SatelliteList.end()); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumMode(int *number) { if (tqsl_init()) return 1; if (number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_mode()) return 1; *number = ModeList.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getMode(int index, const char **mode, const char **group) { if (index < 0 || mode == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_mode()) return 1; if (index >= (int)ModeList.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *mode = ModeList[index].mode.c_str(); if (group) *group = ModeList[index].group.c_str(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumDXCCEntity(int *number) { if (number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_dxcc()) return 1; *number = DXCCList.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity(int index, int *number, const char **name) { if (index < 0 || name == 0 || number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_dxcc()) return 1; if (index >= (int)DXCCList.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *number = DXCCList[index].first; *name = DXCCList[index].second.c_str(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName(int number, const char **name) { if (name == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_dxcc()) return 1; IntMap::const_iterator it; it = DXCCMap.find(number); if (it == DXCCMap.end()) { tQSL_Error = TQSL_NAME_NOT_FOUND; return 1; } *name = it->second.c_str(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap(int number, const char **zonemap) { if (zonemap == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_dxcc()) return 1; IntMap::const_iterator it; it = DXCCZoneMap.find(number); if (it == DXCCZoneMap.end()) { tQSL_Error = TQSL_NAME_NOT_FOUND; return 1; } const char *map = it->second.c_str(); if (!map || map[0] == '\0') *zonemap = NULL; else *zonemap = map; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumPropagationMode(int *number) { if (tqsl_init()) return 1; if (number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_propmode()) return 1; *number = PropModeList.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode(int index, const char **name, const char **descrip) { if (index < 0 || name == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_propmode()) return 1; if (index >= (int)PropModeList.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *name = PropModeList[index].name.c_str(); if (descrip) *descrip = PropModeList[index].descrip.c_str(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumSatellite(int *number) { if (tqsl_init()) return 1; if (number == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_satellite()) return 1; *number = SatelliteList.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getSatellite(int index, const char **name, const char **descrip, tQSL_Date *start, tQSL_Date *end) { if (index < 0 || name == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_satellite()) return 1; if (index >= (int)SatelliteList.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *name = SatelliteList[index].name.c_str(); if (descrip) *descrip = SatelliteList[index].descrip.c_str(); if (start) *start = SatelliteList[index].start; if (end) *end = SatelliteList[index].end; return 0; } static int init_cabrillo_map() { if (tqsl_cabrillo_map.size() > 0) return 0; XMLElement cabrillo_map; if (tqsl_get_xml_config_section("cabrillomap", cabrillo_map)) return 1; XMLElement cabrillo_item; bool ok = cabrillo_map.getFirstElement("cabrillocontest", cabrillo_item); while (ok) { if (cabrillo_item.getText() != "" && strtol(cabrillo_item.getAttribute("field").first.c_str(), NULL, 10) > TQSL_MIN_CABRILLO_MAP_FIELD) tqsl_cabrillo_map[cabrillo_item.getText()] = make_pair(strtol(cabrillo_item.getAttribute("field").first.c_str(), NULL, 10)-1, (cabrillo_item.getAttribute("type").first == "VHF") ? TQSL_CABRILLO_VHF : TQSL_CABRILLO_HF); ok = cabrillo_map.getNextElement(cabrillo_item); } return 0; } DLLEXPORT int CALLCONVENTION tqsl_clearCabrilloMap() { tqsl_cabrillo_user_map.clear(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry(const char *contest, int field, int contest_type) { if (contest == 0 || field <= TQSL_MIN_CABRILLO_MAP_FIELD || (contest_type != TQSL_CABRILLO_HF && contest_type != TQSL_CABRILLO_VHF)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } tqsl_cabrillo_user_map[string_toupper(contest)] = make_pair(field-1, contest_type); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry(const char *contest, int *fieldnum, int *contest_type) { if (contest == 0 || fieldnum == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_cabrillo_map()) return 1; map >::iterator it; if ((it = tqsl_cabrillo_user_map.find(string_toupper(contest))) == tqsl_cabrillo_user_map.end()) { if ((it = tqsl_cabrillo_map.find(string_toupper(contest))) == tqsl_cabrillo_map.end()) { *fieldnum = 0; return 0; } } *fieldnum = it->second.first + 1; if (contest_type) *contest_type = it->second.second; return 0; } static int init_adif_map() { if (tqsl_adif_map.size() > 0) return 0; XMLElement adif_map; if (tqsl_get_xml_config_section("adifmap", adif_map)) return 1; XMLElement adif_item; bool ok = adif_map.getFirstElement("adifmode", adif_item); while (ok) { if (adif_item.getText() != "" && adif_item.getAttribute("mode").first != "") tqsl_adif_map[adif_item.getText()] = adif_item.getAttribute("mode").first; ok = adif_map.getNextElement(adif_item); } return 0; } DLLEXPORT int CALLCONVENTION tqsl_clearADIFModes() { tqsl_adif_map.clear(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_setADIFMode(const char *adif_item, const char *mode) { if (adif_item == 0 || mode == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_adif_map()) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - ADIF map invalid"); return 1; } string umode = string_toupper(mode); tqsl_adif_map[string_toupper(adif_item)] = umode; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getADIFMode(const char *adif_item, char *mode, int nmode) { if (adif_item == 0 || mode == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (init_adif_map()) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - ADIF map invalid"); return 1; } string orig = adif_item; orig = string_toupper(orig); string amode; if (tqsl_adif_map.find(orig) != tqsl_adif_map.end()) amode = tqsl_adif_map[orig]; if (nmode < (int)amode.length()+1) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(mode, amode.c_str()); return 0; } static int init_loc_maps() { if (tqsl_field_map.size() > 0) return 0; XMLElement config_pages; if (tqsl_get_xml_config_section("locpages", config_pages)) return 1; XMLElement config_page; tqsl_page_map.clear(); bool ok; for (ok = config_pages.getFirstElement("page", config_page); ok; ok = config_pages.getNextElement(config_page)) { pair Id = config_page.getAttribute("Id"); int page_num = strtol(Id.first.c_str(), NULL, 10); if (!Id.second || page_num < 1) { // Must have the Id! tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - page missing ID"); return 1; } tqsl_page_map[page_num] = config_page; } XMLElement config_fields; if (tqsl_get_xml_config_section("locfields", config_fields)) return 1; XMLElement config_field; for (ok = config_fields.getFirstElement("field", config_field); ok; ok = config_fields.getNextElement(config_field)) { pair Id = config_field.getAttribute("Id"); if (!Id.second) { // Must have the Id! tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - field missing ID"); return 1; } tqsl_field_map[Id.first] = config_field; } return 0; } static bool inMap(int cqvalue, int ituvalue, bool cqz, bool ituz, const char *map) { /* * Parse the zone map and return true if the value is a valid zone number * The maps are colon-separated number pairs, with a list of pairs comma separated. */ int cq, itu; bool result = false; // No map or empty string -> all match if (!map || map[0] == '\0') { return true; } char *mapcopy = strdup(map); char *mapPart = strtok(mapcopy, ","); while (mapPart) { sscanf(mapPart, "%d:%d", &itu, &cq); if (cqz && ituz) { if ((cq == cqvalue || cqvalue == 0) && (itu == ituvalue || ituvalue == 0)) { result = true; break; } } else if (cqz && (cq == cqvalue || cqvalue == 0)) { result = true; break; } else if (ituz && (itu == ituvalue || ituvalue == 0)) { result = true; break; } mapPart = strtok(NULL, ","); } free (mapcopy); return result; } static TQSL_LOCATION_FIELD * get_location_field(int page, const string& gabbi, TQSL_LOCATION *loc) { if (page == 0) page = loc->page; for (; page > 0; page = loc->pagelist[page-1].prev) { TQSL_LOCATION_FIELDLIST& fl = loc->pagelist[page-1].fieldlist; for (int j = 0; j < (int)fl.size(); j++) { if (fl[j].gabbi_name == gabbi) return &(fl[j]); } } return 0; } static int update_page(int page, TQSL_LOCATION *loc) { TQSL_LOCATION_PAGE& p = loc->pagelist[page-1]; int dxcc; int current_entity = -1; int loaded_cqz = -1; int loaded_ituz = -1; for (int i = 0; i < (int)p.fieldlist.size(); i++) { TQSL_LOCATION_FIELD& field = p.fieldlist[i]; field.changed = false; if (field.gabbi_name == "CALL") { if (field.items.size() == 0 || loc->newflags) { // Build list of call signs from available certs field.changed = true; field.items.clear(); loc->newflags = false; p.hash.clear(); tQSL_Cert *certlist; int ncerts; tqsl_selectCertificates(&certlist, &ncerts, 0, 0, 0, 0, loc->cert_flags); for (int i = 0; i < ncerts; i++) { char callsign[40]; tqsl_getCertificateCallSign(certlist[i], callsign, sizeof callsign); tqsl_getCertificateDXCCEntity(certlist[i], &dxcc); char ibuf[10]; snprintf(ibuf, sizeof ibuf, "%d", dxcc); bool found = false; // Only add a given DXCC entity to a call once. map >::iterator call_p; for (call_p = p.hash.begin(); call_p != p.hash.end(); call_p++) { if (call_p->first == callsign && call_p->second[0] == ibuf) { found = true; break; } } if (!found) p.hash[callsign].push_back(ibuf); tqsl_freeCertificate(certlist[i]); } // Fill the call sign list map >::iterator call_p; field.idx = 0; for (call_p = p.hash.begin(); call_p != p.hash.end(); call_p++) { TQSL_LOCATION_ITEM item; item.text = call_p->first; if (item.text == field.cdata) field.idx = (int)field.items.size(); field.items.push_back(item); } if (field.items.size() > 0) field.cdata = field.items[field.idx].text; else field.cdata = ""; } } else if (field.gabbi_name == "DXCC") { // Note: Expects CALL to be field 0 of this page. string call = p.fieldlist[0].cdata; if (field.items.size() == 0 || call != field.dependency) { // rebuild list field.changed = true; init_dxcc(); int olddxcc = strtol(field.cdata.c_str(), NULL, 10); field.items.clear(); field.idx = 0; #ifdef DXCC_TEST const char *dxcc_test = getenv("TQSL_DXCC"); if (dxcc_test) { vector &entlist = p.hash[call]; char *parse_dxcc = new char[strlen(dxcc_test) + 1]; strcpy(parse_dxcc, dxcc_test); char *cp = strtok(parse_dxcc, ","); while (cp) { if (find(entlist.begin(), entlist.end(), string(cp)) == entlist.end()) entlist.push_back(cp); cp = strtok(0, ","); } delete[] parse_dxcc; } #endif vector::iterator ip; for (ip = p.hash[call].begin(); ip != p.hash[call].end(); ip++) { TQSL_LOCATION_ITEM item; item.text = *ip; item.ivalue = strtol(ip->c_str(), NULL, 10); IntMap::iterator dxcc_it = DXCCMap.find(item.ivalue); if (dxcc_it != DXCCMap.end()) { item.label = dxcc_it->second; item.zonemap = DXCCZoneMap[item.ivalue]; } if (item.ivalue == olddxcc) field.idx = field.items.size(); field.items.push_back(item); } if (field.items.size() > 0) field.cdata = field.items[field.idx].text; field.dependency = call; } // rebuild list } else { if (tqsl_field_map.find(field.gabbi_name) == tqsl_field_map.end()) { // Shouldn't happen! tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - field map mismatch."); return 1; } XMLElement config_field = tqsl_field_map.find(field.gabbi_name)->second; pair attr = config_field.getAttribute("dependsOn"); if (attr.first != "") { // Items list depends on other field TQSL_LOCATION_FIELD *fp = get_location_field(page, attr.first, loc); if (fp) { // Found the dependency field. Now find the enums to use string val = fp->cdata; if (fp->items.size() > 0) val = fp->items[fp->idx].text; if (val == field.dependency) continue; field.dependency = val; field.changed = true; field.items.clear(); XMLElement enumlist; bool ok = config_field.getFirstElement("enums", enumlist); while (ok) { pair dependency = enumlist.getAttribute("dependency"); if (dependency.second && dependency.first == val) { if (!(field.flags & TQSL_LOCATION_FIELD_MUSTSEL)) { TQSL_LOCATION_ITEM item; item.label = "[None]"; field.items.push_back(item); } XMLElement enumitem; bool iok = enumlist.getFirstElement("enum", enumitem); while (iok) { TQSL_LOCATION_ITEM item; item.text = enumitem.getAttribute("value").first; item.label = enumitem.getText(); item.zonemap = enumitem.getAttribute("zonemap").first; field.items.push_back(item); iok = enumlist.getNextElement(enumitem); } } ok = config_field.getNextElement(enumlist); } // enum loop } else { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - dependent field not found."); return 1; } } else { // No dependencies TQSL_LOCATION_FIELD *ent = get_location_field(page, "DXCC", loc); current_entity = strtol(ent->cdata.c_str(), NULL, 10); bool cqz = field.gabbi_name == "CQZ"; bool ituz = field.gabbi_name == "ITUZ"; if (field.items.size() == 0 || (cqz && current_entity != loaded_cqz) || (ituz && current_entity != loaded_ituz)) { XMLElement enumlist; if (config_field.getFirstElement("enums", enumlist)) { field.items.clear(); field.changed = true; if (!(field.flags & TQSL_LOCATION_FIELD_MUSTSEL)) { TQSL_LOCATION_ITEM item; item.label = "[None]"; field.items.push_back(item); } XMLElement enumitem; bool iok = enumlist.getFirstElement("enum", enumitem); while (iok) { TQSL_LOCATION_ITEM item; item.text = enumitem.getAttribute("value").first; item.label = enumitem.getText(); item.zonemap = enumitem.getAttribute("zonemap").first; field.items.push_back(item); iok = enumlist.getNextElement(enumitem); } } else { // No enums supplied int ftype = strtol(config_field.getAttribute("intype").first.c_str(), NULL, 10); if (ftype == TQSL_LOCATION_FIELD_LIST || ftype == TQSL_LOCATION_FIELD_DDLIST) { // This a list field int lower = strtol(config_field.getAttribute("lower").first.c_str(), NULL, 10); int upper = strtol(config_field.getAttribute("upper").first.c_str(), NULL, 10); const char *zoneMap; /* Get the map */ if (tqsl_getDXCCZoneMap(current_entity, &zoneMap)) { zoneMap = NULL; } if (upper < lower) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - field range order incorrect."); return 1; } field.items.clear(); field.changed = true; if (cqz) loaded_cqz = current_entity; if (ituz) loaded_ituz = current_entity; if (!(field.flags & TQSL_LOCATION_FIELD_MUSTSEL)) { TQSL_LOCATION_ITEM item; item.label = "[None]"; field.items.push_back(item); } char buf[40]; for (int j = lower; j <= upper; j++) { if (!zoneMap || inMap(j, j, cqz, ituz, zoneMap)) { snprintf(buf, sizeof buf, "%d", j); TQSL_LOCATION_ITEM item; item.text = buf; item.ivalue = j; field.items.push_back(item); } } } // intype != TEXT } // enums supplied } // itemlist not empty and current entity } // no dependencies } // field name not CALL|DXCC } // field loop /* Sanity check zones */ bool zonesok = true; // Try for subdivision info first string zone_error = ""; TQSL_LOCATION_FIELD *state = get_location_field(page, "US_STATE", loc); if (state) { zone_error = "Invalid zone selections for state"; } else { state = get_location_field(page, "CA_PROVINCE", loc); if (state) { zone_error = "Invalid zone selections for province"; } else { state = get_location_field(page, "RU_OBLAST", loc); if (state) { zone_error = "Invalid zone selections for oblast"; } else { // If no subdivision, use entity. state = get_location_field(page, "DXCC", loc); zone_error = "Invalid zone selections for DXCC entity"; } } } if (state && state->items.size() > 0) { TQSL_LOCATION_FIELD *cqz = get_location_field(page, "CQZ", loc); TQSL_LOCATION_FIELD *ituz = get_location_field(page, "ITUZ", loc); string szm = state->items[state->idx].zonemap; const char* stateZoneMap=szm.c_str(); int currentCQ = cqz->idata; int currentITU = ituz->idata; if (!inMap(currentCQ, currentITU, true, true, stateZoneMap)){ zonesok = false; } TQSL_LOCATION_FIELD *zerr = get_location_field(page, "ZERR", loc); if (zerr) { if(!zonesok) { zerr->cdata = zone_error; } else { zerr->cdata = ""; } } } p.complete = true; return 0; } static int make_page(TQSL_LOCATION_PAGELIST& pagelist, int page_num) { if (init_loc_maps()) return 1; if (tqsl_page_map.find(page_num) == tqsl_page_map.end()) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - page reference could not be found."); return 1; } TQSL_LOCATION_PAGE p; pagelist.push_back(p); XMLElement& config_page = tqsl_page_map[page_num]; pagelist.back().prev = strtol(config_page.getAttribute("follows").first.c_str(), NULL, 10); XMLElement config_pageField; bool field_ok = config_page.getFirstElement("pageField", config_pageField); while (field_ok) { string field_name = config_pageField.getText(); if (field_name == "" || tqsl_field_map.find(field_name) == tqsl_field_map.end()) { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "TQSL Configuration file invalid - page references undefined field."); return 1; } XMLElement& config_field = tqsl_field_map[field_name]; TQSL_LOCATION_FIELD loc_field( field_name, config_field.getAttribute("label").first.c_str(), (config_field.getAttribute("type").first == "C") ? TQSL_LOCATION_FIELD_CHAR : TQSL_LOCATION_FIELD_INT, strtol(config_field.getAttribute("len").first.c_str(), NULL, 10), strtol(config_field.getAttribute("intype").first.c_str(), NULL, 10), strtol(config_field.getAttribute("flags").first.c_str(), NULL, 10) ); pagelist.back().fieldlist.push_back(loc_field); field_ok = config_page.getNextElement(config_pageField); } return 0; } DLLEXPORT int CALLCONVENTION tqsl_initStationLocationCapture(tQSL_Location *locp) { if (tqsl_init()) return 1; if (locp == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_LOCATION *loc = new TQSL_LOCATION; *locp = loc; if (init_loc_maps()) return 1; map::iterator pit; for (pit = tqsl_page_map.begin(); pit != tqsl_page_map.end(); pit++) { if (make_page(loc->pagelist, pit->first)) return 1; } loc->page = 1; if (update_page(1, loc)) return 1; return 0; } DLLEXPORT int CALLCONVENTION tqsl_endStationLocationCapture(tQSL_Location *locp) { if (tqsl_init()) return 1; if (locp == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (*locp == 0) return 0; if (CAST_TQSL_LOCATION(*locp)->sentinel == 0x5445) delete CAST_TQSL_LOCATION(*locp); *locp = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_updateStationLocationCapture(tQSL_Location locp) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; // TQSL_LOCATION_PAGE &p = loc->pagelist[loc->page-1]; return update_page(loc->page, loc); } DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocationCapturePages(tQSL_Location locp, int *npages) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (npages == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *npages = loc->pagelist.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCapturePage(tQSL_Location locp, int *page) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (page == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *page = loc->page; return 0; } DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCapturePage(tQSL_Location locp, int page) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (page < 1 || page > (int)loc->pagelist.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } loc->page = page; return 0; } DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCertFlags(tQSL_Location locp, int flags) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (loc->cert_flags != flags) { loc->cert_flags = flags; loc->newflags = true; loc->page = 1; if (update_page(1, loc)) return 1; } return 0; } static int find_next_page(TQSL_LOCATION *loc) { // Set next page based on page dependencies TQSL_LOCATION_PAGE& p = loc->pagelist[loc->page-1]; map::iterator pit; p.next = 0; for (pit = tqsl_page_map.begin(); pit != tqsl_page_map.end(); pit++) { if (strtol(pit->second.getAttribute("follows").first.c_str(), NULL, 10) == loc->page) { string dependsOn = pit->second.getAttribute("dependsOn").first; string dependency = pit->second.getAttribute("dependency").first; if (dependsOn == "") { p.next = pit->first; break; } TQSL_LOCATION_FIELD *fp = get_location_field(0, dependsOn, loc); //if (fp->idx>=fp->items.size()) { cerr<<"!! " __FILE__ "(" << __LINE__ << "): Was going to index out of fp->items"<items.size() > fp->idx && fp->items[fp->idx].text == dependency) { p.next = pit->first; break; // Found next page //} } } } return 0; } DLLEXPORT int CALLCONVENTION tqsl_nextStationLocationCapture(tQSL_Location locp) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (find_next_page(loc)) return 0; TQSL_LOCATION_PAGE &p = loc->pagelist[loc->page-1]; if (p.next > 0) loc->page = p.next; update_page(loc->page, loc); return 0; } DLLEXPORT int CALLCONVENTION tqsl_prevStationLocationCapture(tQSL_Location locp) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_PAGE &p = loc->pagelist[loc->page-1]; //cerr << "prev: " << p.prev << endl; if (p.prev > 0) loc->page = p.prev; return 0; } DLLEXPORT int CALLCONVENTION tqsl_hasNextStationLocationCapture(tQSL_Location locp, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (rval == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (find_next_page(loc)) return 1; *rval = (loc->pagelist[loc->page-1].next > 0); return 0; } DLLEXPORT int CALLCONVENTION tqsl_hasPrevStationLocationCapture(tQSL_Location locp, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (rval == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *rval = (loc->pagelist[loc->page-1].prev > 0); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumLocationField(tQSL_Location locp, int *numf) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (numf == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; *numf = fl.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabelSize(tQSL_Location locp, int field_num, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (rval == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *rval = fl[field_num].label.size()+1; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel(tQSL_Location locp, int field_num, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (buf == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(buf, fl[field_num].label.c_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBISize(tQSL_Location locp, int field_num, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (rval == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *rval = fl[field_num].gabbi_name.size()+1; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI(tQSL_Location locp, int field_num, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (buf == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(buf, fl[field_num].gabbi_name.c_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType(tQSL_Location locp, int field_num, int *type) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (type == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *type = fl[field_num].input_type; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged(tQSL_Location locp, int field_num, int *changed) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (changed == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *changed = fl[field_num].changed; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType(tQSL_Location locp, int field_num, int *type) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (type == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *type = fl[field_num].data_type; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags(tQSL_Location locp, int field_num, int *flags) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (flags == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *flags = fl[field_num].flags; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength(tQSL_Location locp, int field_num, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (rval == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *rval = fl[field_num].data_len; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData(tQSL_Location locp, int field_num, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (buf == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (fl[field_num].flags & TQSL_LOCATION_FIELD_UPPER) strncpy(buf, string_toupper(fl[field_num].cdata).c_str(), bufsiz); else strncpy(buf, fl[field_num].cdata.c_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData(tQSL_Location locp, int field_num, int *dat) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (dat == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *dat = fl[field_num].idata; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex(tQSL_Location locp, int field_num, int *dat) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (dat == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (fl[field_num].input_type != TQSL_LOCATION_FIELD_DDLIST && fl[field_num].input_type != TQSL_LOCATION_FIELD_LIST) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *dat = fl[field_num].idx; return 0; } DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData(tQSL_Location locp, int field_num, const char *buf) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (buf == 0 || field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } fl[field_num].cdata = string(buf).substr(0, fl[field_num].data_len); if (fl[field_num].flags & TQSL_LOCATION_FIELD_UPPER) fl[field_num].cdata = string_toupper(fl[field_num].cdata); return 0; } /* Set the field's index. For pick lists, this is the index into * 'items'. In that case, also set the field's data to the picked value. */ DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex(tQSL_Location locp, int field_num, int dat) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } fl[field_num].idx = dat; if (fl[field_num].input_type == TQSL_LOCATION_FIELD_DDLIST || fl[field_num].input_type == TQSL_LOCATION_FIELD_LIST) { if (dat >= 0 && dat < (int)fl[field_num].items.size()) { fl[field_num].idx = dat; fl[field_num].cdata = fl[field_num].items[dat].text; fl[field_num].idata = fl[field_num].items[dat].ivalue; } else { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } } return 0; } /* Set the field's integer data. */ DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData(tQSL_Location locp, int field_num, int dat) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (field_num < 0 || field_num >= (int)fl.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } fl[field_num].idata = dat; return 0; } /* For pick lists, this is the index into * 'items'. In that case, also set the field's char data to the picked value. */ DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems(tQSL_Location locp, int field_num, int *rval) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (rval == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; *rval = fl[field_num].items.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem(tQSL_Location locp, int field_num, int item_idx, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; TQSL_LOCATION_FIELDLIST &fl = loc->pagelist[loc->page-1].fieldlist; if (buf == 0 || field_num < 0 || field_num >= (int)fl.size() || (fl[field_num].input_type != TQSL_LOCATION_FIELD_LIST && fl[field_num].input_type != TQSL_LOCATION_FIELD_DDLIST)) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (item_idx < 0 || item_idx >= (int)fl[field_num].items.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } string& str = (fl[field_num].items[item_idx].label == "") ? fl[field_num].items[item_idx].text : fl[field_num].items[item_idx].label; strncpy(buf, str.c_str(), bufsiz); return 0; } static string tqsl_station_data_filename(const char *f = "station_data") { string s = tQSL_BaseDir; #ifdef _WIN32 s += "\\"; #else s += "/"; #endif s += f; return s; } static int tqsl_load_station_data(XMLElement &xel) { int status = xel.parseFile(tqsl_station_data_filename().c_str()); if (status) { if (errno == ENOENT) // If there's no file, no error. return 0; strncpy(tQSL_ErrorFile, tqsl_station_data_filename().c_str(), sizeof tQSL_ErrorFile); if (status == XML_PARSE_SYSTEM_ERROR) { tQSL_Error = TQSL_FILE_SYSTEM_ERROR; tQSL_Errno = errno; } else { tQSL_Error = TQSL_FILE_SYNTAX_ERROR; } return 1; } return status; } static int tqsl_dump_station_data(XMLElement &xel) { ofstream out; string fn = tqsl_station_data_filename(); out.exceptions(std::ios::failbit | std::ios::eofbit | std::ios::badbit); try { out.open(fn.c_str()); out << xel << endl; out.close(); } catch (exception& x) { tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, x.what(), sizeof tQSL_CustomError); return 1; } return 0; } static int tqsl_load_loc(TQSL_LOCATION *loc, XMLElementList::iterator ep, bool ignoreZones) { bool exists; loc->page = 1; loc->data_errors[0] = '\0'; int bad_ituz = 0; int bad_cqz = 0; while(1) { TQSL_LOCATION_PAGE& page = loc->pagelist[loc->page-1]; for (int fidx = 0; fidx < (int)page.fieldlist.size(); fidx++) { TQSL_LOCATION_FIELD& field = page.fieldlist[fidx]; if (field.gabbi_name != "") { // A field that may exist XMLElement el; if (ep->second.getFirstElement(field.gabbi_name, el)) { field.cdata = el.getText(); switch (field.input_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: exists = false; for (int i = 0; i < (int)field.items.size(); i++) { string cp = field.items[i].text; int q = strcasecmp(field.cdata.c_str(), cp.c_str()); if (q == 0) { field.idx = i; field.cdata = cp; field.idata = field.items[i].ivalue; exists = true; break; } } if (!exists) { if (field.gabbi_name == "CQZ") bad_cqz = strtol(field.cdata.c_str(), NULL, 10); else if (field.gabbi_name == "ITUZ") bad_ituz = strtol(field.cdata.c_str(), NULL, 10); } break; case TQSL_LOCATION_FIELD_TEXT: field.cdata = trim(field.cdata); if (field.data_type == TQSL_LOCATION_FIELD_INT) field.idata = strtol(field.cdata.c_str(), NULL, 10); break; } } } if (update_page(loc->page, loc)) return 1; } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; tqsl_nextStationLocationCapture(loc); } if (ignoreZones) return 0; if (bad_cqz && bad_ituz) { snprintf(loc->data_errors, sizeof(loc->data_errors), "This station location is configured with invalid CQ zone %d and invalid ITU zone %d.", bad_cqz, bad_ituz); } else if (bad_cqz) { snprintf(loc->data_errors, sizeof(loc->data_errors), "This station location is configured with invalid CQ zone %d.", bad_cqz); } else if (bad_ituz) { snprintf(loc->data_errors, sizeof(loc->data_errors), "This station location is configured with invalid ITU zone %d.", bad_ituz); } return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationDataEnc(tQSL_StationDataEnc *sdata) { char *dbuf = NULL; size_t dlen = 0; gzFile in = gzopen(tqsl_station_data_filename().c_str(), "rb"); if (!in) { if (errno == ENOENT) { *sdata = NULL; return 0; } tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; strncpy(tQSL_ErrorFile, tqsl_station_data_filename().c_str(), sizeof tQSL_ErrorFile); return 1; } char buf[2048]; int rcount; while ((rcount = gzread(in, buf, sizeof buf)) > 0) { dlen += rcount; } dbuf = (char *)malloc(dlen + 2); if (!dbuf) return 1; *sdata = dbuf; gzrewind(in); while ((rcount = gzread(in, dbuf, sizeof buf)) > 0) { dbuf += rcount; } *dbuf = '\0'; gzclose(in); return 0; } DLLEXPORT int CALLCONVENTION tqsl_freeStationDataEnc(tQSL_StationDataEnc sdata) { if (sdata) free(sdata); return 0; //can never fail } DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations(const char *locdata) { XMLElement sfile; XMLElement new_top_el; XMLElement top_el; std::vector calls; if (tqsl_load_station_data(top_el)) return 1; new_top_el.parseString(locdata); if (!new_top_el.getFirstElement(sfile)) sfile.setElementName("StationDataFile"); // Build alist of valid calls tQSL_Cert *certlist; int ncerts; tqsl_selectCertificates(&certlist, &ncerts, 0, 0, 0, 0, TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED | TQSL_SELECT_CERT_SUPERCEDED); calls.clear(); for (int i = 0; i < ncerts; i++) { char callsign[40]; tqsl_getCertificateCallSign(certlist[i], callsign, sizeof(callsign)); calls.push_back(callsign); tqsl_freeCertificate(certlist[i]); } XMLElementList& ellist = sfile.getElementList(); XMLElementList::iterator ep; XMLElement call; for (ep = ellist.find("StationData"); ep != ellist.end(); ep++) { if (ep->first != "StationData") break; pair rval = ep->second.getAttribute("name"); if (rval.second) { TQSL_LOCATION *oldloc; TQSL_LOCATION *newloc; ep->second.getFirstElement("CALL", call); for (size_t j = 0; j < calls.size(); j++) { if (calls[j] == call.getText()) { if (tqsl_getStationLocation((tQSL_Location *)&oldloc, rval.first.c_str())) { // Location doesn't exist if (tqsl_initStationLocationCapture((tQSL_Location *)&newloc) == 0) { if (tqsl_load_loc(newloc, ep, true) == 0) { // new loads OK tqsl_setStationLocationCaptureName(newloc, rval.first.c_str()); tqsl_saveStationLocationCapture(newloc, 0); tqsl_endStationLocationCapture((tQSL_Location *)&newloc); } } } else { tqsl_endStationLocationCapture((tQSL_Location *)&oldloc); } } } } } return 0; } DLLEXPORT int CALLCONVENTION tqsl_deleteStationLocation(const char *name) { XMLElement top_el; if (tqsl_load_station_data(top_el)) return 1; XMLElement sfile; if (!top_el.getFirstElement(sfile)) sfile.setElementName("StationDataFile"); XMLElementList& ellist = sfile.getElementList(); XMLElementList::iterator ep; for (ep = ellist.find("StationData"); ep != ellist.end(); ep++) { if (ep->first != "StationData") break; pair rval = ep->second.getAttribute("name"); if (rval.second && !strcasecmp(rval.first.c_str(), name)) { ellist.erase(ep); return tqsl_dump_station_data(sfile); } } tQSL_Error = TQSL_LOCATION_NOT_FOUND; return 1; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocation(tQSL_Location *locp, const char *name) { if (tqsl_initStationLocationCapture(locp)) return 1; TQSL_LOCATION *loc; if (!(loc = check_loc(*locp))) return 1; loc->name = name; XMLElement top_el; if (tqsl_load_station_data(top_el)) return 1; XMLElement sfile; if (!top_el.getFirstElement(sfile)) sfile.setElementName("StationDataFile"); XMLElementList& ellist = sfile.getElementList(); bool exists = false; XMLElementList::iterator ep; for (ep = ellist.find("StationData"); ep != ellist.end(); ep++) { if (ep->first != "StationData") break; pair rval = ep->second.getAttribute("name"); if (rval.second && !strcasecmp(rval.first.c_str(), loc->name.c_str())) { exists = true; break; } } if (!exists) { tQSL_Error = TQSL_LOCATION_NOT_FOUND; return 1; } return tqsl_load_loc(loc, ep, false); } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationErrors(tQSL_Location locp, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; strncpy(buf, loc->data_errors, bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocations(tQSL_Location locp, int *nloc) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (nloc == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } loc->names.clear(); XMLElement top_el; if (tqsl_load_station_data(top_el)) return 1; XMLElement sfile; if (top_el.getFirstElement(sfile)) { XMLElement sd; bool ok = sfile.getFirstElement("StationData", sd); while (ok && sd.getElementName() == "StationData") { pair name = sd.getAttribute("name"); if (name.second) { XMLElement xc; string call; if (sd.getFirstElement("CALL", xc)) call = xc.getText(); loc->names.push_back(TQSL_NAME(name.first, call)); } ok = sfile.getNextElement(sd); } } *nloc = loc->names.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName(tQSL_Location locp, int idx, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (buf == 0 || idx < 0 || idx >= (int)loc->names.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(buf, loc->names[idx].name.c_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign(tQSL_Location locp, int idx, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (buf == 0 || idx < 0 || idx >= (int)loc->names.size()) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(buf, loc->names[idx].call.c_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField(tQSL_Location locp, const char *name, char *namebuf, int bufsize) { int old_page; TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (name == NULL || namebuf == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (tqsl_getStationLocationCapturePage(loc, &old_page)) return 1; string find = name; tqsl_setStationLocationCapturePage(loc, 1); do { int numf; if (tqsl_getNumLocationField(loc, &numf)) return 1; for (int i = 0; i < numf; i++) { TQSL_LOCATION_FIELD& field = loc->pagelist[loc->page-1].fieldlist[i]; if (find == field.gabbi_name) { // Found it switch (field.input_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: if (field.data_type == TQSL_LOCATION_FIELD_INT) { char numbuf[20]; if ((int) field.items.size() <= field.idx) { strncpy(namebuf, field.cdata.c_str(), bufsize); } else if (field.idx == 0 && field.items[field.idx].label == "[None]") { strncpy(namebuf, "", bufsize); } else { snprintf(numbuf, sizeof numbuf, "%d", field.items[field.idx].ivalue); strncpy(namebuf, numbuf, bufsize); } } else if (field.idx < 0 || field.idx >= (int)field.items.size()) strncpy(namebuf, "", bufsize); else strncpy(namebuf, field.items[field.idx].text.c_str(), bufsize); break; case TQSL_LOCATION_FIELD_TEXT: field.cdata = trim(field.cdata); if (field.flags & TQSL_LOCATION_FIELD_UPPER) field.cdata = string_toupper(field.cdata); strncpy(namebuf, field.cdata.c_str(), bufsize); break; } goto done; } } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; if (tqsl_nextStationLocationCapture(loc)) return 1; } while (1); strncpy(namebuf, "", bufsize); // Did not find it done: tqsl_setStationLocationCapturePage(loc, old_page); return 0; } static int tqsl_location_to_xml(TQSL_LOCATION *loc, XMLElement& sd) { int old_page; if (tqsl_getStationLocationCapturePage(loc, &old_page)) return 1; tqsl_setStationLocationCapturePage(loc, 1); do { int numf; if (tqsl_getNumLocationField(loc, &numf)) return 1; for (int i = 0; i < numf; i++) { TQSL_LOCATION_FIELD& field = loc->pagelist[loc->page-1].fieldlist[i]; XMLElement fd; fd.setPretext(sd.getPretext() + " "); fd.setElementName(field.gabbi_name); switch (field.input_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: if (field.idx < 0 || field.idx >= (int)field.items.size()) { fd.setText(""); } else if (field.data_type == TQSL_LOCATION_FIELD_INT) { char numbuf[20]; snprintf(numbuf, sizeof numbuf, "%d", field.items[field.idx].ivalue); fd.setText(numbuf); } else fd.setText(field.items[field.idx].text); break; case TQSL_LOCATION_FIELD_TEXT: field.cdata = trim(field.cdata); if (field.flags & TQSL_LOCATION_FIELD_UPPER) field.cdata = string_toupper(field.cdata); fd.setText(field.cdata); break; } if (strcmp(fd.getText().c_str(), "")) sd.addElement(fd); } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; if (tqsl_nextStationLocationCapture(loc)) return 1; } while (1); tqsl_setStationLocationCapturePage(loc, old_page); return 0; } DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCaptureName(tQSL_Location locp, const char *name) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (name == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } loc->name = name; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCaptureName(tQSL_Location locp, char *namebuf, int bufsize) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (namebuf == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } strncpy(namebuf, loc->name.c_str(), bufsize); namebuf[bufsize-1] = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_saveStationLocationCapture(tQSL_Location locp, int overwrite) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp))) return 1; if (loc->name == "") { tQSL_Error = TQSL_EXPECTED_NAME; return 1; } XMLElement top_el; if (tqsl_load_station_data(top_el)) return 1; XMLElement sfile; if (!top_el.getFirstElement(sfile)) sfile.setElementName("StationDataFile"); XMLElementList& ellist = sfile.getElementList(); bool exists = false; XMLElementList::iterator ep; for (ep = ellist.find("StationData"); ep != ellist.end(); ep++) { if (ep->first != "StationData") break; pair rval = ep->second.getAttribute("name"); if (rval.second && !strcasecmp(rval.first.c_str(), loc->name.c_str())) { exists = true; break; } } if (exists && !overwrite) { tQSL_Error = TQSL_NAME_EXISTS; return 1; } XMLElement sd("StationData"); sd.setPretext("\n "); if (tqsl_location_to_xml(loc, sd)) return 1; sd.setAttribute("name", loc->name); sd.setText("\n "); // If 'exists', ep points to the existing station record if (exists) ellist.erase(ep); sfile.addElement(sd); sfile.setText("\n"); tqsl_dump_station_data(sfile); return 0; } DLLEXPORT int CALLCONVENTION tqsl_signQSORecord(tQSL_Cert cert, tQSL_Location locp, TQSL_QSO_RECORD *rec, unsigned char *sig, int *siglen) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp, false))) return 1; if (make_sign_data(loc)) return 1; XMLElement specfield; bool ok = tCONTACT_sign.getFirstElement(specfield); string rec_sign_data = loc->signdata; while (ok) { string eln=specfield.getElementName(); const char *elname = eln.c_str(); const char *value = 0; char buf[100]; if (!strcmp(elname, "CALL")) value = rec->callsign; else if (!strcmp(elname, "BAND")) value = rec->band; else if (!strcmp(elname, "BAND_RX")) value = rec->rxband; else if (!strcmp(elname, "MODE")) value = rec->mode; else if (!strcmp(elname, "FREQ")) value = rec->freq; else if (!strcmp(elname, "FREQ_RX")) value = rec->rxfreq; else if (!strcmp(elname, "PROP_MODE")) value = rec->propmode; else if (!strcmp(elname, "SAT_NAME")) value = rec->satname; else if (!strcmp(elname, "QSO_DATE")) { if (tqsl_isDateValid(&(rec->date))) value = tqsl_convertDateToText(&(rec->date), buf, sizeof buf); } else if (!strcmp(elname, "QSO_TIME")) { if (tqsl_isTimeValid(&(rec->time))) value = tqsl_convertTimeToText(&(rec->time), buf, sizeof buf); } else { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "Unknown field in signing specification: "); strncat(tQSL_CustomError, elname, sizeof tQSL_CustomError - strlen(tQSL_CustomError)-1); return 1; } if (value == 0 || value[0] == 0) { pair attr = specfield.getAttribute("required"); if (attr.second && strtol(attr.first.c_str(), NULL, 10)){ string err = specfield.getElementName() + " field required by signature specification not found"; tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, err.c_str(), sizeof tQSL_CustomError); return 1; } } else { string v(value); rec_sign_data += trim(v); } ok = tCONTACT_sign.getNextElement(specfield); } return tqsl_signDataBlock(cert, (const unsigned char *)rec_sign_data.c_str(), rec_sign_data.size(), sig, siglen); } DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCERT(tQSL_Cert cert, int uid) { static string s; s = ""; char buf[3000]; if (tqsl_getCertificateEncoded(cert, buf, sizeof buf)) return 0; char *cp = strstr(buf, "-----END CERTIFICATE-----"); if (cp) *cp = 0; if ((cp = strstr(buf, "\n"))) cp++; else cp = buf; s = "tCERT\n"; char sbuf[10], lbuf[40]; snprintf(sbuf, sizeof sbuf, "%d", uid); snprintf(lbuf, sizeof lbuf, "%s\n", (int)strlen(sbuf), sbuf); s += lbuf; snprintf(lbuf, sizeof lbuf, "", (int)strlen(cp)); s += lbuf; s += cp; s += "\n"; return s.c_str(); //KC2YWE 1/26 - dangerous but might work since s is static } DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItSTATION(tQSL_Location locp, int uid, int certuid) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp, false))) return 0; unsigned char *buf = 0; int bufsiz = 0; loc->tSTATION = "tSTATION\n"; char sbuf[10], lbuf[40]; snprintf(sbuf, sizeof sbuf, "%d", uid); snprintf(lbuf, sizeof lbuf, "%s\n", (int)strlen(sbuf), sbuf); loc->tSTATION += lbuf; snprintf(sbuf, sizeof sbuf, "%d", certuid); snprintf(lbuf, sizeof lbuf, "%s\n", (int)strlen(sbuf), sbuf); loc->tSTATION += lbuf; int old_page = loc->page; tqsl_setStationLocationCapturePage(loc, 1); do { TQSL_LOCATION_PAGE& p = loc->pagelist[loc->page-1]; for (int i = 0; i < (int)p.fieldlist.size(); i++) { TQSL_LOCATION_FIELD& f = p.fieldlist[i]; string s; if (f.input_type == TQSL_LOCATION_FIELD_BADZONE) // Don't output these to tSTATION continue; if (f.input_type == TQSL_LOCATION_FIELD_DDLIST || f.input_type == TQSL_LOCATION_FIELD_LIST) { if (f.idx < 0 || f.idx >= (int)f.items.size()) s = ""; else { /* Alaska counties are stored as 'pseudo-county|real-county' * so output just the real county name */ s = f.items[f.idx].text; size_t pos = s.find("|"); if (pos != string::npos) s = s.substr(++pos, string::npos); } } else if (f.data_type == TQSL_LOCATION_FIELD_INT) { char buf[20]; snprintf(buf, sizeof buf, "%d", f.idata); s = buf; } else s = f.cdata; if (s.size() == 0) continue; int wantsize = s.size() + f.gabbi_name.size() + 20; if (buf == 0 || bufsiz < wantsize) { if (buf != 0) delete[] buf; buf = new unsigned char[wantsize]; bufsiz = wantsize; } if (tqsl_adifMakeField(f.gabbi_name.c_str(), 0, (unsigned char *)s.c_str(), s.size(), buf, bufsiz)) { delete[] buf; return 0; } loc->tSTATION += (const char *)buf; loc->tSTATION += "\n"; } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; tqsl_nextStationLocationCapture(loc); } while (1); tqsl_setStationLocationCapturePage(loc, old_page); if (buf != 0) delete[] buf; loc->tSTATION += "\n"; return loc->tSTATION.c_str(); } DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACTData(tQSL_Cert cert, tQSL_Location locp, TQSL_QSO_RECORD *qso, int stationuid, char* signdata, int sdlen) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp, false))) return 0; if (make_sign_data(loc)) return 0; XMLElement specfield; bool ok = tCONTACT_sign.getFirstElement(specfield); string rec_sign_data = loc->signdata; while(ok) { string en=specfield.getElementName(); const char *elname = en.c_str(); const char *value = 0; char buf[100]; if (!strcmp(elname, "CALL")) value = qso->callsign; else if (!strcmp(elname, "BAND")) value = qso->band; else if (!strcmp(elname, "BAND_RX")) value = qso->rxband; else if (!strcmp(elname, "MODE")) value = qso->mode; else if (!strcmp(elname, "FREQ")) value = qso->freq; else if (!strcmp(elname, "FREQ_RX")) value = qso->rxfreq; else if (!strcmp(elname, "PROP_MODE")) value = qso->propmode; else if (!strcmp(elname, "SAT_NAME")) value = qso->satname; else if (!strcmp(elname, "QSO_DATE")) { if (tqsl_isDateValid(&(qso->date))) value = tqsl_convertDateToText(&(qso->date), buf, sizeof buf); } else if (!strcmp(elname, "QSO_TIME")) { if (tqsl_isTimeValid(&(qso->time))) value = tqsl_convertTimeToText(&(qso->time), buf, sizeof buf); } else { tQSL_Error = TQSL_CUSTOM_ERROR; strcpy(tQSL_CustomError, "Unknown field in signing specification: "); strncat(tQSL_CustomError, elname, sizeof tQSL_CustomError - strlen(tQSL_CustomError)-1); return 0; } if (value == 0 || value[0] == 0) { pair attr = specfield.getAttribute("required"); if (attr.second && strtol(attr.first.c_str(), NULL, 10)){ string err = specfield.getElementName() + " field required by signature specification not found"; tQSL_Error = TQSL_CUSTOM_ERROR; strncpy(tQSL_CustomError, err.c_str(), sizeof tQSL_CustomError); return 0; } } else { string v(value); rec_sign_data += trim(v); } ok = tCONTACT_sign.getNextElement(specfield); } unsigned char sig[129]; int siglen = sizeof sig; rec_sign_data = string_toupper(rec_sign_data); if (tqsl_signDataBlock(cert, (const unsigned char *)rec_sign_data.c_str(), rec_sign_data.size(), sig, &siglen)) return 0; char b64[512]; if (tqsl_encodeBase64(sig, siglen, b64, sizeof b64)) return 0; loc->tCONTACT = "tCONTACT\n"; char sbuf[10], lbuf[40]; snprintf(sbuf, sizeof sbuf, "%d", stationuid); snprintf(lbuf, sizeof lbuf, "%s\n", (int)strlen(sbuf), sbuf); loc->tCONTACT += lbuf; char buf[256]; tqsl_adifMakeField("CALL", 0, (const unsigned char *)qso->callsign, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; tqsl_adifMakeField("BAND", 0, (const unsigned char *)qso->band, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; tqsl_adifMakeField("MODE", 0, (const unsigned char *)qso->mode, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; // Optional fields if (qso->freq[0] != 0) { tqsl_adifMakeField("FREQ", 0, (const unsigned char *)qso->freq, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; } if (qso->rxfreq[0] != 0) { tqsl_adifMakeField("FREQ_RX", 0, (const unsigned char *)qso->rxfreq, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; } if (qso->propmode[0] != 0) { tqsl_adifMakeField("PROP_MODE", 0, (const unsigned char *)qso->propmode, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; } if (qso->satname[0] != 0) { tqsl_adifMakeField("SAT_NAME", 0, (const unsigned char *)qso->satname, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; } if (qso->rxband[0] != 0) { tqsl_adifMakeField("BAND_RX", 0, (const unsigned char *)qso->rxband, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; } // Date and Time char date_buf[40] = ""; tqsl_convertDateToText(&(qso->date), date_buf, sizeof date_buf); tqsl_adifMakeField("QSO_DATE", 0, (const unsigned char *)date_buf, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; date_buf[0] = 0; tqsl_convertTimeToText(&(qso->time), date_buf, sizeof date_buf); tqsl_adifMakeField("QSO_TIME", 0, (const unsigned char *)date_buf, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; tqsl_adifMakeField(loc->sigspec.c_str(), '6', (const unsigned char *)b64, -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; // Signature tqsl_adifMakeField("SIGNDATA", 0, (const unsigned char *)rec_sign_data.c_str(), -1, (unsigned char *)buf, sizeof buf); loc->tCONTACT += buf; loc->tCONTACT += "\n"; loc->tCONTACT += "\n"; if (signdata) strncpy(signdata, rec_sign_data.c_str(), sdlen); return loc->tCONTACT.c_str(); } DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACT(tQSL_Cert cert, tQSL_Location locp, TQSL_QSO_RECORD *qso, int stationuid) { return tqsl_getGABBItCONTACTData(cert, locp, qso, stationuid, NULL, 0); } DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign(tQSL_Location locp, char *buf, int bufsiz) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp, false))) return 1; if (buf == 0 || bufsiz <= 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_LOCATION_PAGE& p = loc->pagelist[0]; for (int i = 0; i < (int)p.fieldlist.size(); i++) { TQSL_LOCATION_FIELD f = p.fieldlist[i]; if (f.gabbi_name == "CALL") { strncpy(buf, f.cdata.c_str(), bufsiz); buf[bufsiz-1] = 0; if ((int)f.cdata.size() >= bufsiz) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } return 0; } } tQSL_Error = TQSL_CALL_NOT_FOUND; return 1; } DLLEXPORT int CALLCONVENTION tqsl_getLocationDXCCEntity(tQSL_Location locp, int *dxcc) { TQSL_LOCATION *loc; if (!(loc = check_loc(locp, false))) return 1; if (dxcc == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } TQSL_LOCATION_PAGE& p = loc->pagelist[0]; for (int i = 0; i < (int)p.fieldlist.size(); i++) { TQSL_LOCATION_FIELD f = p.fieldlist[i]; if (f.gabbi_name == "DXCC") { if (f.idx < 0 || f.idx >= (int)f.items.size()) break; // No matching DXCC entity *dxcc = f.items[f.idx].ivalue; return 0; } } tQSL_Error = TQSL_NAME_NOT_FOUND; return 1; } DLLEXPORT int CALLCONVENTION tqsl_getNumProviders(int *n) { if (n == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } vector plist; if (tqsl_load_provider_list(plist)) return 1; if (plist.size() == 0) { tQSL_Error = TQSL_PROVIDER_NOT_FOUND; return 1; } *n = plist.size(); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getProvider(int idx, TQSL_PROVIDER *provider) { if (provider == NULL || idx < 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } vector plist; if (tqsl_load_provider_list(plist)) return 1; if (idx >= (int)plist.size()) { tQSL_Error = TQSL_PROVIDER_NOT_FOUND; return 1; } *provider = plist[idx]; return 0; } DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile(const char *file, int(*cb)(int type, const char *, void *), void *userdata) { XMLElement topel; int status = topel.parseFile(file); if (status) { strncpy(tQSL_ErrorFile, file, sizeof tQSL_ErrorFile); if (status == XML_PARSE_SYSTEM_ERROR) { tQSL_Error = TQSL_FILE_SYSTEM_ERROR; tQSL_Errno = errno; } else { tQSL_Error = TQSL_FILE_SYNTAX_ERROR; } return 1; } XMLElement tqsldata; if (!topel.getFirstElement("tqsldata", tqsldata)) { strncpy(tQSL_ErrorFile, file, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_FILE_SYNTAX_ERROR; return 1; } XMLElement section; bool stat = tqsldata.getFirstElement("tqslcerts", section); if (stat) { XMLElement cert; bool cstat = section.getFirstElement("rootcert", cert); while (cstat) { tqsl_import_cert(cert.getText().c_str(), ROOTCERT, cb, userdata); cstat = section.getNextElement(cert); } cstat = section.getFirstElement("cacert", cert); while (cstat) { tqsl_import_cert(cert.getText().c_str(), CACERT, cb, userdata); cstat = section.getNextElement(cert); } cstat = section.getFirstElement("usercert", cert); while (cstat) { tqsl_import_cert(cert.getText().c_str(), USERCERT, cb, userdata); cstat = section.getNextElement(cert); } } stat = tqsldata.getFirstElement("tqslconfig", section); if (stat) { // Check to make sure we aren't overwriting newer version int major = strtol(section.getAttribute("majorversion").first.c_str(), NULL, 10); int minor = strtol(section.getAttribute("minorversion").first.c_str(), NULL, 10); int curmajor, curminor; if (tqsl_getConfigVersion(&curmajor, &curminor)) return 1; if (major < curmajor) return 0; if (major == curmajor) if (minor <= curminor) return 0; // Save the configuration file #ifdef _WIN32 string fn = string(tQSL_BaseDir) + "\\config.xml"; #else string fn = string(tQSL_BaseDir) + "/config.xml"; #endif ofstream out; out.exceptions(std::ios::failbit | std::ios::eofbit | std::ios::badbit); try { out.open(fn.c_str()); out << section << endl; out.close(); } catch (exception& x) { tQSL_Error = TQSL_CUSTOM_ERROR; snprintf(tQSL_CustomError, sizeof tQSL_CustomError, "Error writing new configuration file (%s): %s/%s", fn.c_str(), strerror(errno), x.what()); if (cb) return (*cb)(TQSL_CERT_CB_RESULT | TQSL_CERT_CB_ERROR | TQSL_CERT_CB_CONFIG, fn.c_str(), userdata); return 1; } // Clear stored config data to force re-reading new config tqsl_xml_config.clear(); DXCCMap.clear(); DXCCList.clear(); BandList.clear(); ModeList.clear(); tqsl_page_map.clear(); tqsl_field_map.clear(); tqsl_adif_map.clear(); tqsl_cabrillo_map.clear(); string version = "Configuration V" + section.getAttribute("majorversion").first + "." + section.getAttribute("minorversion").first + "\n" + fn; if (cb) return (*cb)(TQSL_CERT_CB_RESULT | TQSL_CERT_CB_LOADED | TQSL_CERT_CB_CONFIG, version.c_str(), userdata); } return 0; } /* * Get the first user certificate from a .tq6 file */ DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile(const char *file, long *serial) { XMLElement topel; int status = topel.parseFile(file); if (status) { strncpy(tQSL_ErrorFile, file, sizeof tQSL_ErrorFile); if (status == XML_PARSE_SYSTEM_ERROR) { tQSL_Error = TQSL_FILE_SYSTEM_ERROR; tQSL_Errno = errno; } else { tQSL_Error = TQSL_FILE_SYNTAX_ERROR; } return 1; } XMLElement tqsldata; if (!topel.getFirstElement("tqsldata", tqsldata)) { strncpy(tQSL_ErrorFile, file, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_FILE_SYNTAX_ERROR; return 1; } XMLElement section; bool stat = tqsldata.getFirstElement("tqslcerts", section); if (stat) { XMLElement cert; bool cstat = section.getFirstElement("usercert", cert); if (cstat) { if (tqsl_get_pem_serial(cert.getText().c_str(), serial)) { strncpy(tQSL_ErrorFile, file, sizeof tQSL_ErrorFile); tQSL_Error = TQSL_FILE_SYNTAX_ERROR; return 1; } return 0; } } return 1; } tqsl-2.0/src/load_cert.cpp0000664000076400007640000000171012231073120015563 0ustar rmurphyrmurphy/*************************************************************************** load_cert.cpp - description ------------------- begin : Sat Dec 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include #include #include "tqsllib.h" using namespace std; int cb(int, const char *msg, void *) { cout << msg << endl; return 0; } int main(int argc, char *argv[]) { if (tqsl_init()) { cerr << tqsl_getErrorString() << endl; return EXIT_FAILURE; } for (int i = 1; i < argc; i++) { if (tqsl_importTQSLFile(argv[i], cb, 0)) { cerr << tqsl_getErrorString() << endl; return EXIT_FAILURE; } } return EXIT_SUCCESS; } tqsl-2.0/src/gen_crq.cpp0000664000076400007640000000676112231073120015260 0ustar rmurphyrmurphy/*************************************************************************** gen_crq.cpp - description ------------------- begin : Sat Dec 14 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ Generates a set of certificate-request files. ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #endif #include #include #include "tqsllib.h" #include "tqslexc.h" using namespace std; int usage() { cerr << "Usage: -e email -d dxcc [-c sign_call] [-x sign_dxcc] call1 [call2 ...]" << endl; exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { string sign_call, email_addr; int dxcc = 0, sign_dxcc = 0; tQSL_Cert sign_cert = 0; try { if (tqsl_init()) throw tqslexc(); int c; while ((c = getopt(argc, argv, "c:x:e:d:")) != -1) { switch (c) { case 'c': sign_call = optarg; break; case 'x': sign_dxcc = strtol(optarg, NULL, 10); break; case 'd': dxcc = strtol(optarg, NULL, 10); break; case 'e': email_addr = optarg; break; default: usage(); } } if (optind >= argc || email_addr == "" || dxcc == 0) usage(); if (sign_call != "") { // if (sign_dxcc == 0) // usage(); tQSL_Cert *list; int ncerts; if (tqsl_selectCertificates(&list, &ncerts, sign_call.c_str(), sign_dxcc, 0, 0, 1)) throw tqslexc(); if (ncerts < 1) { string erm = "No signing certificate found for " + sign_call; if (sign_dxcc) { const char *entity; tqsl_getDXCCEntityName(sign_dxcc, &entity); erm += " with DXCC Entity="; erm += entity; } throw myexc(erm); } sign_cert = *list; } else if (sign_dxcc != 0) usage(); if (sign_cert) { char buf[512]; long serial; int cdxcc; if (tqsl_getCertificateIssuer(sign_cert, buf, sizeof buf)) throw tqslexc(); if (tqsl_getCertificateSerial(sign_cert, &serial)) throw tqslexc(); if (tqsl_getCertificateDXCCEntity(sign_cert, &cdxcc)) throw tqslexc(); cout << "Signing certificate issuer: " << buf << endl; cout << "Signing certificate serial: " << serial << endl; cout << " Signing certificate DXCC: " << cdxcc << endl; if (tqsl_beginSigning(sign_cert, (char *)"", 0, 0)) throw tqslexc(); } TQSL_CERT_REQ crq; memset(&crq, 0, sizeof crq); strcpy(crq.name, "Ish Kabibble"); strcpy(crq.address1, "1 No Place"); strcpy(crq.city, "City"); strcpy(crq.state, "ST"); strcpy(crq.country, "USA"); strcpy(crq.emailAddress, email_addr.c_str()); crq.dxccEntity = dxcc; tqsl_initDate(&crq.qsoNotBefore, "1945-11-15"); crq.signer = sign_cert; for (; optind < argc; optind++) { string call = argv[optind]; strcpy(crq.callSign, call.c_str()); for (char *cp = argv[optind]; *cp; cp++) { if (*cp == '/') *cp = '_'; } string filename = string(argv[optind]) + ".tq5"; cout << "Creating CRQ for " << crq.callSign << " DXCC=" << crq.dxccEntity << endl; if (tqsl_createCertRequest(filename.c_str(), &crq, 0, 0)) throw tqslexc(); } return EXIT_SUCCESS; } catch (exception& x) { cerr << "Aborting: " << x.what() << endl; return EXIT_FAILURE; } return EXIT_SUCCESS; } tqsl-2.0/src/dumptqsldata.cpp0000664000076400007640000000407012231073120016334 0ustar rmurphyrmurphy/*************************************************************************** dumptqsldata.c - description ------------------- begin : Mon Mar 3 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ /* Dumps the config data from the TQSL library */ #include #include #include "tqsllib.h" void errchk(int stat) { if (stat) { printf("ERROR: %s\n", tqsl_getErrorString()); exit(1); } } int main() { int count, i; const char *cp1, *cp2; tQSL_Date start, end; int low, high; char buf1[20], buf2[20]; errchk(tqsl_init()); puts("===== MODES =====\n Mode Group"); errchk(tqsl_getNumMode(&count)); for (i = 0; i < count; i++) { errchk(tqsl_getMode(i, &cp1, &cp2)); printf(" %-10.10s %s\n", cp1, cp2); } puts("\n===== BANDS =====\n Band Spectrum Low High"); errchk(tqsl_getNumBand(&count)); for (i = 0; i < count; i++) { errchk(tqsl_getBand(i, &cp1, &cp2, &low, &high)); printf(" %-10.10s %-8.8s %-8d %d\n", cp1, cp2, low, high); } puts("\n===== DXCC =====\n Entity Name"); errchk(tqsl_getNumDXCCEntity(&count)); for (i = 0; i < count; i++) { errchk(tqsl_getDXCCEntity(i, &low, &cp1)); printf(" %-6d %s\n", low, cp1); } puts("\n===== PROP_MODES =====\n Mode Descrip"); errchk(tqsl_getNumPropagationMode(&count)); for (i = 0; i < count; i++) { errchk(tqsl_getPropagationMode(i, &cp1, &cp2)); printf(" %-6s %s\n", cp1, cp2); } puts("\n===== SATELLITES =====\n Sat Start Date End Date Descrip"); errchk(tqsl_getNumSatellite(&count)); for (i = 0; i < count; i++) { errchk(tqsl_getSatellite(i, &cp1, &cp2, &start, &end)); buf1[0] = buf2[0] = '\0'; tqsl_convertDateToText(&start, buf1, sizeof buf1); tqsl_convertDateToText(&end, buf2, sizeof buf2); printf(" %-6s %-10s %-10s %s\n", cp1, buf1, buf2, cp2); } return 0; } tqsl-2.0/src/doxygen/0000775000076400007640000000000012231073120014601 5ustar rmurphyrmurphytqsl-2.0/src/doxygen/html/0000775000076400007640000000000012231073120015545 5ustar rmurphyrmurphytqsl-2.0/src/doxygen/html/tqsllib_8h_source.html0000664000076400007640000043716212231073120022101 0ustar rmurphyrmurphy TrustedQSL Library API: tqsllib.h Source File
tqsllib.h
Go to the documentation of this file.
1 /***************************************************************************
2  tqsllib.h - description
3  -------------------
4  begin : Mon May 20 2002
5  copyright : (C) 2002 by ARRL
6  author : Jon Bloom
7  email : jbloom@arrl.org
8  revision : $Id: tqsllib.h,v 1.14 2013/03/01 13:26:44 k1mu Exp $
9  ***************************************************************************/
10 
11 #ifndef TQSLLIB_H
12 #define TQSLLIB_H
13 
14 #if defined(_WIN32) && !defined(TQSL_NODLL)
15  #ifdef TQSLLIB_DEF
16  #define DLLEXPORT __declspec(dllexport)
17  #define DLLEXPORTDATA __declspec(dllexport)
18  #define CALLCONVENTION __stdcall
19  #else
20  #define DLLEXPORT __declspec(dllimport)
21  #define DLLEXPORTDATA __declspec(dllimport)
22  #define CALLCONVENTION __stdcall
23  #endif
24 #else
25  #define DLLEXPORT
26  #define DLLEXPORTDATA
27  #define CALLCONVENTION
28 #endif
29 
30 #include "adif.h"
31 #include "cabrillo.h"
32 
37 /* Sizes */
38 #define TQSL_MAX_PATH_LEN 256
39 #define TQSL_PASSWORD_MAX 80
40 #define TQSL_NAME_ELEMENT_MAX 256
41 #define TQSL_CALLSIGN_MAX 13
42 #define TQSL_CRQ_NAME_MAX 60
43 #define TQSL_CRQ_ADDR_MAX 80
44 #define TQSL_CRQ_CITY_MAX 80
45 #define TQSL_CRQ_STATE_MAX 80
46 #define TQSL_CRQ_POSTAL_MAX 20
47 #define TQSL_CRQ_COUNTRY_MAX 80
48 #define TQSL_CRQ_EMAIL_MAX 180
49 #define TQSL_BAND_MAX 6
50 #define TQSL_MODE_MAX 16
51 #define TQSL_FREQ_MAX 20
52 #define TQSL_SATNAME_MAX 6
53 #define TQSL_PROPMODE_MAX 6
54 
55 #define TQSL_CERT_CB_USER 0
56 #define TQSL_CERT_CB_CA 1
57 #define TQSL_CERT_CB_ROOT 2
58 #define TQSL_CERT_CB_PKEY 3
59 #define TQSL_CERT_CB_CONFIG 4
60 #define TQSL_CERT_CB_CERT_TYPE(x) ((x) & 0xf)
61 #define TQSL_CERT_CB_MILESTONE 0
62 #define TQSL_CERT_CB_RESULT 0x10
63 #define TQSL_CERT_CB_CALL_TYPE(x) ((x) & TQSL_CERT_CB_RESULT)
64 #define TQSL_CERT_CB_PROMPT 0
65 #define TQSL_CERT_CB_DUPLICATE 0x100
66 #define TQSL_CERT_CB_ERROR 0x200
67 #define TQSL_CERT_CB_LOADED 0x300
68 #define TQSL_CERT_CB_RESULT_TYPE(x) ((x) & 0x0f00)
69 
70 typedef void * tQSL_Cert;
71 typedef void * tQSL_Location;
72 typedef char * tQSL_StationDataEnc;
73 
75 typedef struct {
76  int year;
77  int month;
78  int day;
79 } tQSL_Date;
80 
82 typedef struct {
83  int hour;
84  int minute;
85  int second;
86 } tQSL_Time;
87 
89 typedef struct tqsl_provider_st {
95 
97 typedef struct tqsl_cert_req_st {
114  char renew;
115 } TQSL_CERT_REQ;
116 
118 typedef struct {
119  char callsign[TQSL_CALLSIGN_MAX+1];
120  char band[TQSL_BAND_MAX+1];
121  char mode[TQSL_MODE_MAX+1];
124  char freq[TQSL_FREQ_MAX+1];
125  char rxfreq[TQSL_FREQ_MAX+1];
126  char rxband[TQSL_BAND_MAX+1];
127  char propmode[TQSL_PROPMODE_MAX+1];
128  char satname[TQSL_SATNAME_MAX+1];
130 
132 DLLEXPORTDATA extern const char *tQSL_BaseDir;
133 
134 #ifdef __cplusplus
135 extern "C" {
136 #endif
137 
142 
143 
145 DLLEXPORTDATA extern int tQSL_Error;
151 DLLEXPORTDATA extern char tQSL_ErrorFile[256];
153 DLLEXPORTDATA extern char tQSL_CustomError[256];
155 DLLEXPORTDATA extern int tQSL_Errno;
157 DLLEXPORTDATA extern char tQSL_ImportCall[256];
158 
164 
174 DLLEXPORT int CALLCONVENTION tqsl_setDirectory(const char *dir);
175 
180 
185 DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString_v(int err);
186 
194 DLLEXPORT int CALLCONVENTION tqsl_encodeBase64(const unsigned char *data, int datalen, char *output, int outputlen);
195 
204 DLLEXPORT int CALLCONVENTION tqsl_decodeBase64(const char *input, unsigned char *data, int *datalen);
205 
212 DLLEXPORT int CALLCONVENTION tqsl_initDate(tQSL_Date *date, const char *str);
213 
220 DLLEXPORT int CALLCONVENTION tqsl_initTime(tQSL_Time *time, const char *str);
221 
232 
238 DLLEXPORT int CALLCONVENTION tqsl_subtractDates(const tQSL_Date *a, const tQSL_Date *b, int *diff);
239 
244 DLLEXPORT char* CALLCONVENTION tqsl_convertDateToText(const tQSL_Date *date, char *buf, int bufsiz);
245 
251 
257 
263 
268 DLLEXPORT char* CALLCONVENTION tqsl_convertTimeToText(const tQSL_Time *time, char *buf, int bufsiz);
269 
272 DLLEXPORT int CALLCONVENTION tqsl_getVersion(int *major, int *minor);
273 
276 DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion(int *major, int *minor);
277 
306 #define TQSL_SELECT_CERT_WITHKEYS 1
307 #define TQSL_SELECT_CERT_EXPIRED 2
308 #define TQSL_SELECT_CERT_SUPERCEDED 4
309 
310 
335 DLLEXPORT int CALLCONVENTION tqsl_selectCertificates(tQSL_Cert **certlist, int *ncerts,
336  const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flag);
337 
347 DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates(tQSL_Cert **certlist, int *ncerts, const char *type);
348 
358  int idx);
359 
363 
367 
371 
374 DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded(tQSL_Cert cert, char *buf, int bufsiz);
375 
378 DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded(tQSL_Cert cert, char *buf, int bufsiz);
379 
382 DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded(const char *callsign, const char *type, const char *keybuf, const char *certbuf);
383 
387 
391 DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt(tQSL_Cert cert, char *serial, int serialsiz);
392 
397 
407 DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer(tQSL_Cert cert, char *buf, int bufsiz);
408 
438 DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign(tQSL_Cert cert, char *buf, int bufsiz);
448 DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName(tQSL_Cert cert, char *buf, int bufsiz);
449 
459 DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress(tQSL_Cert cert, char *buf, int bufsiz);
460 
470 
480 
490 
500 
510 
522 
534 
545 DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity(tQSL_Cert cert, char *str, int bufsiz);
546 
557 DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState(tQSL_Cert cert, char *str, int bufsiz);
558 
570 
582 
583 #define TQSL_PK_TYPE_ERR 0
584 #define TQSL_PK_TYPE_NONE 1
585 #define TQSL_PK_TYPE_UNENC 2
586 #define TQSL_PK_TYPE_ENC 3
587 
588 
603 
604 
609 
610 /* int tqsl_checkCertificate(tQSL_Cert); */
611 
629 DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile(const char *file, int(*cb)(int type, const char *message, void *userdata), void *user);
630 
639 DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile(const char *file, long *serial);
640 
644 
650 
663 DLLEXPORT int CALLCONVENTION tqsl_createCertRequest(const char *filename, TQSL_CERT_REQ *req,
664  int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user);
665 
673 DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File(tQSL_Cert cert, const char *filename, const char *p12password);
674 
683 DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64(tQSL_Cert cert, char *base64, int b64len, const char *p12password);
684 
687 DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File(const char *filename, const char *p12password, const char *password,
688  int (*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type , const char *message, void *userdata), void *user);
689 
692 DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64(const char *base64, const char *p12password, const char *password,
693  int (*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type , const char *message, void *userdata), void *user);
694 
698 
721 DLLEXPORT int CALLCONVENTION tqsl_beginSigning(tQSL_Cert cert, char *password, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user);
722 
728 
734 
740 DLLEXPORT int CALLCONVENTION tqsl_signDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int *siglen);
741 
746 DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock(tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int siglen);
747 
755 DLLEXPORT int CALLCONVENTION tqsl_signQSORecord(tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *rec, unsigned char *sig, int *siglen);
756 
762 
867 /* Location field input types */
868 
869 #define TQSL_LOCATION_FIELD_TEXT 1
870 #define TQSL_LOCATION_FIELD_DDLIST 2
871 #define TQSL_LOCATION_FIELD_LIST 3
872 #define TQSL_LOCATION_FIELD_BADZONE 4
873 
874 /* Location field data types */
875 #define TQSL_LOCATION_FIELD_CHAR 1
876 #define TQSL_LOCATION_FIELD_INT 2
877 
878 
880 
886 
889 
893 
896 
902 
907 
910 
913 
916 
919 
927 
930 
933 
936 
938 DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName(tQSL_Location loc, int idx, char *buf, int bufsiz);
939 
941 DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign(tQSL_Location loc, int idx, char *buf, int bufsiz);
942 
944 DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField(tQSL_Location locp, const char *name, char *namebuf, int bufsize);
945 
951 
959 
964 
968 
970 DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations(const char *locdata);
971 
974 
977 
980 
982 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel(tQSL_Location loc, int field_num, char *buf, int bufsiz);
983 
986 
988 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI(tQSL_Location loc, int field_num, char *buf, int bufsiz);
989 
995 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType(tQSL_Location loc, int field_num, int *type);
996 
1001 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType(tQSL_Location loc, int field_num, int *type);
1002 
1011 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags(tQSL_Location loc, int field_num, int *flags);
1012 
1014 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength(tQSL_Location loc, int field_num, int *rval);
1015 
1022 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData(tQSL_Location loc, int field_num, char *buf, int bufsiz);
1023 
1029 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData(tQSL_Location loc, int field_num, int *dat);
1030 
1035 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex(tQSL_Location loc, int field_num, int *dat);
1036 
1038 DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems(tQSL_Location loc, int field_num, int *rval);
1039 
1041 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem(tQSL_Location loc, int field_num, int item_idx, char *buf, int bufsiz);
1042 
1044 DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData(tQSL_Location loc, int field_num, const char *buf);
1045 
1048 DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData(tQSL_Location loc, int field_num, int dat);
1049 
1054 DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex(tQSL_Location loc, int field_num, int dat);
1055 
1060 DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged(tQSL_Location loc, int field_num, int *changed);
1061 
1063 DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign(tQSL_Location loc, char *buf, int bufsiz);
1064 
1067 
1071 
1074 DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity(int index, int *number, const char **name);
1075 
1078 DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName(int number, const char **name);
1079 
1082 DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap(int number, const char **zonemap);
1083 
1085 DLLEXPORT int CALLCONVENTION tqsl_getNumBand(int *number);
1086 
1096 DLLEXPORT int CALLCONVENTION tqsl_getBand(int index, const char **name, const char **spectrum, int *low, int *high);
1097 
1099 DLLEXPORT int CALLCONVENTION tqsl_getNumMode(int *number);
1100 
1108 DLLEXPORT int CALLCONVENTION tqsl_getMode(int index, const char **mode, const char **group);
1109 
1112 
1120 DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode(int index, const char **name, const char **descrip);
1121 
1124 
1134 DLLEXPORT int CALLCONVENTION tqsl_getSatellite(int index, const char **name, const char **descrip,
1135  tQSL_Date *start, tQSL_Date *end);
1136 
1140 
1151 DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry(const char *contest, int field, int contest_type);
1152 
1164 DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry(const char *contest, int *fieldnum, int *contest_type);
1165 
1169 
1172 DLLEXPORT int CALLCONVENTION tqsl_setADIFMode(const char *adif_item, const char *mode);
1173 
1176 DLLEXPORT int CALLCONVENTION tqsl_getADIFMode(const char *adif_item, char *mode, int nmode);
1177 
1187 DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCERT(tQSL_Cert cert, int uid);
1188 
1199 DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItSTATION(tQSL_Location loc, int uid, int certuid);
1200 
1214  int stationuid);
1215 
1230  int stationuid, char *signdata, int sdlen);
1231 
1234 #ifdef __cplusplus
1235 }
1236 #endif
1237 
1238 /* Useful defines */
1239 #define TQSL_MAX_PW_LENGTH 32
1240 
1241 #endif /* TQSLLIB_H */
tqsl-2.0/src/doxygen/html/tqsllib_8h.html0000664000076400007640000037725412231073120020526 0ustar rmurphyrmurphy TrustedQSL Library API: tqsllib.h File Reference
tqsllib.h File Reference
#include "adif.h"
#include "cabrillo.h"

Go to the source code of this file.

Classes

struct  tQSL_Date
 
struct  tQSL_Time
 
struct  tqsl_provider_st
 
struct  tqsl_cert_req_st
 
struct  TQSL_QSO_RECORD
 

Macros

#define DLLEXPORT
 Symbol exports - Windows only.
 
#define DLLEXPORTDATA
 Symbol exports - Windows only.
 
#define CALLCONVENTION
 Symbol exports - Windows only.
 
#define TQSL_MAX_PATH_LEN   256
 Max length of a FS path.
 
#define TQSL_PASSWORD_MAX   80
 Max password length.
 
#define TQSL_NAME_ELEMENT_MAX   256
 Max Org name length.
 
#define TQSL_CALLSIGN_MAX   13
 Max callsign length.
 
#define TQSL_CRQ_NAME_MAX   60
 Max length of request name.
 
#define TQSL_CRQ_ADDR_MAX   80
 Max length of request addr.
 
#define TQSL_CRQ_CITY_MAX   80
 Max length of request city.
 
#define TQSL_CRQ_STATE_MAX   80
 Max length of request state.
 
#define TQSL_CRQ_POSTAL_MAX   20
 Max length of request zip.
 
#define TQSL_CRQ_COUNTRY_MAX   80
 Max length of req entity.
 
#define TQSL_CRQ_EMAIL_MAX   180
 Max length of req email.
 
#define TQSL_BAND_MAX   6
 Max length of a band name.
 
#define TQSL_MODE_MAX   16
 Max length of a mode name.
 
#define TQSL_FREQ_MAX   20
 Max length of a frequency.
 
#define TQSL_SATNAME_MAX   6
 Max length of a sat name.
 
#define TQSL_PROPMODE_MAX   6
 Max length of a prop mode.
 
#define TQSL_CERT_CB_USER   0
 Callback is for user cert.
 
#define TQSL_CERT_CB_CA   1
 Callback is for CA cert.
 
#define TQSL_CERT_CB_ROOT   2
 Callback is for root cert.
 
#define TQSL_CERT_CB_PKEY   3
 Callback is for private key.
 
#define TQSL_CERT_CB_CONFIG   4
 Callback for config file.
 
#define TQSL_CERT_CB_CERT_TYPE(x)   ((x) & 0xf)
 Type of the cert.
 
#define TQSL_CERT_CB_MILESTONE   0
 New certificate.
 
#define TQSL_CERT_CB_RESULT   0x10
 Cert import result.
 
#define TQSL_CERT_CB_CALL_TYPE(x)   ((x) & TQSL_CERT_CB_RESULT)
 Callback type.
 
#define TQSL_CERT_CB_PROMPT   0
 Callback prompt.
 
#define TQSL_CERT_CB_DUPLICATE   0x100
 Dupe cert callback.
 
#define TQSL_CERT_CB_ERROR   0x200
 Error import callback.
 
#define TQSL_CERT_CB_LOADED   0x300
 Cert loaded callback.
 
#define TQSL_CERT_CB_RESULT_TYPE(x)   ((x) & 0x0f00)
 Result type mask.
 
#define TQSL_SELECT_CERT_WITHKEYS   1
 Private keys only (no cert)
 
#define TQSL_SELECT_CERT_EXPIRED   2
 Include expired certs.
 
#define TQSL_SELECT_CERT_SUPERCEDED   4
 Include superseded certs.
 
#define TQSL_PK_TYPE_ERR   0
 Error retrieving private key.
 
#define TQSL_PK_TYPE_NONE   1
 No private key.
 
#define TQSL_PK_TYPE_UNENC   2
 Private key is not encrypted.
 
#define TQSL_PK_TYPE_ENC   3
 Private key is encrypted.
 
#define TQSL_LOCATION_FIELD_TEXT   1
 Text type input field.
 
#define TQSL_LOCATION_FIELD_DDLIST   2
 Dropdown list input field.
 
#define TQSL_LOCATION_FIELD_LIST   3
 List type input field.
 
#define TQSL_LOCATION_FIELD_BADZONE   4
 Used to return zone selection errors.
 
#define TQSL_LOCATION_FIELD_CHAR   1
 Character field.
 
#define TQSL_LOCATION_FIELD_INT   2
 Integer field.
 
#define TQSL_MAX_PW_LENGTH   32
 Password buffer length.
 

Typedefs

typedef void * tQSL_Cert
 Opaque certificate type.
 
typedef void * tQSL_Location
 Opaque location type.
 
typedef char * tQSL_StationDataEnc
 Opaque station data type.
 
typedef struct tqsl_provider_st TQSL_PROVIDER
 
typedef struct tqsl_cert_req_st TQSL_CERT_REQ
 

Functions

DLLEXPORT int CALLCONVENTION tqsl_init ()
 
DLLEXPORT int CALLCONVENTION tqsl_setDirectory (const char *dir)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getErrorString ()
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getErrorString_v (int err)
 
DLLEXPORT int CALLCONVENTION tqsl_encodeBase64 (const unsigned char *data, int datalen, char *output, int outputlen)
 
DLLEXPORT int CALLCONVENTION tqsl_decodeBase64 (const char *input, unsigned char *data, int *datalen)
 
DLLEXPORT int CALLCONVENTION tqsl_initDate (tQSL_Date *date, const char *str)
 
DLLEXPORT int CALLCONVENTION tqsl_initTime (tQSL_Time *time, const char *str)
 
DLLEXPORT int CALLCONVENTION tqsl_compareDates (const tQSL_Date *a, const tQSL_Date *b)
 
DLLEXPORT int CALLCONVENTION tqsl_subtractDates (const tQSL_Date *a, const tQSL_Date *b, int *diff)
 
DLLEXPORT char *CALLCONVENTION tqsl_convertDateToText (const tQSL_Date *date, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_isDateValid (const tQSL_Date *d)
 
DLLEXPORT int CALLCONVENTION tqsl_isDateNull (const tQSL_Date *d)
 
DLLEXPORT int CALLCONVENTION tqsl_isTimeValid (const tQSL_Time *t)
 
DLLEXPORT char *CALLCONVENTION tqsl_convertTimeToText (const tQSL_Time *time, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getVersion (int *major, int *minor)
 
DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion (int *major, int *minor)
 
DLLEXPORT int CALLCONVENTION tqsl_selectCertificates (tQSL_Cert **certlist, int *ncerts, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flag)
 
DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates (tQSL_Cert **certlist, int *ncerts, const char *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getSelectedCertificate (tQSL_Cert *cert, const tQSL_Cert **certlist, int idx)
 
DLLEXPORT int CALLCONVENTION tqsl_isCertificateExpired (tQSL_Cert cert, int *status)
 
DLLEXPORT int CALLCONVENTION tqsl_isCertificateSuperceded (tQSL_Cert cert, int *status)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateKeyOnly (tQSL_Cert cert, int *keyonly)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded (const char *callsign, const char *type, const char *keybuf, const char *certbuf)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerial (tQSL_Cert cert, long *serial)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt (tQSL_Cert cert, char *serial, int serialsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialLength (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganization (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganizationalUnit (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotBeforeDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotAfterDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotBeforeDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotAfterDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateDXCCEntity (tQSL_Cert cert, int *dxcc)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress1 (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress2 (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestPostalCode (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCountry (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificatePrivateKeyType (tQSL_Cert cert)
 
DLLEXPORT void CALLCONVENTION tqsl_freeCertificate (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile (const char *file, int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile (const char *file, long *serial)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumProviders (int *n)
 
DLLEXPORT int CALLCONVENTION tqsl_getProvider (int idx, TQSL_PROVIDER *provider)
 
DLLEXPORT int CALLCONVENTION tqsl_createCertRequest (const char *filename, TQSL_CERT_REQ *req, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File (tQSL_Cert cert, const char *filename, const char *p12password)
 
DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64 (tQSL_Cert cert, char *base64, int b64len, const char *p12password)
 
DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File (const char *filename, const char *p12password, const char *password, int(*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64 (const char *base64, const char *p12password, const char *password, int(*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_deleteCertificate (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_beginSigning (tQSL_Cert cert, char *password, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_checkSigningStatus (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_getMaxSignatureSize (tQSL_Cert cert, int *sigsize)
 
DLLEXPORT int CALLCONVENTION tqsl_signDataBlock (tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int *siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock (tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_signQSORecord (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *rec, unsigned char *sig, int *siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_endSigning (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_initStationLocationCapture (tQSL_Location *locp)
 
DLLEXPORT int CALLCONVENTION tqsl_endStationLocationCapture (tQSL_Location *locp)
 
DLLEXPORT int CALLCONVENTION tqsl_updateStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocationCapturePages (tQSL_Location loc, int *npages)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCapturePage (tQSL_Location loc, int *page)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCapturePage (tQSL_Location loc, int page)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCertFlags (tQSL_Location loc, int flags)
 
DLLEXPORT int CALLCONVENTION tqsl_nextStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_prevStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_hasNextStationLocationCapture (tQSL_Location loc, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_hasPrevStationLocationCapture (tQSL_Location loc, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_saveStationLocationCapture (tQSL_Location loc, int overwrite)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCaptureName (tQSL_Location loc, char *namebuf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCaptureName (tQSL_Location loc, const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocations (tQSL_Location loc, int *nloc)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName (tQSL_Location loc, int idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign (tQSL_Location loc, int idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField (tQSL_Location locp, const char *name, char *namebuf, int bufsize)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocation (tQSL_Location *loc, const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationErrors (tQSL_Location loc, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationDataEnc (tQSL_StationDataEnc *sdata)
 
DLLEXPORT int CALLCONVENTION tqsl_freeStationDataEnc (tQSL_StationDataEnc sdata)
 
DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations (const char *locdata)
 
DLLEXPORT int CALLCONVENTION tqsl_deleteStationLocation (const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumLocationField (tQSL_Location loc, int *numf)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabelSize (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBISize (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType (tQSL_Location loc, int field_num, int *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType (tQSL_Location loc, int field_num, int *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags (tQSL_Location loc, int field_num, int *flags)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData (tQSL_Location loc, int field_num, int *dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex (tQSL_Location loc, int field_num, int *dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem (tQSL_Location loc, int field_num, int item_idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData (tQSL_Location loc, int field_num, const char *buf)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData (tQSL_Location loc, int field_num, int dat)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex (tQSL_Location loc, int field_num, int dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged (tQSL_Location loc, int field_num, int *changed)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign (tQSL_Location loc, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationDXCCEntity (tQSL_Location loc, int *dxcc)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumDXCCEntity (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity (int index, int *number, const char **name)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName (int number, const char **name)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap (int number, const char **zonemap)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumBand (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getBand (int index, const char **name, const char **spectrum, int *low, int *high)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumMode (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getMode (int index, const char **mode, const char **group)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumPropagationMode (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode (int index, const char **name, const char **descrip)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumSatellite (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getSatellite (int index, const char **name, const char **descrip, tQSL_Date *start, tQSL_Date *end)
 
DLLEXPORT int CALLCONVENTION tqsl_clearCabrilloMap ()
 
DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry (const char *contest, int field, int contest_type)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry (const char *contest, int *fieldnum, int *contest_type)
 
DLLEXPORT int CALLCONVENTION tqsl_clearADIFModes ()
 
DLLEXPORT int CALLCONVENTION tqsl_setADIFMode (const char *adif_item, const char *mode)
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFMode (const char *adif_item, char *mode, int nmode)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCERT (tQSL_Cert cert, int uid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItSTATION (tQSL_Location loc, int uid, int certuid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCONTACT (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCONTACTData (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid, char *signdata, int sdlen)
 

Variables

DLLEXPORTDATA const char * tQSL_BaseDir
 Base directory for tQSL library working files.
 
DLLEXPORTDATA int tQSL_Error
 Error code from most recent tQSL library call. More...
 
DLLEXPORTDATA
TQSL_ADIF_GET_FIELD_ERROR 
tQSL_ADIF_Error
 The ADIF error code.
 
DLLEXPORTDATA
TQSL_CABRILLO_ERROR_TYPE 
tQSL_Cabrillo_Error
 The ADIF error code.
 
DLLEXPORTDATA char tQSL_ErrorFile [256]
 File name of file giving error. (May be empty.)
 
DLLEXPORTDATA char tQSL_CustomError [256]
 Custom error message string.
 
DLLEXPORTDATA int tQSL_Errno
 System errno - stored when tQSL_Error == TQSL_SYSTEM_ERROR.
 
DLLEXPORTDATA char tQSL_ImportCall [256]
 Callsign used in import - used for missing public key error.
 

Detailed Description

tQSL library functions.

Typedef Documentation

Certificate request data

Certificate provider data

tqsl-2.0/src/doxygen/html/tqsllib.css0000664000076400007640000000211612231073120017731 0ustar rmurphyrmurphyBODY { font-family: Helvetica,Arial,sans-serif; font-size: small } H1 { text-align: center; font-size: x-large } H2 { font-size: large } CODE { font-size: medium } A.qindex {} A.qindexRef {} A.el { text-decoration: none; font-weight: bold; } A.elRef { font-weight: bold } A.code { text-decoration: none; font-weight: normal; color: #4444ee } A.codeRef { font-weight: normal; color: #4444ee } A:link { color: #0000ff } A:visited { color: #0066cc } DL.el { margin-left: -1cm } DIV.fragment { width: 100%; border: none; background-color: #eeeeee } DIV.ah { background-color: black; margin-bottom: 3; margin-top: 3 } TD.md { background-color: #f2f2ff } DIV.groupHeader { margin-left: 16; margin-top: 12; margin-bottom: 6; font-weight: bold } DIV.groupText { margin-left: 16; font-style: italic; font-size: smaller } FONT.keyword { color: #008000 } FONT.keywordtype { color: #604020 } FONT.keywordflow { color: #e08000 } FONT.comment { color: #800000 } FONT.preprocessor { color: #806020 } FONT.stringliteral { color: #002080 } FONT.charliteral { color: #008080 } TD { font-size: small } tqsl-2.0/src/doxygen/html/tqsllib-doc_8h_source.html0000664000076400007640000000705712231073120022640 0ustar rmurphyrmurphy TrustedQSL Library API: tqsllib-doc.h Source File
tqsllib-doc.h
1 /***************************************************************************
2  tqsllib-doc.h - description
3  -------------------
4  begin : Tue Jun 4 2002
5  copyright : (C) 2002 by ARRL
6  author : Jon Bloom
7  email : jbloom@arrl.org
8  revision : $Id$
9  ***************************************************************************/
10 
tqsl-2.0/src/doxygen/html/tqslerrno_8h_source.html0000664000076400007640000003106112231073120022444 0ustar rmurphyrmurphy TrustedQSL Library API: tqslerrno.h Source File
tqslerrno.h
Go to the documentation of this file.
1 /***************************************************************************
2  tqslerrno.h - description
3  -------------------
4  begin : Tue May 28 2002
5  copyright : (C) 2002 by ARRL
6  author : Jon Bloom
7  email : jbloom@arrl.org
8  revision : $Id$
9  ***************************************************************************/
10 
11 #ifndef __TQSLERRNO_H
12 #define __TQSLERRNO_H
13 
18 #define TQSL_NO_ERROR 0
19 #define TQSL_SYSTEM_ERROR 1
20 #define TQSL_OPENSSL_ERROR 2
21 #define TQSL_ADIF_ERROR 3
22 #define TQSL_CUSTOM_ERROR 4
23 #define TQSL_CABRILLO_ERROR 5
24 #define TQSL_OPENSSL_VERSION_ERROR 6
25 #define TQSL_ERROR_ENUM_BASE 16
26 #define TQSL_ALLOC_ERROR 16
27 #define TQSL_RANDOM_ERROR 17
28 #define TQSL_ARGUMENT_ERROR 18
29 #define TQSL_OPERATOR_ABORT 19
30 #define TQSL_NOKEY_ERROR 20
31 #define TQSL_BUFFER_ERROR 21
32 #define TQSL_INVALID_DATE 22
33 #define TQSL_SIGNINIT_ERROR 23
34 #define TQSL_PASSWORD_ERROR 24
35 #define TQSL_EXPECTED_NAME 25
36 #define TQSL_NAME_EXISTS 26
37 #define TQSL_NAME_NOT_FOUND 27
38 #define TQSL_INVALID_TIME 28
39 #define TQSL_CERT_DATE_MISMATCH 29
40 #define TQSL_PROVIDER_NOT_FOUND 30
41 #define TQSL_CERT_KEY_ONLY 31
42 #define TQSL_CONFIG_ERROR 32
43 #define TQSL_CERT_NOT_FOUND 33
44 #define TQSL_PKCS12_ERROR 34
45 #define TQSL_CERT_TYPE_ERROR 35
46 #define TQSL_DATE_OUT_OF_RANGE 36
47 #define TQSL_DUPLICATE_QSO 37
48 #define TQSL_DB_ERROR 38
49 #define TQSL_LOCATION_NOT_FOUND 39
50 #define TQSL_CALL_NOT_FOUND 40
51 #define TQSL_CONFIG_SYNTAX_ERROR 41
52 #define TQSL_FILE_SYSTEM_ERROR 42
53 #define TQSL_FILE_SYNTAX_ERROR 43
54 
55 #endif /* __TQSLERRNO_H */
tqsl-2.0/src/doxygen/html/tqslerrno_8h.html0000664000076400007640000006041012231073120021064 0ustar rmurphyrmurphy TrustedQSL Library API: tqslerrno.h File Reference
tqslerrno.h File Reference

Go to the source code of this file.

Macros

#define TQSL_NO_ERROR   0
 No error.
 
#define TQSL_SYSTEM_ERROR   1
 System Error.
 
#define TQSL_OPENSSL_ERROR   2
 Error in OpenSSL calls.
 
#define TQSL_ADIF_ERROR   3
 ADIF Errors.
 
#define TQSL_CUSTOM_ERROR   4
 Custom errors - output to tQSL_CustomError.
 
#define TQSL_CABRILLO_ERROR   5
 Cabrillo handler error.
 
#define TQSL_OPENSSL_VERSION_ERROR   6
 OpenSSL version obsolete.
 
#define TQSL_ERROR_ENUM_BASE   16
 Base for enumerated errors.
 
#define TQSL_ALLOC_ERROR   16
 Memory allocation error.
 
#define TQSL_RANDOM_ERROR   17
 Error initializing random number generator.
 
#define TQSL_ARGUMENT_ERROR   18
 Invalid arguments.
 
#define TQSL_OPERATOR_ABORT   19
 Aborted by operator.
 
#define TQSL_NOKEY_ERROR   20
 No key available.
 
#define TQSL_BUFFER_ERROR   21
 Insufficient buffer space.
 
#define TQSL_INVALID_DATE   22
 Date string invalid.
 
#define TQSL_SIGNINIT_ERROR   23
 Error initializing signing routine.
 
#define TQSL_PASSWORD_ERROR   24
 Invalid password.
 
#define TQSL_EXPECTED_NAME   25
 Name expected but not supplied.
 
#define TQSL_NAME_EXISTS   26
 Entity name exists already.
 
#define TQSL_NAME_NOT_FOUND   27
 Entity name does not exist.
 
#define TQSL_INVALID_TIME   28
 Time format is invalid.
 
#define TQSL_CERT_DATE_MISMATCH   29
 Certificate date mismatch.
 
#define TQSL_PROVIDER_NOT_FOUND   30
 Certificate provider unknown.
 
#define TQSL_CERT_KEY_ONLY   31
 No signed public key is installed.
 
#define TQSL_CONFIG_ERROR   32
 There is an error in the configuration file.
 
#define TQSL_CERT_NOT_FOUND   33
 The certificate could not be found.
 
#define TQSL_PKCS12_ERROR   34
 There is an error parsing the .p12 file.
 
#define TQSL_CERT_TYPE_ERROR   35
 The certificate type is invalid.
 
#define TQSL_DATE_OUT_OF_RANGE   36
 The date is out of the valid range.
 
#define TQSL_DUPLICATE_QSO   37
 This QSO is a duplicate.
 
#define TQSL_DB_ERROR   38
 The dupe database could not be accessed.
 
#define TQSL_LOCATION_NOT_FOUND   39
 The station location is invalid.
 
#define TQSL_CALL_NOT_FOUND   40
 The callsign could not be located.
 
#define TQSL_CONFIG_SYNTAX_ERROR   41
 The config file has a syntax error.
 
#define TQSL_FILE_SYSTEM_ERROR   42
 There was a file system I/O error.
 
#define TQSL_FILE_SYNTAX_ERROR   43
 The file format is invalid.
 

Detailed Description

tQSL_Error values

tqsl-2.0/src/doxygen/html/tqslconvert_8h_source.html0000664000076400007640000004571012231073120023005 0ustar rmurphyrmurphy TrustedQSL Library API: tqslconvert.h Source File
tqslconvert.h
Go to the documentation of this file.
1 /***************************************************************************
2  convert.h - description
3  -------------------
4  begin : Sun Nov 17 2002
5  copyright : (C) 2002 by ARRL
6  author : Jon Bloom
7  email : jbloom@arrl.org
8  revision : $Id$
9  ***************************************************************************/
10 
11 #ifndef __tqslconvert_h
12 #define __tqslconvert_h
13 
14 #include "tqsllib.h"
15 
27 typedef void * tQSL_Converter;
28 
29 
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
42 
52 DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter(tQSL_Converter *conv, const char *filename,
53  tQSL_Cert *certs, int ncerts, tQSL_Location loc);
54 
65  tQSL_Cert *certs, int ncerts, tQSL_Location loc);
66 
69 
79 
89 
97 
105 
112 
120 tqsl_getDuplicateRecords(tQSL_Converter convp, char *key, char *data, int keylen);
121 
129 tqsl_putDuplicateRecord(tQSL_Converter convp, const char *key, const char *data, int keylen);
130 
140  tQSL_Date *end);
141 
164 
167 
171 
177 
180 #ifdef __cplusplus
181 }
182 #endif
183 
184 #endif /* __tqslconvert_h */
185 
tqsl-2.0/src/doxygen/html/tqslconvert_8h.html0000664000076400007640000003456712231073120021435 0ustar rmurphyrmurphy TrustedQSL Library API: tqslconvert.h File Reference
tqslconvert.h File Reference
#include "tqsllib.h"

Go to the source code of this file.

Typedefs

typedef void * tQSL_Converter
 

Functions

DLLEXPORT int CALLCONVENTION tqsl_beginConverter (tQSL_Converter *convp)
 
DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter (tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_beginCabrilloConverter (tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_endConverter (tQSL_Converter *conv)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowBadCall (tQSL_Converter conv, int allow)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowDuplicates (tQSL_Converter convp, int allow)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAppName (tQSL_Converter convp, const char *app)
 
DLLEXPORT int CALLCONVENTION tqsl_converterRollBack (tQSL_Converter convp)
 
DLLEXPORT int CALLCONVENTION tqsl_converterCommit (tQSL_Converter convp)
 
DLLEXPORT int CALLCONVENTION tqsl_getDuplicateRecords (tQSL_Converter convp, char *key, char *data, int keylen)
 
DLLEXPORT int CALLCONVENTION tqsl_putDuplicateRecord (tQSL_Converter convp, const char *key, const char *data, int keylen)
 
DLLEXPORT int CALLCONVENTION tqsl_setADIFConverterDateFilter (tQSL_Converter conv, tQSL_Date *start, tQSL_Date *end)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getConverterGABBI (tQSL_Converter conv)
 
DLLEXPORT int CALLCONVENTION tqsl_getConverterCert (tQSL_Converter conv, tQSL_Cert *certp)
 
DLLEXPORT int CALLCONVENTION tqsl_getConverterLine (tQSL_Converter conv, int *lineno)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getConverterRecordText (tQSL_Converter conv)
 

Detailed Description

tQSL library converter functions.

tqsl-2.0/src/doxygen/html/tabs.css0000664000076400007640000000221312231073120017206 0ustar rmurphyrmurphy.tabs, .tabs2, .tabs3 { background-image: url('tab_b.png'); width: 100%; z-index: 101; font-size: 13px; font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; } .tabs2 { font-size: 10px; } .tabs3 { font-size: 9px; } .tablist { margin: 0; padding: 0; display: table; } .tablist li { float: left; display: table-cell; background-image: url('tab_b.png'); line-height: 36px; list-style: none; } .tablist a { display: block; padding: 0 20px; font-weight: bold; background-image:url('tab_s.png'); background-repeat:no-repeat; background-position:right; color: #283A5D; text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); text-decoration: none; outline: none; } .tabs3 .tablist a { padding: 0 10px; } .tablist a:hover { background-image: url('tab_h.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); text-decoration: none; } .tablist li.current a { background-image: url('tab_a.png'); background-repeat:repeat-x; color: #fff; text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); } tqsl-2.0/src/doxygen/html/tab_s.png0000664000076400007640000000027012231073120017342 0ustar rmurphyrmurphyPNG  IHDR$[IDATx݁ @@ѣ?Q"%If6[HQ<]dr s?O=w'F -~rÍ[芭m֬ݯнF)Y% `n,9B!ь\<#IENDB`tqsl-2.0/src/doxygen/html/tab_h.png0000664000076400007640000000026112231073120017327 0ustar rmurphyrmurphyPNG  IHDR$[xIDATxM@~ΒEv"!d*rGq={SݧH uO^[_Xvyұ=VCff{R%_rug(?gh\i>|sIENDB`tqsl-2.0/src/doxygen/html/tab_b.png0000664000076400007640000000025112231073120017320 0ustar rmurphyrmurphyPNG  IHDR$[pIDATxM EǻԸu`V0}:t]Ds䮂u|x>1&m8SxLU޲iEOsnxKN~jIENDB`tqsl-2.0/src/doxygen/html/tab_a.png0000664000076400007640000000021612231073120017320 0ustar rmurphyrmurphyPNG  IHDR$[UIDATxK 0C'o([Ž%x#٩ We# 3t I 3+E~\D9wM}Y_A4Y}IENDB`tqsl-2.0/src/doxygen/html/sync_on.png0000664000076400007640000000151512231073120017725 0ustar rmurphyrmurphyPNG  IHDRw=IDATx_HTY8i4-g6&kQ)!0URKڅ/PE>K-+K.YdEPaAZSܝ;3wgfsWK.Da'q_k DQCg 0Y:qZ)~L0HV z-C%g68%wUϿ }? ?3 K@h aaUe s~2&&B*Alji*˨,oƣT,d[3-*> LɟfkҠw#*AEjKUy>&{8m5Ki jjD*Nigw7DmzK۾M!k?o_lX#~XӑR*EՂדE;6e"Q(=Ezæ5Kؼָ_ 1zBJ X96jL^7{J1i@%8'7M_\Q#Uy Wo x8sv|Sn q_m >b[JX,4[T{Ratjjzz'ȶiIws KC^Y%6ꈺ]vhiWvh'̂|[^YrD=ѝlU_?]Y(N8f1qn-etm 0}b%׌=0?1s08;_ W|%\Zð >舽lnp.a{ )t; b n652?>Oдunm`׭ZWjC~>־0+ {{fMŕټ` ݛ%uA6,]kWu]7ihu1 l Ҷ̺:\cxhRQt$ fd<4B[fd7=.M9//O a},j?.5ښm?X2#d p(?c!a1ޗةܾ7dK:)3],H+ku<|`LhC7e םt H$^2%l.aeÉ|s }D^hz~Rá]|#@חև[k<|(*ݹdtM:,]' X_n| /cfOIENDB`tqsl-2.0/src/doxygen/html/structtqsl__provider__st.html0000664000076400007640000001263012231073120023603 0ustar rmurphyrmurphy TrustedQSL Library API: tqsl_provider_st Struct Reference
tqsl_provider_st Struct Reference

#include <tqsllib.h>

Public Attributes

char organizationName [TQSL_NAME_ELEMENT_MAX+1]
 Provider name.
 
char organizationalUnitName [TQSL_NAME_ELEMENT_MAX+1]
 Provider unit.
 
char emailAddress [TQSL_NAME_ELEMENT_MAX+1]
 Provider e-mail.
 
char url [TQSL_NAME_ELEMENT_MAX+1]
 Provider URL.
 

Detailed Description

Certificate provider data


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtqsl__provider__st-members.html0000664000076400007640000000630312231073120025233 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tqsl_provider_st Member List
tqsl-2.0/src/doxygen/html/structtqsl__cert__req__st.html0000664000076400007640000003426412231073120023723 0ustar rmurphyrmurphy TrustedQSL Library API: tqsl_cert_req_st Struct Reference
tqsl_cert_req_st Struct Reference

#include <tqsllib.h>

Public Attributes

char providerName [TQSL_NAME_ELEMENT_MAX+1]
 < Cert request data More...
 
char providerUnit [TQSL_NAME_ELEMENT_MAX+1]
 Provider unit.
 
char callSign [TQSL_CALLSIGN_MAX+1]
 Callsign.
 
char name [TQSL_CRQ_NAME_MAX+1]
 Name.
 
char address1 [TQSL_CRQ_ADDR_MAX+1]
 Address 1.
 
char address2 [TQSL_CRQ_ADDR_MAX+1]
 Address 2.
 
char city [TQSL_CRQ_CITY_MAX+1]
 City.
 
char state [TQSL_CRQ_STATE_MAX+1]
 State.
 
char postalCode [TQSL_CRQ_POSTAL_MAX+1]
 Postal Code.
 
char country [TQSL_CRQ_COUNTRY_MAX+1]
 Country.
 
char emailAddress [TQSL_CRQ_EMAIL_MAX+1]
 e-mail
 
int dxccEntity
 DXCC Entity code.
 
tQSL_Date qsoNotBefore
 QSOs not before date.
 
tQSL_Date qsoNotAfter
 QSOs not after date.
 
char password [TQSL_PASSWORD_MAX+1]
 Password.
 
tQSL_Cert signer
 Signing cert.
 
char renew
 Rewewal reference.
 

Detailed Description

Certificate request data

Member Data Documentation

char tqsl_cert_req_st::providerName[TQSL_NAME_ELEMENT_MAX+1]

< Cert request data

Provider name


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtqsl__cert__req__st-members.html0000664000076400007640000001472712231073120025355 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tqsl_cert_req_st Member List
tqsl-2.0/src/doxygen/html/structtqsl__cabrilloField.html0000664000076400007640000001141212231073120023634 0ustar rmurphyrmurphy TrustedQSL Library API: tqsl_cabrilloField Struct Reference
tqsl_cabrilloField Struct Reference

#include <cabrillo.h>

Public Attributes

char name [TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX+1]
 < Cabrillo field More...
 
char value [TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX+1]
 Field value.
 

Detailed Description

Cabrillo field data:

  • name - ADIF field name
  • value - Field content

Member Data Documentation

char tqsl_cabrilloField::name[TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX+1]

< Cabrillo field

Field name


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtqsl__cabrilloField-members.html0000664000076400007640000000526512231073120025275 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tqsl_cabrilloField Member List

This is the complete list of members for tqsl_cabrilloField, including all inherited members.

nametqsl_cabrilloField
valuetqsl_cabrilloField
tqsl-2.0/src/doxygen/html/structtqsl__adifFieldResults.html0000664000076400007640000001504112231073120024334 0ustar rmurphyrmurphy TrustedQSL Library API: tqsl_adifFieldResults Struct Reference
tqsl_adifFieldResults Struct Reference

#include <adif.h>

Public Attributes

char name [TQSL_ADIF_FIELD_NAME_LENGTH_MAX+1]
 Field name.
 
char size [TQSL_ADIF_FIELD_SIZE_LENGTH_MAX+1]
 Size.
 
char type [TQSL_ADIF_FIELD_TYPE_LENGTH_MAX+1]
 Type.
 
unsigned char * data
 data
 
unsigned int adifNameIndex
 Name index.
 
void * userPointer
 User pointer.
 

Detailed Description

Field returned from parsing


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtqsl__adifFieldResults-members.html0000664000076400007640000000740112231073120025765 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tqsl_adifFieldResults Member List
tqsl-2.0/src/doxygen/html/structtqsl__adifFieldDefinitions.html0000664000076400007640000001736212231073120025156 0ustar rmurphyrmurphy TrustedQSL Library API: tqsl_adifFieldDefinitions Struct Reference
tqsl_adifFieldDefinitions Struct Reference

#include <adif.h>

Public Attributes

char name [TQSL_ADIF_FIELD_NAME_LENGTH_MAX+1]
 Field name.
 
char type [TQSL_ADIF_FIELD_TYPE_LENGTH_MAX+1]
 Field type.
 
TQSL_ADIF_RANGE_TYPE rangeType
 Range type.
 
unsigned int max_length
 Max length.
 
long signed min_value
 Min value.
 
long signed max_value
 Max value.
 
const char ** enumStrings
 Enumerated values.
 
void * userPointer
 user poitner
 

Detailed Description

An ADIF field definition


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtqsl__adifFieldDefinitions-members.html0000664000076400007640000001062112231073120026575 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tqsl_adifFieldDefinitions Member List
tqsl-2.0/src/doxygen/html/structtQSL__Time.html0000664000076400007640000001057012231073120021643 0ustar rmurphyrmurphy TrustedQSL Library API: tQSL_Time Struct Reference
tQSL_Time Struct Reference

#include <tqsllib.h>

Public Attributes

int hour
 Time hour field.
 
int minute
 Time minute field.
 
int second
 Time seconds field.
 

Detailed Description

Struct that holds h-m-s


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtQSL__Time-members.html0000664000076400007640000000552212231073120023274 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tQSL_Time Member List

This is the complete list of members for tQSL_Time, including all inherited members.

hourtQSL_Time
minutetQSL_Time
secondtQSL_Time
tqsl-2.0/src/doxygen/html/structtQSL__Date.html0000664000076400007640000001054612231073120021625 0ustar rmurphyrmurphy TrustedQSL Library API: tQSL_Date Struct Reference
tQSL_Date Struct Reference

#include <tqsllib.h>

Public Attributes

int year
 Numeric year.
 
int month
 Numeric month.
 
int day
 Numeric day.
 

Detailed Description

Struct that holds y-m-d


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structtQSL__Date-members.html0000664000076400007640000000551612231073120023256 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
tQSL_Date Member List

This is the complete list of members for tQSL_Date, including all inherited members.

daytQSL_Date
monthtQSL_Date
yeartQSL_Date
tqsl-2.0/src/doxygen/html/structTQSL__QSO__RECORD.html0000664000076400007640000002225412231073120022546 0ustar rmurphyrmurphy TrustedQSL Library API: TQSL_QSO_RECORD Struct Reference
TQSL_QSO_RECORD Struct Reference

#include <tqsllib.h>

Public Attributes

char callsign [TQSL_CALLSIGN_MAX+1]
 QSO callsign.
 
char band [TQSL_BAND_MAX+1]
 QSO band.
 
char mode [TQSL_MODE_MAX+1]
 QSO mode.
 
tQSL_Date date
 QSO date.
 
tQSL_Time time
 QSO time.
 
char freq [TQSL_FREQ_MAX+1]
 QSO frequency.
 
char rxfreq [TQSL_FREQ_MAX+1]
 QSO receive frequency.
 
char rxband [TQSL_BAND_MAX+1]
 QSO RX band.
 
char propmode [TQSL_PROPMODE_MAX+1]
 QSO prop mode.
 
char satname [TQSL_SATNAME_MAX+1]
 QSO satellite name.
 

Detailed Description

QSO data


The documentation for this struct was generated from the following file:
tqsl-2.0/src/doxygen/html/structTQSL__QSO__RECORD-members.html0000664000076400007640000001116112231073120024171 0ustar rmurphyrmurphy TrustedQSL Library API: Member List
TQSL_QSO_RECORD Member List
tqsl-2.0/src/doxygen/html/open.png0000664000076400007640000000017312231073120017215 0ustar rmurphyrmurphyPNG  IHDR BIDATx 0 ׬ՙ\39b!9{|I>$#ߴ8/z/>2[giU,/~\ 9ٸIENDB`tqsl-2.0/src/doxygen/html/nav_h.png0000664000076400007640000000014212231073120017343 0ustar rmurphyrmurphyPNG  IHDR ,@)IDATxA @BQۛТ) ) aܿoRlIENDB`tqsl-2.0/src/doxygen/html/nav_g.png0000664000076400007640000000015412231073120017345 0ustar rmurphyrmurphyPNG  IHDRrcf3IDATxݡ O@C0:B%#GdLrERq˱/9iDNIENDB`tqsl-2.0/src/doxygen/html/nav_f.png0000664000076400007640000000023112231073120017340 0ustar rmurphyrmurphyPNG  IHDR8`IDATxK Eі[BmkHprӼ.ꎤR6Z VIE5jliIJ0/u޿6sH yIENDB`tqsl-2.0/src/doxygen/html/modules.html0000664000076400007640000000642312231073120020110 0ustar rmurphyrmurphy TrustedQSL Library API: Modules
TrustedQSL Library API
Modules
tqsl-2.0/src/doxygen/html/jquery.js0000664000076400007640000026726112231073120017440 0ustar rmurphyrmurphy/*! jQuery v1.7.1 jquery.com | jquery.org/license */ (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")), f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c) {if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); tqsl-2.0/src/doxygen/html/index.html0000664000076400007640000000742512231073120017552 0ustar rmurphyrmurphy TrustedQSL Library API: Main Page
TrustedQSL Library API
TrustedQSL Library API Documentation

The TrustedQSL library API is divided into several groups:

  • Certificate Handling API - Request, load and retrieve digital certificates
  • Data API - Manage station-location data and produce signed data records
  • Converter API - Convert and sign ADIF and Cabrillo log files
  • Utility API - Functions to operate on objects, set system parameters, and report errors
  • Signing API - Low-level digital signing
  • ADIF API - Low-level parsing and creation of ADIF files
  • Cabrillo API - Low-level parsing of Cabrillo files.

Most of the library functions return an integer value that is zero if there is no error and 1 if there is an error. The specific error can be determined by examining tQSL_Error and, possibly, tQSL_ADIF_Error, tQSL_Cabrillo_Error, tQSL_ErrorFile and tQSL_CustomError. The tqsl_getErrorString() and tqsl_getErrorString_v() functions can be used to get error text strings.

tqsl-2.0/src/doxygen/html/group__Util.html0000664000076400007640000010744512231073120020736 0ustar rmurphyrmurphy TrustedQSL Library API: Utility API
TrustedQSL Library API
Utility API

Functions

DLLEXPORT int CALLCONVENTION tqsl_init ()
 
DLLEXPORT int CALLCONVENTION tqsl_setDirectory (const char *dir)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getErrorString ()
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getErrorString_v (int err)
 
DLLEXPORT int CALLCONVENTION tqsl_encodeBase64 (const unsigned char *data, int datalen, char *output, int outputlen)
 
DLLEXPORT int CALLCONVENTION tqsl_decodeBase64 (const char *input, unsigned char *data, int *datalen)
 
DLLEXPORT int CALLCONVENTION tqsl_initDate (tQSL_Date *date, const char *str)
 
DLLEXPORT int CALLCONVENTION tqsl_initTime (tQSL_Time *time, const char *str)
 
DLLEXPORT int CALLCONVENTION tqsl_compareDates (const tQSL_Date *a, const tQSL_Date *b)
 
DLLEXPORT int CALLCONVENTION tqsl_subtractDates (const tQSL_Date *a, const tQSL_Date *b, int *diff)
 
DLLEXPORT char *CALLCONVENTION tqsl_convertDateToText (const tQSL_Date *date, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_isDateValid (const tQSL_Date *d)
 
DLLEXPORT int CALLCONVENTION tqsl_isDateNull (const tQSL_Date *d)
 
DLLEXPORT int CALLCONVENTION tqsl_isTimeValid (const tQSL_Time *t)
 
DLLEXPORT char *CALLCONVENTION tqsl_convertTimeToText (const tQSL_Time *time, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getVersion (int *major, int *minor)
 
DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion (int *major, int *minor)
 

Variables

DLLEXPORTDATA int tQSL_Error
 Error code from most recent tQSL library call. More...
 
DLLEXPORTDATA
TQSL_ADIF_GET_FIELD_ERROR 
tQSL_ADIF_Error
 The ADIF error code.
 
DLLEXPORTDATA
TQSL_CABRILLO_ERROR_TYPE 
tQSL_Cabrillo_Error
 The ADIF error code.
 
DLLEXPORTDATA char tQSL_ErrorFile [256]
 File name of file giving error. (May be empty.)
 
DLLEXPORTDATA char tQSL_CustomError [256]
 Custom error message string.
 
DLLEXPORTDATA int tQSL_Errno
 System errno - stored when tQSL_Error == TQSL_SYSTEM_ERROR.
 
DLLEXPORTDATA char tQSL_ImportCall [256]
 Callsign used in import - used for missing public key error.
 

Detailed Description

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_compareDates ( const tQSL_Date a,
const tQSL_Date b 
)

Compare two tQSL_Date objects.

Returns:

  • -1 if a < b
  • 0 if a == b
  • 1 if a > b
DLLEXPORT char* CALLCONVENTION tqsl_convertDateToText ( const tQSL_Date date,
char *  buf,
int  bufsiz 
)

Converts a tQSL_Date object to a YYYY-MM-DD string.

Returns a pointer to buf or NULL on error

DLLEXPORT char* CALLCONVENTION tqsl_convertTimeToText ( const tQSL_Time time,
char *  buf,
int  bufsiz 
)

Converts a tQSL_Time object to a HH:MM:SSZ string.

Returns a pointer to buf or NULL on error

DLLEXPORT int CALLCONVENTION tqsl_decodeBase64 ( const char *  input,
unsigned char *  data,
int *  datalen 
)

Decode Base64 text into binary data.

  • input = NUL-terminated text string of Base64-encoded data
  • data = pointer to output buffer
  • datalen = pointer to int containing the size of the output buffer in bytes

Places the number of resulting data bytes into *datalen.

DLLEXPORT int CALLCONVENTION tqsl_encodeBase64 ( const unsigned char *  data,
int  datalen,
char *  output,
int  outputlen 
)

Encode a block of data into Base64 text.

  • data = block of data to encode
  • datalen = length of data in bytes
  • output = pointer to output buffer
  • outputlen = size of output buffer in bytes
DLLEXPORT int CALLCONVENTION tqsl_getConfigVersion ( int *  major,
int *  minor 
)

Returns the configuration-file version. major and/or minor may be NULL.

DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString ( )

Gets the error string for the current tQSL library error and resets the error status. See tqsl_getErrorString_v().

DLLEXPORT const char* CALLCONVENTION tqsl_getErrorString_v ( int  err)

Gets the error string corresponding to the given error number. The error string is available only until the next call to tqsl_getErrorString_v or tqsl_getErrorString.

DLLEXPORT int CALLCONVENTION tqsl_getVersion ( int *  major,
int *  minor 
)

Returns the library version. major and/or minor may be NULL.

DLLEXPORT int CALLCONVENTION tqsl_init ( )

Initialize the tQSL library

This function should be called prior to calling any other library functions.

DLLEXPORT int CALLCONVENTION tqsl_initDate ( tQSL_Date date,
const char *  str 
)

Initialize a tQSL_Date object from a date string.

The date string must be YYYY-MM-DD or YYYYMMDD format.

Returns 0 on success, nonzero on failure

DLLEXPORT int CALLCONVENTION tqsl_initTime ( tQSL_Time time,
const char *  str 
)

Initialize a tQSL_Time object from a time string.

The time string must be HH[:]MM[[:]SS] format.

Returns 0 on success, nonzero on failure

DLLEXPORT int CALLCONVENTION tqsl_isDateNull ( const tQSL_Date d)

Test whether a tQSL_Date is empty (contains all zeroes)

Returns 1 if the date is null

DLLEXPORT int CALLCONVENTION tqsl_isDateValid ( const tQSL_Date d)

Test whether a tQSL_Date contains a valid date value

Returns 1 if the date is valid

DLLEXPORT int CALLCONVENTION tqsl_isTimeValid ( const tQSL_Time t)

Test whether a tQSL_Time contains a valid time value

Returns 1 if the time is valid

DLLEXPORT int CALLCONVENTION tqsl_setDirectory ( const char *  dir)

Set the directory where the TQSL files are kept. May be called either before of after tqsl_init(), but should be called before calling any other functions in the library.

Note that this is purely optional. The library will figure out an approriate directory if tqsl_setDirectory isn't called. Unless there is some particular need to set the directory explicitly, programs should refrain from doing so.

DLLEXPORT int CALLCONVENTION tqsl_subtractDates ( const tQSL_Date a,
const tQSL_Date b,
int *  diff 
)

Calculate the number of days between two tQSL_Date objects.

Returns a positive result if the first date is earlier, otherwise negative.

Variable Documentation

DLLEXPORTDATA int tQSL_Error

Error code from most recent tQSL library call.

The values for the error code are defined in tqslerrno.h

tqsl-2.0/src/doxygen/html/group__Sign.html0000664000076400007640000004224212231073120020712 0ustar rmurphyrmurphy TrustedQSL Library API: Signing API
TrustedQSL Library API
Signing API

Functions

DLLEXPORT int CALLCONVENTION tqsl_beginSigning (tQSL_Cert cert, char *password, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_checkSigningStatus (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_getMaxSignatureSize (tQSL_Cert cert, int *sigsize)
 
DLLEXPORT int CALLCONVENTION tqsl_signDataBlock (tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int *siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock (tQSL_Cert cert, const unsigned char *data, int datalen, unsigned char *sig, int siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_signQSORecord (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *rec, unsigned char *sig, int *siglen)
 
DLLEXPORT int CALLCONVENTION tqsl_endSigning (tQSL_Cert cert)
 

Detailed Description

The Signing API uses a tQSL_Cert (see Certificate Handling API) to digitally sign a block of data.

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_beginSigning ( tQSL_Cert  cert,
char *  password,
int(*)(char *pwbuf, int pwsize, void *userdata)  pwcb,
void *  user 
)

Initialize the tQSL_Cert object for use in signing.

This produces an unencrypted copy of the private key in memory.

if password is not NULL, it must point to the password to use to decrypt the private key. If password is NULL and pwcb is not NULL, pwcb is called to get the password. If the private key is encrypted and both password and pwcb are NULL, or if the supplied password fails to decrypt the key, a TQSL_PASSWORD_ERROR error is returned.

pwcb parameters: pwbuf is a pointer to a buffer of pwsize chars. The buffer should be NUL-terminated.

DLLEXPORT int CALLCONVENTION tqsl_checkSigningStatus ( tQSL_Cert  cert)

Test whether the tQSL_Cert object is initialized for signing.

Returns 0 if initialized. Sets tQSL_Error to TQSL_SIGNINIT_ERROR if not.

DLLEXPORT int CALLCONVENTION tqsl_endSigning ( tQSL_Cert  cert)

Terminate signing operations for this tQSL_Cert object.

This zero-fills the unencrypted private key in memory.

DLLEXPORT int CALLCONVENTION tqsl_getMaxSignatureSize ( tQSL_Cert  cert,
int *  sigsize 
)

Get the maximum size of a signature block that will be produced when the tQSL_Cert is used to sign data. (Note that the size of the signature block is unaffected by the size of the data block being signed.)

DLLEXPORT int CALLCONVENTION tqsl_signDataBlock ( tQSL_Cert  cert,
const unsigned char *  data,
int  datalen,
unsigned char *  sig,
int *  siglen 
)

Sign a data block.

tqsl_beginSigning() must have been called for the tQSL_Cert object before calling this function.

DLLEXPORT int CALLCONVENTION tqsl_signQSORecord ( tQSL_Cert  cert,
tQSL_Location  loc,
TQSL_QSO_RECORD rec,
unsigned char *  sig,
int *  siglen 
)

Sign a single QSO record

tqsl_beginSigning() must have been called for the tQSL_Cert object before calling this function.

loc must be a valid tQSL_Location object. See Data API.

DLLEXPORT int CALLCONVENTION tqsl_verifyDataBlock ( tQSL_Cert  cert,
const unsigned char *  data,
int  datalen,
unsigned char *  sig,
int  siglen 
)

Verify a signed data block.

tqsl_beginSigning() need not have been called.

tqsl-2.0/src/doxygen/html/group__Data.html0000664000076400007640000040550712231073120020672 0ustar rmurphyrmurphy TrustedQSL Library API: Data API
TrustedQSL Library API
Data API

Macros

#define TQSL_LOCATION_FIELD_TEXT   1
 Text type input field.
 
#define TQSL_LOCATION_FIELD_DDLIST   2
 Dropdown list input field.
 
#define TQSL_LOCATION_FIELD_LIST   3
 List type input field.
 
#define TQSL_LOCATION_FIELD_BADZONE   4
 Used to return zone selection errors.
 
#define TQSL_LOCATION_FIELD_CHAR   1
 Character field.
 
#define TQSL_LOCATION_FIELD_INT   2
 Integer field.
 

Functions

DLLEXPORT int CALLCONVENTION tqsl_initStationLocationCapture (tQSL_Location *locp)
 
DLLEXPORT int CALLCONVENTION tqsl_endStationLocationCapture (tQSL_Location *locp)
 
DLLEXPORT int CALLCONVENTION tqsl_updateStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocationCapturePages (tQSL_Location loc, int *npages)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCapturePage (tQSL_Location loc, int *page)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCapturePage (tQSL_Location loc, int page)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCertFlags (tQSL_Location loc, int flags)
 
DLLEXPORT int CALLCONVENTION tqsl_nextStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_prevStationLocationCapture (tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_hasNextStationLocationCapture (tQSL_Location loc, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_hasPrevStationLocationCapture (tQSL_Location loc, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_saveStationLocationCapture (tQSL_Location loc, int overwrite)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCaptureName (tQSL_Location loc, char *namebuf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCaptureName (tQSL_Location loc, const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocations (tQSL_Location loc, int *nloc)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName (tQSL_Location loc, int idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign (tQSL_Location loc, int idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField (tQSL_Location locp, const char *name, char *namebuf, int bufsize)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocation (tQSL_Location *loc, const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationLocationErrors (tQSL_Location loc, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getStationDataEnc (tQSL_StationDataEnc *sdata)
 
DLLEXPORT int CALLCONVENTION tqsl_freeStationDataEnc (tQSL_StationDataEnc sdata)
 
DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations (const char *locdata)
 
DLLEXPORT int CALLCONVENTION tqsl_deleteStationLocation (const char *name)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumLocationField (tQSL_Location loc, int *numf)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabelSize (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBISize (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType (tQSL_Location loc, int field_num, int *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType (tQSL_Location loc, int field_num, int *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags (tQSL_Location loc, int field_num, int *flags)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData (tQSL_Location loc, int field_num, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData (tQSL_Location loc, int field_num, int *dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex (tQSL_Location loc, int field_num, int *dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems (tQSL_Location loc, int field_num, int *rval)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem (tQSL_Location loc, int field_num, int item_idx, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData (tQSL_Location loc, int field_num, const char *buf)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData (tQSL_Location loc, int field_num, int dat)
 
DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex (tQSL_Location loc, int field_num, int dat)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged (tQSL_Location loc, int field_num, int *changed)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign (tQSL_Location loc, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getLocationDXCCEntity (tQSL_Location loc, int *dxcc)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumDXCCEntity (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity (int index, int *number, const char **name)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName (int number, const char **name)
 
DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap (int number, const char **zonemap)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumBand (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getBand (int index, const char **name, const char **spectrum, int *low, int *high)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumMode (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getMode (int index, const char **mode, const char **group)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumPropagationMode (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode (int index, const char **name, const char **descrip)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumSatellite (int *number)
 
DLLEXPORT int CALLCONVENTION tqsl_getSatellite (int index, const char **name, const char **descrip, tQSL_Date *start, tQSL_Date *end)
 
DLLEXPORT int CALLCONVENTION tqsl_clearCabrilloMap ()
 
DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry (const char *contest, int field, int contest_type)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry (const char *contest, int *fieldnum, int *contest_type)
 
DLLEXPORT int CALLCONVENTION tqsl_clearADIFModes ()
 
DLLEXPORT int CALLCONVENTION tqsl_setADIFMode (const char *adif_item, const char *mode)
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFMode (const char *adif_item, char *mode, int nmode)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCERT (tQSL_Cert cert, int uid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItSTATION (tQSL_Location loc, int uid, int certuid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCONTACT (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getGABBItCONTACTData (tQSL_Cert cert, tQSL_Location loc, TQSL_QSO_RECORD *qso, int stationuid, char *signdata, int sdlen)
 

Detailed Description

The Data API is used to form data into TrustedQSL records. A TrustedQSL record consists of a station record and a QSO record. Together, the two records fully describe one station's end of the QSO – just as a paper QSL card does.

The station record contains the callsign and geographic location of the station submitting the QSO record. The library manages the station records. The tqsl_xxxStationLocationCapture functions are used to generate and save a station record. The intent is to provide an interface that makes a step-by-step system (such as a GUI "wizard") easily implemented.

The tqsl_getStationLocation() function is used to retrieve station records.

With the necessary station location available, a signed GABBI output file can be generated using the tqsl_getGABBIxxxxx functions:

The GABBI format requires that the tCERT record contain an integer identifier that is unique within the GABBI file. Similarly, each tSTATION record must contain a unique identifier. Aditionally, the tSTATION record must reference the identifier of a preceding tCERT record. Finally, each tCONTACT record must reference a preceding tSTATION record. (A GABBI processor uses these identifiers and references to tie the station and contact records together and to verify their signature via the certificate.) It is the responsibility of the caller to supply these identifiers and to ensure that the supplied references match the tQSL_Cert and tQSL_Location used to create the referenced GABBI records.

Station Location Generation

The station-location generation process involves determining the values for a number of station-location parameters. Normally this will be done by prompting the user for the values. The responses given by the user may determine which later fields are required. For example, if the user indicates that the DXCC entity is UNITED STATES, a later field would ask for the US state. This field would not be required if the DXCC entity were not in the US.

To accommodate the dynamic nature of the field requirements, the fields are ordered such that dependent fields are queried after the field(s) on which they depend. To make this process acceptable in a GUI system, the fields are grouped into pages, where multiple fields may be displayed on the same page. The grouping is such that which fields are within the page is not dependent on any of the values of the fields within the page. That is, a page of fields contains the same fields no matter what value any of the fields contains. (However, the values of fields within the page can depend on the values of fields that precede them in the page.)

Here is a brief overview of the sequence of events involved in generating a station location interactively, one field at a time:

1) Call tqsl_initStationLocationCapture() (new location) or tqsl_getStationLocation() (existing location).

2) For field from 0 to tqsl_getNumLocationField():

3) If tqsl_hasNextStationLocationCapture() returns 1, call tqsl_nextStationLocationCapture() and go back to step 2.

In the case of a GUI system, you'll probably want to display the fields in pages. The sequence of events is a bit different:

1) Call tqsl_initStationLocationCapture() (new location) or tqsl_getStationLocation() (existing location).

2) For field from 0 to tqsl_getNumLocationField(),

3) Each time the user changes a field, call tqsl_updateStationLocationCapture(). This may change the allowable selection for fields that follow the field the user changed, so the control for each of those fields should be updated as in step 2.

4) Once the user has completed entries for the page, if tqsl_hasNextStationLocationCapture() returns 1, call tqsl_nextStationLocationCapture() and go back to step 2.

N.B. The first two fields in the station-location capture process are always call sign and DXCC entity, in that order. As a practical matter, these two fields must match the corresponding fields in the available certificates. The library will therefore constrain the values of these fields to match what's available in the certificate store. See Certificate Handling API.

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_clearADIFModes ( )

Clear the map of ADIF modes

DLLEXPORT int CALLCONVENTION tqsl_clearCabrilloMap ( )

Clear the map of Cabrillo contests.

DLLEXPORT int CALLCONVENTION tqsl_deleteStationLocation ( const char *  name)

Remove the stored station location by name.

DLLEXPORT int CALLCONVENTION tqsl_endStationLocationCapture ( tQSL_Location locp)

Release the station-location resources. This should be called for any tQSL_Location that was initialized via tqsl_initStationLocationCapture() or tqsl_getStationLocation()

DLLEXPORT int CALLCONVENTION tqsl_freeStationDataEnc ( tQSL_StationDataEnc  sdata)

Free the pointer returned by tqsl_getStationDataEnc(tQSL_StationDataEnc*)

DLLEXPORT int CALLCONVENTION tqsl_getADIFMode ( const char *  adif_item,
char *  mode,
int  nmode 
)

Map an ADIF mode to its TQSL equivalent.

DLLEXPORT int CALLCONVENTION tqsl_getBand ( int  index,
const char **  name,
const char **  spectrum,
int *  low,
int *  high 
)

Get a band by its index.

name - The GAABI name of the band. spectrum - HF | VHF | UHF low - The low end of the band in kHz (HF) or MHz (VHF/UHF) high - The low high of the band in kHz (HF) or MHz (VHF/UHF)

Note: spectrum, low and/or high may be NULL.

DLLEXPORT int CALLCONVENTION tqsl_getCabrilloMapEntry ( const char *  contest,
int *  fieldnum,
int *  contest_type 
)

Get the mapping of a Cabrillo contest name (as found in the CONTEST line of a Cabrillo file) to a call-worked field number and the contest type.

fieldnum will be set to 0 if the contest name isn't in the Cabrillo map. Otherwise it is set to the QSO line field number of the call-worked field, with field counting starting at 1.

contest_type may be NULL. If not, it is set to the Cabrillo contest type (TQSL_CABRILLO_HF or TQSL_CABRILLO_VHF), defined in cabrillo.h.

DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntity ( int  index,
int *  number,
const char **  name 
)

Get a DXCC entity from the list of DXCC entities by its index.

DLLEXPORT int CALLCONVENTION tqsl_getDXCCEntityName ( int  number,
const char **  name 
)

Get the name of a DXCC Entity by its DXCC number.

DLLEXPORT int CALLCONVENTION tqsl_getDXCCZoneMap ( int  number,
const char **  zonemap 
)

Get the zonemap of a DXCC Entity by its DXCC number.

DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCERT ( tQSL_Cert  cert,
int  uid 
)

Get a GABBI record that contains the certificate.

uid is the value for the CERT_UID field

Returns the NULL pointer on error.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the GABBI records should be written in binary mode.

DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACT ( tQSL_Cert  cert,
tQSL_Location  loc,
TQSL_QSO_RECORD qso,
int  stationuid 
)

Get a GABBI record that contains the QSO data.

  • stationuid is the value of the associated STATION_UID field.

N.B.: If cert is not initialized for signing (see tqsl_beginSigning()) the function will return with a TQSL_SIGNINIT_ERROR error.

Returns the NULL pointer on error.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the GABBI records should be written in binary mode.

DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItCONTACTData ( tQSL_Cert  cert,
tQSL_Location  loc,
TQSL_QSO_RECORD qso,
int  stationuid,
char *  signdata,
int  sdlen 
)

Get a GABBI record that contains the QSO data along with the associated signdata (QSO data signed to validate the QSO).

  • stationuid is the value of the associated STATION_UID field.

N.B.: If cert is not initialized for signing (see tqsl_beginSigning()) the function will return with a TQSL_SIGNINIT_ERROR error.

Returns the NULL pointer on error.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the GABBI records should be written in binary mode.

DLLEXPORT const char* CALLCONVENTION tqsl_getGABBItSTATION ( tQSL_Location  loc,
int  uid,
int  certuid 
)

Get a GABBI record that contains the Staion Location data.

  • uid is the value for the STATION_UID field.
  • certuid is the value of the asociated CERT_UID field.

Returns the NULL pointer on error.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the GABBI records should be written in binary mode.

DLLEXPORT int CALLCONVENTION tqsl_getLocationCallSign ( tQSL_Location  loc,
char *  buf,
int  bufsiz 
)

Get the call sign from the station location.

DLLEXPORT int CALLCONVENTION tqsl_getLocationDXCCEntity ( tQSL_Location  loc,
int *  dxcc 
)

Get the DXCC entity from the station location.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldChanged ( tQSL_Location  loc,
int  field_num,
int *  changed 
)

Get the changed status of a field. The changed flag is set to 1 if the field's pick list was changed during the last call to tqsl_updateStationLocationCapture or zero if the list was not changed.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldCharData ( tQSL_Location  loc,
int  field_num,
char *  buf,
int  bufsiz 
)

Get the character data from the specified field.

If the field input type (see tqsl_getLocationFieldInputType()) is TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, this will return the text of the selected item.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBI ( tQSL_Location  loc,
int  field_num,
char *  buf,
int  bufsiz 
)

Get the GABBI name of the specified field

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataGABBISize ( tQSL_Location  loc,
int  field_num,
int *  rval 
)

Get the size of the GABBI name of the specified field

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabel ( tQSL_Location  loc,
int  field_num,
char *  buf,
int  bufsiz 
)

Get the label for the specified field

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLabelSize ( tQSL_Location  loc,
int  field_num,
int *  rval 
)

Get the number of characters in the label for the specified field

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataLength ( tQSL_Location  loc,
int  field_num,
int *  rval 
)

Get the length of the input field data.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldDataType ( tQSL_Location  loc,
int  field_num,
int *  type 
)

Get the data type of the input field.

type will be either TQSL_LOCATION_FIELD_CHAR or TQSL_LOCATION_FIELD_INT

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldFlags ( tQSL_Location  loc,
int  field_num,
int *  flags 
)

Get the flags for the input field.

flags will be either TQSL_LOCATION_FIELD_UPPER Field is to be uppercased on input TQSL_LOCATION_FIELD_MUSTSEL Value must be selected TQSL_LOCATION_FIELD_SELNXT Value must be selected to allow Next/Finish

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIndex ( tQSL_Location  loc,
int  field_num,
int *  dat 
)

If the field input type (see tqsl_getLocationFieldInputType()) is TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, gets the index of the selected list item.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldInputType ( tQSL_Location  loc,
int  field_num,
int *  type 
)

Get the input type of the input field.

type will be one of TQSL_LOCATION_FIELD_TEXT, TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldIntData ( tQSL_Location  loc,
int  field_num,
int *  dat 
)

Get the integer data from the specified field.

This is only meaningful if the field data type (see tqsl_getLocationFieldDataType()) is TQSL_LOCATION_FIELD_INT.

DLLEXPORT int CALLCONVENTION tqsl_getLocationFieldListItem ( tQSL_Location  loc,
int  field_num,
int  item_idx,
char *  buf,
int  bufsiz 
)

Get the text of a specified item of a specified field

DLLEXPORT int CALLCONVENTION tqsl_getMode ( int  index,
const char **  mode,
const char **  group 
)

Get a mode by its index.

mode - The GAABI mode name group - CW | PHONE | IMAGE | DATA

Note: group may be NULL.

DLLEXPORT int CALLCONVENTION tqsl_getNumBand ( int *  number)

Get the number of Band entries in the Band list

DLLEXPORT int CALLCONVENTION tqsl_getNumDXCCEntity ( int *  number)

Get the number of DXCC entities in the master DXCC list.

DLLEXPORT int CALLCONVENTION tqsl_getNumLocationField ( tQSL_Location  loc,
int *  numf 
)

Get the number of fields on the current station location page

DLLEXPORT int CALLCONVENTION tqsl_getNumLocationFieldListItems ( tQSL_Location  loc,
int  field_num,
int *  rval 
)

Get the number of items in the specified field's pick list.

DLLEXPORT int CALLCONVENTION tqsl_getNumMode ( int *  number)

Get the number of Mode entries in the Mode list

DLLEXPORT int CALLCONVENTION tqsl_getNumPropagationMode ( int *  number)

Get the number of Propagation Mode entries in the Propagation Mode list

DLLEXPORT int CALLCONVENTION tqsl_getNumSatellite ( int *  number)

Get the number of Satellite entries in the Satellite list

DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocationCapturePages ( tQSL_Location  loc,
int *  npages 
)

Return the number of station location capture pages.

DLLEXPORT int CALLCONVENTION tqsl_getNumStationLocations ( tQSL_Location  loc,
int *  nloc 
)

Get the number of saved station locations

DLLEXPORT int CALLCONVENTION tqsl_getPropagationMode ( int  index,
const char **  name,
const char **  descrip 
)

Get a propagation mode by its index.

name - The GAABI propagation mode name descrip - Text description of the propagation mode

Note: descrip may be NULL.

DLLEXPORT int CALLCONVENTION tqsl_getSatellite ( int  index,
const char **  name,
const char **  descrip,
tQSL_Date start,
tQSL_Date end 
)

Get a satellite by its index.

name - The GAABI satellite name descrip - Text description of the satellite start - The date the satellite entered service end - The last date the satellite was in service

Note: descrip, start and/or end may be NULL.

DLLEXPORT int CALLCONVENTION tqsl_getStationDataEnc ( tQSL_StationDataEnc sdata)

Return the contents of the station data file as a byte stream. The caller is required to tqsl_freeStationDataEnc() this pointer when done with it.

DLLEXPORT int CALLCONVENTION tqsl_getStationLocation ( tQSL_Location loc,
const char *  name 
)

Retrieve a saved station location. Once finished wih the station location, tqsl_endStationLocationCapture() should be called to release resources.

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCallSign ( tQSL_Location  loc,
int  idx,
char *  buf,
int  bufsiz 
)

Get the call sign from the station location

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCaptureName ( tQSL_Location  loc,
char *  namebuf,
int  bufsiz 
)

Get the name of the station location

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationCapturePage ( tQSL_Location  loc,
int *  page 
)

Get the current page number

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationErrors ( tQSL_Location  loc,
char *  buf,
int  bufsiz 
)

Get any errors returned from parsing the selected station location. This should be called after tqsl_getStationLocation to determine if any of the existing fields failed validation. Currently only zone data is validated here, but future validations for things like properly formatted grid squares is likely.

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationField ( tQSL_Location  locp,
const char *  name,
char *  namebuf,
int  bufsize 
)

Get a named field from the station location

DLLEXPORT int CALLCONVENTION tqsl_getStationLocationName ( tQSL_Location  loc,
int  idx,
char *  buf,
int  bufsiz 
)

Get the name of the specified (by idx) saved station location

DLLEXPORT int CALLCONVENTION tqsl_hasNextStationLocationCapture ( tQSL_Location  loc,
int *  rval 
)

Returns 1 (in rval) if there is a next page

DLLEXPORT int CALLCONVENTION tqsl_hasPrevStationLocationCapture ( tQSL_Location  loc,
int *  rval 
)

Returns 1 (in rval) if there is a previous page

DLLEXPORT int CALLCONVENTION tqsl_initStationLocationCapture ( tQSL_Location locp)

Begin the process of generating a station record

DLLEXPORT int CALLCONVENTION tqsl_mergeStationLocations ( const char *  locdata)

Merge saved location data with existing

DLLEXPORT int CALLCONVENTION tqsl_nextStationLocationCapture ( tQSL_Location  loc)

Advance the page to the next one in the page sequence

DLLEXPORT int CALLCONVENTION tqsl_prevStationLocationCapture ( tQSL_Location  loc)

Return the page to the previous one in the page sequence.

DLLEXPORT int CALLCONVENTION tqsl_saveStationLocationCapture ( tQSL_Location  loc,
int  overwrite 
)

Save the station location data. Note that the name must have been set via tqsl_setStationLocationCaptureName if this is a new station location. If the overwrite parameter is zero and a station location of that name is already in existance, an error occurs with tQSL_Error set to TQSL_NAME_EXISTS.

DLLEXPORT int CALLCONVENTION tqsl_setADIFMode ( const char *  adif_item,
const char *  mode 
)

Set the mapping of an ADIF mode to a TQSL mode.

DLLEXPORT int CALLCONVENTION tqsl_setCabrilloMapEntry ( const char *  contest,
int  field,
int  contest_type 
)

Set the mapping of a Cabrillo contest name (as found in the CONTEST line of a Cabrillo file) to the QSO line call-worked field number and the contest type.

field can have a value of TQSL_MIN_CABRILLO_MAP_FIELD (cabrillo.h) or greater. Field number starts at 1.

contest_type must be TQSL_CABRILLO_HF or TQSL_CABRILLO_VHF, defined in cabrillo.h

DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldCharData ( tQSL_Location  loc,
int  field_num,
const char *  buf 
)

Set the text data of a specified field.

DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIndex ( tQSL_Location  loc,
int  field_num,
int  dat 
)

If the field input type (see tqsl_getLocationFieldInputType()) is TQSL_LOCATION_FIELD_DDLIST or TQSL_LOCATION_FIELD_LIST, sets the index of the selected list item.

DLLEXPORT int CALLCONVENTION tqsl_setLocationFieldIntData ( tQSL_Location  loc,
int  field_num,
int  dat 
)

Set the integer data of a specified field.

DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCaptureName ( tQSL_Location  loc,
const char *  name 
)

Set the name of the station location

DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCapturePage ( tQSL_Location  loc,
int  page 
)

Set the current page number. Typically, the page number will be 1 (the starting page) or a value obtained from tqsl_getStationLocationCapturePage().

DLLEXPORT int CALLCONVENTION tqsl_setStationLocationCertFlags ( tQSL_Location  loc,
int  flags 
)

Set the certificate flags used in a location page. This is used to enable expired certs (or disable).

DLLEXPORT int CALLCONVENTION tqsl_updateStationLocationCapture ( tQSL_Location  loc)

Update the pages based on the currently selected settings.

tqsl-2.0/src/doxygen/html/group__Convert.html0000664000076400007640000010636612231073120021442 0ustar rmurphyrmurphy TrustedQSL Library API: Converter API
TrustedQSL Library API
Converter API

Typedefs

typedef void * tQSL_Converter
 

Functions

DLLEXPORT int CALLCONVENTION tqsl_beginConverter (tQSL_Converter *convp)
 
DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter (tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_beginCabrilloConverter (tQSL_Converter *conv, const char *filename, tQSL_Cert *certs, int ncerts, tQSL_Location loc)
 
DLLEXPORT int CALLCONVENTION tqsl_endConverter (tQSL_Converter *conv)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowBadCall (tQSL_Converter conv, int allow)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowDuplicates (tQSL_Converter convp, int allow)
 
DLLEXPORT int CALLCONVENTION tqsl_setConverterAppName (tQSL_Converter convp, const char *app)
 
DLLEXPORT int CALLCONVENTION tqsl_converterRollBack (tQSL_Converter convp)
 
DLLEXPORT int CALLCONVENTION tqsl_converterCommit (tQSL_Converter convp)
 
DLLEXPORT int CALLCONVENTION tqsl_getDuplicateRecords (tQSL_Converter convp, char *key, char *data, int keylen)
 
DLLEXPORT int CALLCONVENTION tqsl_putDuplicateRecord (tQSL_Converter convp, const char *key, const char *data, int keylen)
 
DLLEXPORT int CALLCONVENTION tqsl_setADIFConverterDateFilter (tQSL_Converter conv, tQSL_Date *start, tQSL_Date *end)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getConverterGABBI (tQSL_Converter conv)
 
DLLEXPORT int CALLCONVENTION tqsl_getConverterCert (tQSL_Converter conv, tQSL_Cert *certp)
 
DLLEXPORT int CALLCONVENTION tqsl_getConverterLine (tQSL_Converter conv, int *lineno)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getConverterRecordText (tQSL_Converter conv)
 

Detailed Description

The Converter API provides the capability of converting Cabrillo and ADIF files to GABBI output.

Typedef Documentation

typedef void* tQSL_Converter
 Opaque converter type used by applications 

to access conversion functions

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_beginADIFConverter ( tQSL_Converter conv,
const char *  filename,
tQSL_Cert certs,
int  ncerts,
tQSL_Location  loc 
)

Initiates the conversion process for an ADIF file.

certs and ncerts define a set of certificates that are available to the converter for signing records. Typically, this list will be obtained by calling tqsl_selectCertificates().

tqsl_endConverter() should be called to free the resources when the conversion is finished.

DLLEXPORT int CALLCONVENTION tqsl_beginCabrilloConverter ( tQSL_Converter conv,
const char *  filename,
tQSL_Cert certs,
int  ncerts,
tQSL_Location  loc 
)

Initiates the conversion process for a Cabrillo file.

certs and ncerts define a set of certificates that are available to the converter for signing records. Typically, this list will be obtained by calling tqsl_selectCertificates().

tqsl_endConverter() should be called to free the resources when the conversion is finished.

DLLEXPORT int CALLCONVENTION tqsl_beginConverter ( tQSL_Converter convp)

Create a simple converter object

Allocates resources for converting logs and processing duplicate records.

DLLEXPORT int CALLCONVENTION tqsl_converterCommit ( tQSL_Converter  convp)

Commits insertions into the duplicates database.

This is called when a log is created normally and without issue, and so the presumption is that we are "done" with these QSOs.

DLLEXPORT int CALLCONVENTION tqsl_converterRollBack ( tQSL_Converter  convp)

Roll back insertions into the duplicates database.

This is called when cancelling creating a log, and causes any records added to the duplicates database to be removed so re-processing that log does not cause the records to be mis-marked as duplicates.

DLLEXPORT int CALLCONVENTION tqsl_endConverter ( tQSL_Converter conv)

End the conversion process by freeing the used resources.

DLLEXPORT int CALLCONVENTION tqsl_getConverterCert ( tQSL_Converter  conv,
tQSL_Cert certp 
)

Get the certificate used to sign the most recent QSO record.

DLLEXPORT const char* CALLCONVENTION tqsl_getConverterGABBI ( tQSL_Converter  conv)

This is the main converter function. It returns a single GABBI record.

Returns the NULL pointer on error or EOF. (Test tQSL_Error to determine which.)

tQSL_Error is set to TQSL_DATE_OUT_OF_RANGE if QSO date range checking is active and the QSO date is outside the specified range. This is a non-fatal error.

tQSL_Error is set to TQSL_DUPLICATE_QSO if the QSO has already been processed on the current computer.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the GABBI records should be written in binary mode.

N.B. If the selected certificate has not been initialized for signing via tqsl_beginSigning(), this function will return a TQSL_SIGNINIT_ERROR. The cert that caused the error can be obtained via tqsl_getConverterCert(), initialized for signing, and then this function can be called again. No data records will be lost in this process.

DLLEXPORT int CALLCONVENTION tqsl_getConverterLine ( tQSL_Converter  conv,
int *  lineno 
)

Get the input-file line number last read by the converter, starting at line 1.

DLLEXPORT const char* CALLCONVENTION tqsl_getConverterRecordText ( tQSL_Converter  conv)

Get the text of the last record read by the converter.

Returns NULL on error.

DLLEXPORT int CALLCONVENTION tqsl_getDuplicateRecords ( tQSL_Converter  convp,
char *  key,
char *  data,
int  keylen 
)

Bulk read the duplicate DB records

This is called to retrieve the QSO records from the dupe database. It returns the key/value pair upon each call. Return -1 for end of file, 0 for success, 1 for errors.

DLLEXPORT int CALLCONVENTION tqsl_putDuplicateRecord ( tQSL_Converter  convp,
const char *  key,
const char *  data,
int  keylen 
)

Bulk write duplicate DB records

This is called to store a QSO record into the dupe database.

Return -1 for duplicate insertion, 0 for success, 1 for errors.

DLLEXPORT int CALLCONVENTION tqsl_setADIFConverterDateFilter ( tQSL_Converter  conv,
tQSL_Date start,
tQSL_Date end 
)

Set QSO date filtering in the converter.

If start points to a valid date, QSOs prior to that date will be ignored by the converter. Similarly, if end points to a valid date, QSOs after that date will be ignored. Either or both may be NULL (or point to an invalid date) to disable date filtering for the respective range.

DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowBadCall ( tQSL_Converter  conv,
int  allow 
)

Configure the converter to allow (allow != 0) or disallow (allow == 0) nonamateur call signs in the CALL field. (Note: the test for validity is fairly trivial and will allow some nonamateur calls to get through, but it does catch most common errors.)

allow defaults to 0 when tqsl_beginADIFConverter or tqsl_beginCabrilloConverter is called.

DLLEXPORT int CALLCONVENTION tqsl_setConverterAllowDuplicates ( tQSL_Converter  convp,
int  allow 
)

Configure the converter to allow (allow != 0) or disallow (allow == 0) duplicate QSOs in a signed log. Duplicate detection is done using QSO details, location details, and certificate serial number.

allow defaults to 1 for backwards compatibility when tqsl_beginADIFConverter or tqsl_beginCabrilloConverter is called.

DLLEXPORT int CALLCONVENTION tqsl_setConverterAppName ( tQSL_Converter  convp,
const char *  app 
)

Specify the name of the application using the conversion library. This is output in a header record in the exported log file. Call this before calling tqsl_getConverterGABBI.

app is a c string containing the application name.

tqsl-2.0/src/doxygen/html/group__CertStuff.html0000664000076400007640000027363212231073120021730 0ustar rmurphyrmurphy TrustedQSL Library API: Certificate Handling API
TrustedQSL Library API
Certificate Handling API

Macros

#define TQSL_SELECT_CERT_WITHKEYS   1
 Private keys only (no cert)
 
#define TQSL_SELECT_CERT_EXPIRED   2
 Include expired certs.
 
#define TQSL_SELECT_CERT_SUPERCEDED   4
 Include superseded certs.
 
#define TQSL_PK_TYPE_ERR   0
 Error retrieving private key.
 
#define TQSL_PK_TYPE_NONE   1
 No private key.
 
#define TQSL_PK_TYPE_UNENC   2
 Private key is not encrypted.
 
#define TQSL_PK_TYPE_ENC   3
 Private key is encrypted.
 

Functions

DLLEXPORT int CALLCONVENTION tqsl_selectCertificates (tQSL_Cert **certlist, int *ncerts, const char *callsign, int dxcc, const tQSL_Date *date, const TQSL_PROVIDER *issuer, int flag)
 
DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates (tQSL_Cert **certlist, int *ncerts, const char *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getSelectedCertificate (tQSL_Cert *cert, const tQSL_Cert **certlist, int idx)
 
DLLEXPORT int CALLCONVENTION tqsl_isCertificateExpired (tQSL_Cert cert, int *status)
 
DLLEXPORT int CALLCONVENTION tqsl_isCertificateSuperceded (tQSL_Cert cert, int *status)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateKeyOnly (tQSL_Cert cert, int *keyonly)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded (const char *callsign, const char *type, const char *keybuf, const char *certbuf)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerial (tQSL_Cert cert, long *serial)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt (tQSL_Cert cert, char *serial, int serialsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialLength (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganization (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganizationalUnit (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress (tQSL_Cert cert, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotBeforeDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotAfterDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotBeforeDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotAfterDate (tQSL_Cert cert, tQSL_Date *date)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateDXCCEntity (tQSL_Cert cert, int *dxcc)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress1 (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress2 (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestPostalCode (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCountry (tQSL_Cert cert, char *str, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCertificatePrivateKeyType (tQSL_Cert cert)
 
DLLEXPORT void CALLCONVENTION tqsl_freeCertificate (tQSL_Cert cert)
 
DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile (const char *file, int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile (const char *file, long *serial)
 
DLLEXPORT int CALLCONVENTION tqsl_getNumProviders (int *n)
 
DLLEXPORT int CALLCONVENTION tqsl_getProvider (int idx, TQSL_PROVIDER *provider)
 
DLLEXPORT int CALLCONVENTION tqsl_createCertRequest (const char *filename, TQSL_CERT_REQ *req, int(*pwcb)(char *pwbuf, int pwsize, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File (tQSL_Cert cert, const char *filename, const char *p12password)
 
DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64 (tQSL_Cert cert, char *base64, int b64len, const char *p12password)
 
DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File (const char *filename, const char *p12password, const char *password, int(*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64 (const char *base64, const char *p12password, const char *password, int(*pwcb)(char *buf, int bufsiz, void *userdata), int(*cb)(int type, const char *message, void *userdata), void *user)
 
DLLEXPORT int CALLCONVENTION tqsl_deleteCertificate (tQSL_Cert cert)
 

Detailed Description

Certificates are managed by manipulating tQSL_Cert objects. A tQSL_Cert contains:

  • The identity of the organization that issued the certificate (the "issuer").
  • The name and call sign of the amateur radio operator (ARO).
  • The DXCC entity number for which this certificate is valid.
  • The range of QSO dates for which this certificate can be used.
  • The resources needed to digitally sign and verify QSO records.

The certificate management process consists of:

  • Applying for a certificate. Certificate requests are produced via the tqsl_createCertRequest() function, which produces a certificate-request file to send to the issuer.
  • Importing the certificate file received from the issuer into the local "certificate store," a directory managed by the tQSL library, via tqsl_importTQSLFile().
  • Selecting an appropriate certificate to use to sign a QSO record via tqsl_selectCertificates().

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_createCertRequest ( const char *  filename,
TQSL_CERT_REQ req,
int(*)(char *pwbuf, int pwsize, void *userdata)  pwcb,
void *  user 
)

Create a certificate-request Gabbi file.

The req parameter must be properly populated with the required fields.

If req->password is NULL and cb is not NULL, the callback will be called to acquire the password. Otherwise req->password will be used as the password. If the password is NULL or an empty string the generated private key will be stored unencrypted.

If req->signer is not zero and the signing certificate requires a password, the password may be in req->signer_password, else signer_pwcb is called.

DLLEXPORT int CALLCONVENTION tqsl_deleteCertificate ( tQSL_Cert  cert)

Delete a certificate and private key

DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12Base64 ( tQSL_Cert  cert,
char *  base64,
int  b64len,
const char *  p12password 
)

Save a key pair and certificates to a Base64 string in PKCS12 format.

The tQSL_Cert must be initialized for signing (see tqsl_beginSigning()) if the user certificate is being exported.

The supplied p12password is used to encrypt the PKCS12 data.

DLLEXPORT int CALLCONVENTION tqsl_exportPKCS12File ( tQSL_Cert  cert,
const char *  filename,
const char *  p12password 
)

Save a key pair and certificates to a file in PKCS12 format.

The tQSL_Cert must be initialized for signing (see tqsl_beginSigning()) if the user certificate is being exported.

The supplied p12password is used to encrypt the PKCS12 data.

DLLEXPORT void CALLCONVENTION tqsl_freeCertificate ( tQSL_Cert  cert)

Free the memory used by the tQSL_Cert. Once this function is called, cert should not be used again in any way.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateAROName ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the ARO name string from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateCallSign ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the ARO call sign string from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateDXCCEntity ( tQSL_Cert  cert,
int *  dxcc 
)

Get the DXCC entity number from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • dxcc - Pointer to an int to hold the returned date.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateEmailAddress ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the email address from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateEncoded ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the encoded certificate for inclusion in a GABBI file.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuer ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the issuer (DN) string from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganization ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the issuer's organization name from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateIssuerOrganizationalUnit ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the issuer's organizational unit name from a tQSL_Cert.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateKeyOnly ( tQSL_Cert  cert,
int *  keyonly 
)

Find out if the "certificate" is just a key pair.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotAfterDate ( tQSL_Cert  cert,
tQSL_Date date 
)

Get the certificate's not-after date from a tQSL_Cert.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateNotBeforeDate ( tQSL_Cert  cert,
tQSL_Date date 
)

Get the certificate's not-before date from a tQSL_Cert.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificatePrivateKeyType ( tQSL_Cert  cert)

Determine the nature of the private key associated with a certificate.

Returns one of the following values:

  • TQSL_PK_TYPE_ERR - An error occurred. Use tqsl_getErrorString() to examine.
  • TQSL_PK_TYPE_NONE - No matching private key was found.
  • TQSL_PK_TYPE_UNENC - The matching private key is unencrypted.
  • TQSL_PK_TYPE_ENC - The matching private key is encrypted (password protected).
DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotAfterDate ( tQSL_Cert  cert,
tQSL_Date date 
)

Get the QSO not-after date from a tQSL_Cert.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateQSONotBeforeDate ( tQSL_Cert  cert,
tQSL_Date date 
)

Get the QSO not-before date from a tQSL_Cert.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress1 ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the first address line from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestAddress2 ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the second address line from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCity ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the city from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestCountry ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the country from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestPostalCode ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the postal (ZIP) code from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateRequestState ( tQSL_Cert  cert,
char *  str,
int  bufsiz 
)

Get the state from the certificate request used in applying for a tQSL_Cert certificate.

  • cert - a tQSL_Cert object, normally one returned from tqsl_selectCertificates()
  • buf - Buffer to hold the returned string.
  • bufsiz - Size of buf.

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerial ( tQSL_Cert  cert,
long *  serial 
)

Get the issuer's serial number of the certificate.

DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialExt ( tQSL_Cert  cert,
char *  serial,
int  serialsiz 
)

Get the issuer's serial number of the certificate as a hexadecimal string. Needed for certs with long serial numbers (typically root certs).

DLLEXPORT int CALLCONVENTION tqsl_getCertificateSerialLength ( tQSL_Cert  cert)

Get the length of the issuer's serial number of the certificate as it will be returned by tqsl_getCertificateSerialExt.

DLLEXPORT int CALLCONVENTION tqsl_getKeyEncoded ( tQSL_Cert  cert,
char *  buf,
int  bufsiz 
)

Get the encoded private key for inclusion in a backup file.

DLLEXPORT int CALLCONVENTION tqsl_getNumProviders ( int *  n)

Get the number of certificate providers known to tqsllib.

DLLEXPORT int CALLCONVENTION tqsl_getProvider ( int  idx,
TQSL_PROVIDER provider 
)

Get the information for a certificate provider.

DLLEXPORT int CALLCONVENTION tqsl_getSelectedCertificate ( tQSL_Cert cert,
const tQSL_Cert **  certlist,
int  idx 
)

Get a particulat certificate from the list returnded by tqsl_selectCertificates. This function exists principally to make it easier for VB programs to access the list of certificates.

It is the caller's responsibility to ensure that 0 <= idx < ncerts (where ncerts is the value returned by tqsl_selectCertificates)

DLLEXPORT int CALLCONVENTION tqsl_getSerialFromTQSLFile ( const char *  file,
long *  serial 
)

Get the serial for the first user cert from a .tq6 file used to support asking the user to save their cert after import

  • file is the path to the file
  • serial is where the serial number is returned

Returns 0 on success, nonzero on failure.

DLLEXPORT int CALLCONVENTION tqsl_importKeyPairEncoded ( const char *  callsign,
const char *  type,
const char *  keybuf,
const char *  certbuf 
)

Import a base64 encoded certificate and private key from a backup file.

DLLEXPORT int CALLCONVENTION tqsl_importPKCS12Base64 ( const char *  base64,
const char *  p12password,
const char *  password,
int(*)(char *buf, int bufsiz, void *userdata)  pwcb,
int(*)(int type, const char *message, void *userdata)  cb,
void *  user 
)

Load certificates and a private key from a Base64 encoded PKCS12 string.

DLLEXPORT int CALLCONVENTION tqsl_importPKCS12File ( const char *  filename,
const char *  p12password,
const char *  password,
int(*)(char *buf, int bufsiz, void *userdata)  pwcb,
int(*)(int type, const char *message, void *userdata)  cb,
void *  user 
)

Load certificates and a private key from a PKCS12 file.

DLLEXPORT int CALLCONVENTION tqsl_importTQSLFile ( const char *  file,
int(*)(int type, const char *message, void *userdata)  cb,
void *  user 
)

Import a Gabbi cert file received from a CA

The callback, cb, will be called whenever a certificate is ready to be imported:

cb(type, message);

type has several fields that can be accessed via macros:

TQSL_CERT_CB_CALL_TYPE(type) := TQSL_CERT_CB_MILESTONE | TQSL_CERT_CB_RESULT

TQSL_CERT_CB_CERT_TYPE(type) := TQSL_CERT_CB_ROOT | TQSL_CERT_CB_CA | TQSL_CERT_CB_USER

TQSL_CERT_CB_RESULT_TYPE(type) := TQSL_CERT_CB_PROMPT | TQSL_CERT_CB_WARNING | TQSL_CERT_CB_ERROR

TQSL_CERT_CB_RESULT_TYPE() is meaningful only if TQSL_CERT_CB_CALL_TYPE() == TQSL_CERT_CB_RESULT

DLLEXPORT int CALLCONVENTION tqsl_isCertificateExpired ( tQSL_Cert  cert,
int *  status 
)

Find out if the "certificate" is expired

DLLEXPORT int CALLCONVENTION tqsl_isCertificateSuperceded ( tQSL_Cert  cert,
int *  status 
)

Find out if the "certificate" is superceded

DLLEXPORT int CALLCONVENTION tqsl_selectCACertificates ( tQSL_Cert **  certlist,
int *  ncerts,
const char *  type 
)

Get a list of authority certificates

Selects a set of certificates from the root or authorities certificate stores The function produces a list of tQSL_Cert objects.

Each of the tQSL_Cert objects in the list should be freed by calling tqsl_freeCertificate().

DLLEXPORT int CALLCONVENTION tqsl_selectCertificates ( tQSL_Cert **  certlist,
int *  ncerts,
const char *  callsign,
int  dxcc,
const tQSL_Date date,
const TQSL_PROVIDER issuer,
int  flag 
)

Get a list of certificates

Selects a set of certificates from the user's certificate store based on optional selection criteria. The function produces a list of tQSL_Cert objects.

  • certlist - Pointer to a variable that is set by the function to point to the list of tQSL_Cert objects.
  • ncerts - Pointer to an int that is set to the number of objects in the certlist list.
  • callsign - Optional call sign to match.
  • date - Optional QSO date string in ISO format. Only certs that have a QSO date range that encompasses this date will be returned.
  • issuer - Optional issuer (DN) string to match.
  • flag - OR of TQSL_SELECT_CERT_EXPIRED (include expired certs), TQSL_SELECT_CERT_SUPERCEDED and TQSL_SELECT_CERT_WITHKEYS (keys that don't have associated certs will be returned).

Returns 0 on success, nonzero on failure.

Each of the tQSL_Cert objects in the list should be freed by calling tqsl_freeCertificate().

tqsl-2.0/src/doxygen/html/group__Cabrillo.html0000664000076400007640000005522512231073120021546 0ustar rmurphyrmurphy TrustedQSL Library API: Cabrillo API
TrustedQSL Library API

Classes

struct  tqsl_cabrilloField
 

Macros

#define TQSL_CABRILLO_MAX_FIELDS   12
 Max field count.
 
#define TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX   64
 Max field name length.
 
#define TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX   40
 Max field value length.
 
#define TQSL_MIN_CABRILLO_MAP_FIELD   5
 First possible call-worked field.
 
#define TQSL_DEF_CABRILLO_MAP_FIELD   8
 Default call-worked field.
 

Typedefs

typedef void * tQSL_Cabrillo
 Opaque cabrillo log type.
 

Enumerations

enum  TQSL_CABRILLO_ERROR_TYPE {
  TQSL_CABRILLO_NO_ERROR, TQSL_CABRILLO_EOF, TQSL_CABRILLO_NO_START_RECORD, TQSL_CABRILLO_NO_CONTEST_RECORD,
  TQSL_CABRILLO_UNKNOWN_CONTEST, TQSL_CABRILLO_BAD_FIELD_DATA, TQSL_CABRILLO_EOR
}
 Cabrillo status values.
 
enum  TQSL_CABRILLO_FREQ_TYPE { TQSL_CABRILLO_HF, TQSL_CABRILLO_VHF, TQSL_CABRILLO_UNKNOWN }
 

Functions

DLLEXPORT const char
*CALLCONVENTION 
tqsl_cabrilloGetError (TQSL_CABRILLO_ERROR_TYPE err)
 
DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo (tQSL_Cabrillo *cabp, const char *filename)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest (tQSL_Cabrillo cab, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloFreqType (tQSL_Cabrillo cab, TQSL_CABRILLO_FREQ_TYPE *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloLine (tQSL_Cabrillo cab, int *lineno)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getCabrilloRecordText (tQSL_Cabrillo cab)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloField (tQSL_Cabrillo cab, tqsl_cabrilloField *field, TQSL_CABRILLO_ERROR_TYPE *err)
 
DLLEXPORT int CALLCONVENTION tqsl_endCabrillo (tQSL_Cabrillo *cabp)
 

Detailed Description

These functions and data structures provide a means of parsing a Cabrillo file into its component fields.

For convenience, the returned fields are identified using field names from the ADIF specification.

Enumeration Type Documentation

Frequency type: HF, VHF, or UNKNOWN

Function Documentation

DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo ( tQSL_Cabrillo cabp,
const char *  filename 
)

Initialize a Cabrillo file for reading

DLLEXPORT const char* CALLCONVENTION tqsl_cabrilloGetError ( TQSL_CABRILLO_ERROR_TYPE  err)

Get the Cabrillo error message that corresponds to a particular error value

DLLEXPORT int CALLCONVENTION tqsl_endCabrillo ( tQSL_Cabrillo cabp)

Finish reading a Cabrillo file and release its resources

DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest ( tQSL_Cabrillo  cab,
char *  buf,
int  bufsiz 
)

Get the Contest name as specified in the Cabrillo CONTEST line

DLLEXPORT int CALLCONVENTION tqsl_getCabrilloField ( tQSL_Cabrillo  cab,
tqsl_cabrilloField field,
TQSL_CABRILLO_ERROR_TYPE err 
)

Get the next field of the Cabrillo record

err is set to TQSL_CABRILLO_NO_ERROR or TQSL_CABRILLO_EOR (end-of-record) if field was populated with data. If err == TQSL_CABRILLO_EOR, this is the last field of the record.

err == TQSL_CABRILLO_EOF when there is no more data available.

DLLEXPORT int CALLCONVENTION tqsl_getCabrilloFreqType ( tQSL_Cabrillo  cab,
TQSL_CABRILLO_FREQ_TYPE type 
)

Get the Frequency type (HF or VHF) as determined by the contest

DLLEXPORT int CALLCONVENTION tqsl_getCabrilloLine ( tQSL_Cabrillo  cab,
int *  lineno 
)

Get the current line number (starting from 1) of the input file

DLLEXPORT const char* CALLCONVENTION tqsl_getCabrilloRecordText ( tQSL_Cabrillo  cab)

Get the text of the current Cabrillo record

tqsl-2.0/src/doxygen/html/group__ADIF.html0000664000076400007640000005236112231073120020520 0ustar rmurphyrmurphy TrustedQSL Library API: ADIF API
TrustedQSL Library API

Classes

struct  tqsl_adifFieldDefinitions
 
struct  tqsl_adifFieldResults
 

Macros

#define TQSL_ADIF_FIELD_NAME_LENGTH_MAX   64
 Max length of ADIF field.
 
#define TQSL_ADIF_FIELD_SIZE_LENGTH_MAX   10
 Max length of field name.
 
#define TQSL_ADIF_FIELD_TYPE_LENGTH_MAX   1
 Max length of field type.
 

Typedefs

typedef void * tQSL_ADIF
 Opaque ADIF type.
 

Enumerations

enum  TQSL_ADIF_BOOLEAN { TQSL_FALSE, TQSL_TRUE }
 
enum  TQSL_ADIF_RANGE_TYPE { TQSL_ADIF_RANGE_TYPE_NONE, TQSL_ADIF_RANGE_TYPE_MINMAX, TQSL_ADIF_RANGE_TYPE_ENUMERATION }
 Specifies the type of range limits to apply to a field.
 
enum  TQSL_ADIF_GET_FIELD_ERROR {
  TQSL_ADIF_GET_FIELD_SUCCESS, TQSL_ADIF_GET_FIELD_NO_NAME_MATCH, TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH, TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH,
  TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH, TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION, TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW, TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW,
  TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW, TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW, TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE, TQSL_ADIF_GET_FIELD_EOF
}
 Response values returned from tqsl_getADIFField()
 

Functions

DLLEXPORT const char
*CALLCONVENTION 
tqsl_adifGetError (TQSL_ADIF_GET_FIELD_ERROR status)
 
DLLEXPORT int CALLCONVENTION tqsl_beginADIF (tQSL_ADIF *adifp, const char *filename)
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFField (tQSL_ADIF adif, tqsl_adifFieldResults *field, TQSL_ADIF_GET_FIELD_ERROR *status, const tqsl_adifFieldDefinitions *adifFields, const char *const *typesDefined, unsigned char *(*allocator)(size_t))
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFLine (tQSL_ADIF adif, int *lineno)
 
DLLEXPORT int CALLCONVENTION tqsl_endADIF (tQSL_ADIF *adifp)
 
DLLEXPORT int CALLCONVENTION tqsl_adifMakeField (const char *fieldname, char type, const unsigned char *value, int len, unsigned char *buf, int buflen)
 

Detailed Description

These functions and data structures provide a means of parsing an ADIF file into its component fields, along with range-checking the field contents.

Enumeration Type Documentation

Boolean type - TRUE/FALSE

Function Documentation

DLLEXPORT const char* CALLCONVENTION tqsl_adifGetError ( TQSL_ADIF_GET_FIELD_ERROR  status)

Get the ADIF error message that corresponds to a particular error value

DLLEXPORT int CALLCONVENTION tqsl_adifMakeField ( const char *  fieldname,
char  type,
const unsigned char *  value,
int  len,
unsigned char *  buf,
int  buflen 
)

Form an ADIF field string.

N.B. On systems that distinguish text-mode files from binary-mode files, notably Windows, the text should be written in binary mode.

DLLEXPORT int CALLCONVENTION tqsl_beginADIF ( tQSL_ADIF adifp,
const char *  filename 
)

Initialize an ADIF file for reading

DLLEXPORT int CALLCONVENTION tqsl_endADIF ( tQSL_ADIF adifp)

End and release an ADIF file

DLLEXPORT int CALLCONVENTION tqsl_getADIFField ( tQSL_ADIF  adif,
tqsl_adifFieldResults field,
TQSL_ADIF_GET_FIELD_ERROR status,
const tqsl_adifFieldDefinitions adifFields,
const char *const *  typesDefined,
unsigned char *(*)(size_t)  allocator 
)

Get the next field from an ADIF file

  • adif - ADIF handle returned from tqsl_beginADIF()
  • field - pointer to struct that contains the field data and description
  • status - pointer to returned status variable
  • adifFields - pointer to an array of field-definition structures. The last item in the array should have an empty string as its name member.
  • typesDefined - pointer to an array of char pointers that define the allowed field-type strings. The last item in the array should point to an empty string.
  • allocator - pointer to a function that returns a pointer to a memory block of the specified size. This function will be called at most one time during a call to tqsl_getADIFField. The returned pointer will then be used to populate the data member of field. The caller is responsible for freeing this memory, if needed.
DLLEXPORT int CALLCONVENTION tqsl_getADIFLine ( tQSL_ADIF  adif,
int *  lineno 
)

Get the current line number (starting from 1) of the input file

tqsl-2.0/src/doxygen/html/globals_vars.html0000664000076400007640000000641612231073120021120 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 
tqsl-2.0/src/doxygen/html/globals_type.html0000664000076400007640000000640712231073120021126 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 
tqsl-2.0/src/doxygen/html/globals_func.html0000664000076400007640000005537012231073120021103 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 

- t -

tqsl-2.0/src/doxygen/html/globals_eval.html0000664000076400007640000000563712231073120021100 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 
tqsl-2.0/src/doxygen/html/globals_enum.html0000664000076400007640000000574312231073120021113 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 
tqsl-2.0/src/doxygen/html/globals_defs.html0000664000076400007640000003313512231073120021064 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
 

- c -

- d -

- t -

tqsl-2.0/src/doxygen/html/globals_0x74.html0000664000076400007640000010737612231073120020656 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
Here is a list of all documented file members with links to the documentation:

- t -

tqsl-2.0/src/doxygen/html/globals_0x64.html0000664000076400007640000000603712231073120020645 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
Here is a list of all documented file members with links to the documentation:

- d -

tqsl-2.0/src/doxygen/html/globals.html0000664000076400007640000000604612231073120020064 0ustar rmurphyrmurphy TrustedQSL Library API: File Members
Here is a list of all documented file members with links to the documentation:

- c -

tqsl-2.0/src/doxygen/html/functions_vars.html0000664000076400007640000002541012231073120021500 0ustar rmurphyrmurphy TrustedQSL Library API: Class Members - Variables
 

- a -

- b -

- c -

- d -

- e -

- f -

- h -

- m -

- n -

- o -

- p -

- q -

- r -

- s -

- t -

- u -

- v -

- y -

tqsl-2.0/src/doxygen/html/functions.html0000664000076400007640000002557012231073120020454 0ustar rmurphyrmurphy TrustedQSL Library API: Class Members
Here is a list of all documented class members with links to the class documentation for each member:

- a -

- b -

- c -

- d -

- e -

- f -

- h -

- m -

- n -

- o -

- p -

- q -

- r -

- s -

- t -

- u -

- v -

- y -

tqsl-2.0/src/doxygen/html/ftv2vertline.png0000664000076400007640000000012612231073120020704 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATxݱðScOx@ y}IENDB`tqsl-2.0/src/doxygen/html/ftv2splitbar.png0000664000076400007640000000047212231073120020700 0ustar rmurphyrmurphyPNG  IHDRMIDATxݡJCa( %4 bȘͶ3v^EL ,b;{Ï/aYկq:\IIIIIIIIIIIIIIIIII-l揊_t/ϻYQVYivk_ۣI@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$I@$C[V=[fIENDB`tqsl-2.0/src/doxygen/html/ftv2pnode.png0000664000076400007640000000034512231073120020164 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATx=QFDk:FPK؃=V@ճ 8SHx0bnrr{򽿾$ TP XOd6"SOB(Q)+YĈ ҪR>Vtsm9(k-@ȧ-$ b [he Kp-l|CApRG'rͭaIENDB`tqsl-2.0/src/doxygen/html/ftv2plastnode.png0000664000076400007640000000034512231073120021050 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATx=QFDk:FPK؃=V@ճ 8SHx0bnrr{򽿾$ TP XOd6"SOB(Q)+YĈ ҪR>Vtsm9(k-@ȧ-$ b [he Kp-l|CApRG'rͭaIENDB`tqsl-2.0/src/doxygen/html/ftv2ns.png0000664000076400007640000000060412231073120017475 0ustar rmurphyrmurphyPNG  IHDR}\KIDATx1K1 G⁂n lE(nࢋMA@ tK%ܕ ]BI%uͅa,e v祫i\tun0oV\$G.&@Y=%$um6'߫9Q\b)0-ZTH`pcsm 5:>ަI F] jgo[ on Ԭvq?\ 6Tee lQ c3*dWTM\rh61F fIENDB`tqsl-2.0/src/doxygen/html/ftv2node.png0000664000076400007640000000012612231073120020001 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATxݱðScOx@ y}IENDB`tqsl-2.0/src/doxygen/html/ftv2mo.png0000664000076400007640000000062312231073120017471 0ustar rmurphyrmurphyPNG  IHDR}\ZIDATx1K@iBҡ(h"EI'oک 8R- BTP]zB3 _㒻}]V}dIiJb+|K…,[P\ʘMƢ#F`JݤkA?Y4ck6"Z)0SHM@㋺Wmo4HJ+Qobt *~8_+3Y- PwA+^}+xhϕMAE]TD~EÞߴ^R)`A9pq-۾ۍ3tƛTH) ICxd#1 m@V?Zgo_3-\IENDB`tqsl-2.0/src/doxygen/html/ftv2mnode.png0000664000076400007640000000036612231073120020164 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATx!NA\ Um@`5i`h W7] b&ofdY4 c 3v=]\B I=BB;k WN@vy4]Y|M}]x6a }dׇY>||5?>|B"'IENDB`tqsl-2.0/src/doxygen/html/ftv2mlastnode.png0000664000076400007640000000036612231073120021050 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATx!NA\ Um@`5i`h W7] b&ofdY4 c 3v=]\B I=BB;k WN@vy4]Y|M}]x6a }dׇY>||5?>|B"'IENDB`tqsl-2.0/src/doxygen/html/ftv2link.png0000664000076400007640000000135212231073120020013 0ustar rmurphyrmurphyPNG  IHDR}\IDATxMOS[sa?-XZ(PD4 AWbu`b 77wHFCԁ/`voAPqP@ 980 +y^Z9SW\83g3'Nçl_bpV"ֆXd]3xM[1W *PGz/Eg{ aoV:这1$RW,@56-,m/蹖 r5T*S(Vf89u գwa=<{ҡUr+dDF$`zNܮ0Q3~_^N=vpTLT}kqm<?ZhX_ݥ[) `ga_*2`'=F2EP l=8Wv%THqɿ<"GxH{#֫aJmKsVءM^ T ݛr߽m_?Wİ#uIENDB`tqsl-2.0/src/doxygen/html/ftv2lastnode.png0000664000076400007640000000012612231073120020665 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATxݱðScOx@ y}IENDB`tqsl-2.0/src/doxygen/html/ftv2folderopen.png0000664000076400007640000000112512231073120021211 0ustar rmurphyrmurphyPNG  IHDR}\IDATx]?oP9i4i;iiZ7`b٬,HU'$*T]TDP6w};C; aӝߟjAInS}9Hӎ|? =_Ɗue*;YEsYBėsٌ ɫYq !Gǿv̇خ F}qb]70)d-}PfY{4@}2ԗNIǃc%UImcƝ>xt9$ OVE*Û#׈r@l$PrHaa dZrqIoT\,tj2FAxv-Lp׌p TI/ \sf; jViTo^cpb]€<a՜y9:+,E f6NEKU}^;nZuUS4 ѬbN.kjT% iV )GJ@TxIENDB`tqsl-2.0/src/doxygen/html/ftv2folderclosed.png0000664000076400007640000000115012231073120021517 0ustar rmurphyrmurphyPNG  IHDR}\/IDATx]MO@~uؐlp]#]PYEC\9y`xC &=qvZv3m؃vLN}}ޝZA@n ONp xKxj8s _[D'yye+ 7#rNlk* 0Ь_d_(Öz=xvhzP-䍒̪u$\DJcB4.:Ϗ-}LE #gN;B6䬜@p&h>p9EEάʑ"un$R"?{<%PNt$߶+^<"2Dqq\ҙaA"ԵP}#Ez{.8i p(ADwDE߂z;Kק8t q:uvvݛvEn{MFXgfZ֝*ߩ:jYq#3SWr'  IENDB`tqsl-2.0/src/doxygen/html/ftv2doc.png0000664000076400007640000000135212231073120017623 0ustar rmurphyrmurphyPNG  IHDR}\IDATxMOS[sa?-XZ(PD4 AWbu`b 77wHFCԁ/`voAPqP@ 980 +y^Z9SW\83g3'Nçl_bpV"ֆXd]3xM[1W *PGz/Eg{ aoV:这1$RW,@56-,m/蹖 r5T*S(Vf89u գwa=<{ҡUr+dDF$`zNܮ0Q3~_^N=vpTLT}kqm<?ZhX_ݥ[) `ga_*2`'=F2EP l=8Wv%THqɿ<"GxH{#֫aJmKsVءM^ T ݛr߽m_?Wİ#uIENDB`tqsl-2.0/src/doxygen/html/ftv2cl.png0000664000076400007640000000070512231073120017455 0ustar rmurphyrmurphyPNG  IHDR}\IDATx;H#Ao4ႇK ,m vڞJ XY B|drcvoİ 0Ò3ͤe״1X8nQ88֧3*rb-$P1@Z-#011HkK wO@!fuc;sB[EA\>]Pzf| +g5b i5mM_q,cod!,{Y,zT8H]𤕘7/8Q!F~6?Y A@Ũ.@TYr8*>?e[6xIENDB`tqsl-2.0/src/doxygen/html/ftv2blank.png0000664000076400007640000000012612231073120020143 0ustar rmurphyrmurphyPNG  IHDRɪ|IDATxݱðScOx@ y}IENDB`tqsl-2.0/src/doxygen/html/files.html0000664000076400007640000000750012231073120017537 0ustar rmurphyrmurphy TrustedQSL Library API: File List
File List
Here is a list of all documented files with brief descriptions:
tqsl-2.0/src/doxygen/html/dynsections.js0000664000076400007640000000564712231073120020461 0ustar rmurphyrmurphyfunction toggleVisibility(linkObj) { var base = $(linkObj).attr('id'); var summary = $('#'+base+'-summary'); var content = $('#'+base+'-content'); var trigger = $('#'+base+'-trigger'); var src=$(trigger).attr('src'); if (content.is(':visible')===true) { content.hide(); summary.show(); $(linkObj).addClass('closed').removeClass('opened'); $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png'); } else { content.show(); summary.hide(); $(linkObj).removeClass('closed').addClass('opened'); $(trigger).attr('src',src.substring(0,src.length-10)+'open.png'); } return false; } function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); } function toggleLevel(level) { $('table.directory tr').each(function(){ var l = this.id.split('_').length-1; var i = $('#img'+this.id.substring(3)); var a = $('#arr'+this.id.substring(3)); if (lmuľe5{Jկ(bl}`UyacCAklysA7oJ .Be. Z'-PyF.lp&.j7rez19HG%qz׈c_k_")HJn~֘5 q5#+9T Rܸrzϴ̝ =υ{áOfwg|/$;֙ƭ]W"/< DఽB}yIEc^=[VhM$l];Kr¦* t$]M;I1!M (f<5~z mՠ>کIz;u[ie^ӳNF6B\}7+,'a -yHY,^f~?Hc{Z+4\sٷnߣFơsغD?<vkx0MlذIxdEEAMg*YE7ۙ^[uv[wG=Edn׶l'pGk+C82 dz3H BS[wŘ ~xptmţiQ歉AB1fى4uI]6% 1t.NJphz̠R1"3-"&1[:N mW0_œ 6&)ꦬ}~{m]zMP~^:eQT_*798ˍ 347E¿uSɻU_ NWeNӏ|;;d"ȉ޵ᆴ"ĴMM+bY_E]PXKНIޥoE<_(EP|m,өZߺk,kM`jzeU t36˷r}w:Χ |TܵQK_pໃYd0!a –W$$/\$ 2mLH dHV,:RZJaz*>_NT(‚^SVFU8E܈nd;8\C]=m:bDd=ߞUU5O|]Pv\]2"y[yzg{Y{Ù5;w{N3nĨwKݭ29Id y)P8ũ@mPwjl,6 hWd ump.DžtwR xBδYcxg*vo y򑕓[?V0NO난~󒯷h#Hk8kӍ^q@]ӓ,56-κUn[>]@nϜp[6# 4tn:}8T9_Y$/GK(ђM`dѺ;OB &P{qhJ+閧l2M_1ӫtlya L^y.۽[ u/]iS}N>e1qjf&iT\=kϛX-.84V5u!TE .OH4zwTr. xքHHg hT$yqzp< qrwI]I鲘s":ՖbզL69VW<;3?M3AV#ޯKUr9!qtH+6V/TS^pqgLP'5E ޺ n"2|;W"֬TwtO' +W+Z̖<&nO,I06.Z.h*INڒOegBXZ9hDSʍ A/c`A"z|ş;H#|%OOD mcƤqmu&~n πZj =_n[nN$_bE)8?6l}#bW( d-p&a"9ņ$ڛA!;{~8ޣ10`#kuN Qbh 8Mawhq(bK Z%m֍(J)@> 7% {y ohf>{p.­_%glZ\B2B #Һphݚ[<#SpA7Ht4:|gtL*($Ʃ$;b`=MM5ǾHH.HeA5}rd)T};Q5i2O00;,냔}g]79_{C>h{.II?[Kswz6u;OJa˶zvd l舊yc'rTWӰL |ʽhB T'ò]K(=Kx  L,Pʵu׈ž1ݫ;pGDxZY kf676oھH~޸ 8Up6(? K+?%ݷ/19U?B)l @=ޞkIENDB`tqsl-2.0/src/doxygen/html/closed.png0000664000076400007640000000020412231073120017520 0ustar rmurphyrmurphyPNG  IHDR KIDATxm @!Gk7-`&sts@k}2 P%_N .:0Dk›x" ֛)x5IENDB`tqsl-2.0/src/doxygen/html/classes.html0000664000076400007640000000663212231073120020077 0ustar rmurphyrmurphy TrustedQSL Library API: Class Index
Class Index
tqsl-2.0/src/doxygen/html/cabrillo_8h_source.html0000664000076400007640000004517112231073120022211 0ustar rmurphyrmurphy TrustedQSL Library API: cabrillo.h Source File
cabrillo.h
Go to the documentation of this file.
1 /***************************************************************************
2  cabrillo.h - description
3  -------------------
4  begin : Thu Dec 5 2002
5  copyright : (C) 2002 by ARRL
6  author : Jon Bloom
7  email : jbloom@arrl.org
8  revision : $Id$
9  ***************************************************************************/
10 
11 #ifndef __CABRILLO_H
12 #define __CABRILLO_H
13 
14 #include "tqsllib.h"
15 
16 #undef CLIENT_STATIC
17 #ifndef LOTW_SERVER
18 #define CLIENT_STATIC static
19 #else
20 #define CLIENT_STATIC
21 #endif
22 
35 #define TQSL_CABRILLO_MAX_FIELDS 12
36 #define TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX 64
37 #define TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX 40
38 
39 
40 typedef enum {
41  TQSL_CABRILLO_NO_ERROR,
42  TQSL_CABRILLO_EOF,
43  TQSL_CABRILLO_NO_START_RECORD,
44  TQSL_CABRILLO_NO_CONTEST_RECORD,
45  TQSL_CABRILLO_UNKNOWN_CONTEST,
46  TQSL_CABRILLO_BAD_FIELD_DATA,
47  TQSL_CABRILLO_EOR,
49 
53 typedef enum {
54  TQSL_CABRILLO_HF,
55  TQSL_CABRILLO_VHF,
56  TQSL_CABRILLO_UNKNOWN,
58 
59 // Minimum field number for callsign and default field number
60 // For VHF, default should be 7.
61 #define TQSL_MIN_CABRILLO_MAP_FIELD 5
62 #define TQSL_DEF_CABRILLO_MAP_FIELD 8
63 
64 
69 typedef struct {
73 
74 typedef void * tQSL_Cabrillo;
75 
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79 
82 
84 DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo(tQSL_Cabrillo *cabp, const char *filename);
85 
87 DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest(tQSL_Cabrillo cab, char *buf, int bufsiz);
88 
91 
94 
97 
107 
110 
111 #ifdef __cplusplus
112 }
113 #endif
114 
117 #endif // __CABRILLO_H
tqsl-2.0/src/doxygen/html/cabrillo_8h.html0000664000076400007640000003514512231073120020631 0ustar rmurphyrmurphy TrustedQSL Library API: cabrillo.h File Reference
cabrillo.h File Reference
#include "tqsllib.h"

Go to the source code of this file.

Classes

struct  tqsl_cabrilloField
 

Macros

#define CLIENT_STATIC   static
 Static linkage.
 
#define TQSL_CABRILLO_MAX_FIELDS   12
 Max field count.
 
#define TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX   64
 Max field name length.
 
#define TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX   40
 Max field value length.
 
#define TQSL_MIN_CABRILLO_MAP_FIELD   5
 First possible call-worked field.
 
#define TQSL_DEF_CABRILLO_MAP_FIELD   8
 Default call-worked field.
 

Typedefs

typedef void * tQSL_Cabrillo
 Opaque cabrillo log type.
 

Enumerations

enum  TQSL_CABRILLO_ERROR_TYPE {
  TQSL_CABRILLO_NO_ERROR, TQSL_CABRILLO_EOF, TQSL_CABRILLO_NO_START_RECORD, TQSL_CABRILLO_NO_CONTEST_RECORD,
  TQSL_CABRILLO_UNKNOWN_CONTEST, TQSL_CABRILLO_BAD_FIELD_DATA, TQSL_CABRILLO_EOR
}
 Cabrillo status values.
 
enum  TQSL_CABRILLO_FREQ_TYPE { TQSL_CABRILLO_HF, TQSL_CABRILLO_VHF, TQSL_CABRILLO_UNKNOWN }
 

Functions

DLLEXPORT const char
*CALLCONVENTION 
tqsl_cabrilloGetError (TQSL_CABRILLO_ERROR_TYPE err)
 
DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo (tQSL_Cabrillo *cabp, const char *filename)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest (tQSL_Cabrillo cab, char *buf, int bufsiz)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloFreqType (tQSL_Cabrillo cab, TQSL_CABRILLO_FREQ_TYPE *type)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloLine (tQSL_Cabrillo cab, int *lineno)
 
DLLEXPORT const char
*CALLCONVENTION 
tqsl_getCabrilloRecordText (tQSL_Cabrillo cab)
 
DLLEXPORT int CALLCONVENTION tqsl_getCabrilloField (tQSL_Cabrillo cab, tqsl_cabrilloField *field, TQSL_CABRILLO_ERROR_TYPE *err)
 
DLLEXPORT int CALLCONVENTION tqsl_endCabrillo (tQSL_Cabrillo *cabp)
 
tqsl-2.0/src/doxygen/html/bdwn.png0000664000076400007640000000022312231073120017202 0ustar rmurphyrmurphyPNG  IHDR5ZIDATx DP1lm rj.e D[ɾ|6V3?Ls'(}>+ Kch` ^ލnIENDB`tqsl-2.0/src/doxygen/html/bc_s.png0000664000076400007640000000124412231073120017162 0ustar rmurphyrmurphyPNG  IHDR_ kIDATxkQϝ̤I&m&156*nąܸR,4 +H(Ub1J.(EmߏhJmKS'C(х & r3g(z&_9}՟@mu ` h`ԯ &~M4%3?h)\Yi>Jb @giވkg\轭EUv+?E"pB\Y&$vM+Dn)}:Xo 3گ'.f0u9Ljf6%3Gf#sm(,k*ʒJJˢou_~ r]%%mnu]zr5[ưXeI TrustedQSL Library API: Class List
Class List
Here are the classes, structs, unions and interfaces with brief descriptions:
tqsl-2.0/src/doxygen/html/adif_8h_source.html0000664000076400007640000005751112231073120021326 0ustar rmurphyrmurphy TrustedQSL Library API: adif.h Source File
adif.h
Go to the documentation of this file.
1 /***************************************************************************
2  adif.h - description
3  -------------------
4  begin : Wed May 15 2002
5  copyright : (C) 2002 by ARRL
6  email : MSimcik@localhost.localdomain
7  revision : $Id$
8  ***************************************************************************/
9 
10 #ifndef __ADIF_H
11 #define __ADIF_H
12 
13 #include "tqsllib.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 
28 #define TQSL_ADIF_FIELD_NAME_LENGTH_MAX 64
29 #define TQSL_ADIF_FIELD_SIZE_LENGTH_MAX 10
30 #define TQSL_ADIF_FIELD_TYPE_LENGTH_MAX 1
31 
32 
35 #ifndef TQSL_ADIF_BOOLEAN
36 typedef enum
37 {
38  TQSL_FALSE,
39  TQSL_TRUE
41 #endif
42 
43 typedef void * tQSL_ADIF;
44 
46 typedef enum
47 {
48  TQSL_ADIF_RANGE_TYPE_NONE,
49  TQSL_ADIF_RANGE_TYPE_MINMAX,
50  TQSL_ADIF_RANGE_TYPE_ENUMERATION
52 
54 typedef enum
55 {
56  TQSL_ADIF_GET_FIELD_SUCCESS,
57  TQSL_ADIF_GET_FIELD_NO_NAME_MATCH,
58  TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH,
59  TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH,
60  TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH,
61  TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION,
62  TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW,
63  TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW,
64  TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW,
65  TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW,
66  TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE,
67  TQSL_ADIF_GET_FIELD_EOF
69 
71 typedef struct
72 {
76  unsigned int max_length;
77  long signed min_value;
78  long signed max_value;
79  const char **enumStrings;
80  void *userPointer;
82 
84 typedef struct
85 {
89  unsigned char *data;
90  unsigned int adifNameIndex;
91  void *userPointer;
93 
94 
95 /* function prototypes */
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
103 
105 DLLEXPORT int CALLCONVENTION tqsl_beginADIF(tQSL_ADIF *adifp, const char *filename);
106 
124  const tqsl_adifFieldDefinitions *adifFields, const char * const *typesDefined,
125  unsigned char *(*allocator)(size_t) );
126 
128 DLLEXPORT int CALLCONVENTION tqsl_getADIFLine(tQSL_ADIF adif, int *lineno);
129 
132 
138 DLLEXPORT int CALLCONVENTION tqsl_adifMakeField(const char *fieldname, char type, const unsigned char *value, int len,
139  unsigned char *buf, int buflen);
140 
141 #ifdef __cplusplus
142 }
143 #endif
144 
147 #endif /* __ADIF_H */
tqsl-2.0/src/doxygen/html/adif_8h.html0000664000076400007640000003144712231073120017746 0ustar rmurphyrmurphy TrustedQSL Library API: adif.h File Reference
adif.h File Reference
#include "tqsllib.h"
#include <stdio.h>
#include <stdlib.h>

Go to the source code of this file.

Classes

struct  tqsl_adifFieldDefinitions
 
struct  tqsl_adifFieldResults
 

Macros

#define TQSL_ADIF_FIELD_NAME_LENGTH_MAX   64
 Max length of ADIF field.
 
#define TQSL_ADIF_FIELD_SIZE_LENGTH_MAX   10
 Max length of field name.
 
#define TQSL_ADIF_FIELD_TYPE_LENGTH_MAX   1
 Max length of field type.
 

Typedefs

typedef void * tQSL_ADIF
 Opaque ADIF type.
 

Enumerations

enum  TQSL_ADIF_BOOLEAN { TQSL_FALSE, TQSL_TRUE }
 
enum  TQSL_ADIF_RANGE_TYPE { TQSL_ADIF_RANGE_TYPE_NONE, TQSL_ADIF_RANGE_TYPE_MINMAX, TQSL_ADIF_RANGE_TYPE_ENUMERATION }
 Specifies the type of range limits to apply to a field.
 
enum  TQSL_ADIF_GET_FIELD_ERROR {
  TQSL_ADIF_GET_FIELD_SUCCESS, TQSL_ADIF_GET_FIELD_NO_NAME_MATCH, TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH, TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH,
  TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH, TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION, TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW, TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW,
  TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW, TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW, TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE, TQSL_ADIF_GET_FIELD_EOF
}
 Response values returned from tqsl_getADIFField()
 

Functions

DLLEXPORT const char
*CALLCONVENTION 
tqsl_adifGetError (TQSL_ADIF_GET_FIELD_ERROR status)
 
DLLEXPORT int CALLCONVENTION tqsl_beginADIF (tQSL_ADIF *adifp, const char *filename)
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFField (tQSL_ADIF adif, tqsl_adifFieldResults *field, TQSL_ADIF_GET_FIELD_ERROR *status, const tqsl_adifFieldDefinitions *adifFields, const char *const *typesDefined, unsigned char *(*allocator)(size_t))
 
DLLEXPORT int CALLCONVENTION tqsl_getADIFLine (tQSL_ADIF adif, int *lineno)
 
DLLEXPORT int CALLCONVENTION tqsl_endADIF (tQSL_ADIF *adifp)
 
DLLEXPORT int CALLCONVENTION tqsl_adifMakeField (const char *fieldname, char type, const unsigned char *value, int len, unsigned char *buf, int buflen)
 
tqsl-2.0/src/doxygen/html/.gitignore0000664000076400007640000000001712231073120017533 0ustar rmurphyrmurphy._* #osx cruft tqsl-2.0/src/converter.cpp0000664000076400007640000000651712231073120015650 0ustar rmurphyrmurphy/*************************************************************************** converter.cpp - c++ example program for signing a log ------------------- begin : Sun Dec 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include #include #include #include #ifdef HAVE_GETOPT_H #include #endif #include "tqsllib.h" #include "tqslerrno.h" #include "tqslconvert.h" #include "tqslexc.h" using namespace std; int usage() { cerr << "Usage: converter [-ac] station-location infile [outfile]\n"; exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { enum { UNKNOWN, CABRILLO, ADIF } type = UNKNOWN; int opt; while ((opt = getopt(argc, argv, "ca")) != -1) { switch (opt) { case 'c': type = CABRILLO; break; case 'a': type = ADIF; break; default: usage(); } } if (argc - optind < 2) usage(); tQSL_Converter conv = 0; try { if (tqsl_init()) throw tqslexc(); // Get the specified station location data tQSL_Location loc; if (tqsl_getStationLocation(&loc, argv[optind++])) throw tqslexc(); // Get the callsign and DXCC entity to use char call[256]; int dxcc; if (tqsl_getLocationCallSign(loc, call, sizeof call)) throw tqslexc(); if (tqsl_getLocationDXCCEntity(loc, &dxcc)) throw tqslexc(); // Get a list of available signing certificates tQSL_Cert *certs; int ncerts; if (tqsl_selectCertificates(&certs, &ncerts, call, dxcc, 0, 0, 1)) throw tqslexc(); if (ncerts < 1) throw myexc(string("No certificates available for ") + call); int stat = 1; if (type == UNKNOWN || type == CABRILLO) { if ((stat = tqsl_beginCabrilloConverter(&conv, argv[optind], certs, ncerts, loc)) != 0 && type == CABRILLO) throw tqslexc(); } if (stat) { if (tqsl_beginADIFConverter(&conv, argv[optind], certs, ncerts, loc)) throw tqslexc(); } tqsl_setConverterAllowDuplicates(conv, false); optind++; const char *ofile = (optind < argc) ? argv[optind] : "converted.tq7"; ofstream out; out.open(ofile, ios::out|ios::trunc|ios::binary); if (!out.is_open()) throw myexc(string("Unable to open ") + ofile); bool haveout = false; do { const char *gabbi = tqsl_getConverterGABBI(conv); if (gabbi) { haveout = true; out << gabbi; continue; } if (tQSL_Error == TQSL_SIGNINIT_ERROR) { tQSL_Cert cert; if (tqsl_getConverterCert(conv, &cert)) throw tqslexc(); if (tqsl_beginSigning(cert, 0, 0, 0)) throw tqslexc(); continue; } if (tQSL_Error == TQSL_DUPLICATE_QSO) continue; break; } while (1); out.close(); if (tQSL_Error != TQSL_NO_ERROR) throw tqslexc(); else if (!haveout) cerr << "Empty log file" << endl; } catch (exception& x) { char buf[40] = ""; int lineno; if (conv && !tqsl_getConverterLine(conv, &lineno)) // && lineno > 0) snprintf(buf, sizeof buf, " on line %d", lineno); cerr << "Aborted: " << x.what() << buf << endl; tqsl_converterRollBack(conv); return EXIT_FAILURE; } tqsl_converterCommit(conv); return EXIT_SUCCESS; } tqsl-2.0/src/converter.c0000664000076400007640000000640612231073120015305 0ustar rmurphyrmurphy/*************************************************************************** converter.c - "C" example program for signing a log ------------------- begin : Sun Dec 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include #include #include #include #include #include #include "tqsllib.h" #include "tqslerrno.h" #include "tqslconvert.h" int usage() { fprintf(stderr, "Usage: converter [-ac] station-location infile [outfile]\n"); exit(EXIT_FAILURE); } void fail(tQSL_Converter conv) { char buf[40]; const char *err = tqsl_getErrorString(); int lineno; buf[0] = '\0'; if (conv && !tqsl_getConverterLine(conv, &lineno)) // && lineno > 0) sprintf(buf, " on line %d", lineno); fprintf(stderr, "Aborted: %s%s\n", err, buf); if (conv) tqsl_converterRollBack(conv); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { enum { UNKNOWN, CABRILLO, ADIF } type = UNKNOWN; int opt; tQSL_Location loc; tQSL_Converter conv = 0; int stat = 1; char call[256]; int dxcc; tQSL_Cert *certs; int ncerts; int haveout = 0; const char *ofile; int out; while ((opt = getopt(argc, argv, "ca")) != -1) { switch (opt) { case 'c': type = CABRILLO; break; case 'a': type = ADIF; break; default: usage(); } } if (argc - optind < 2) usage(); if (tqsl_init()) fail(conv); // Get the specified station location data if (tqsl_getStationLocation(&loc, argv[optind++])) fail(conv); // Get the callsign and DXCC entity to use if (tqsl_getLocationCallSign(loc, call, sizeof call)) fail(conv); if (tqsl_getLocationDXCCEntity(loc, &dxcc)) fail(conv); // Get a list of available signing certificates if (tqsl_selectCertificates(&certs, &ncerts, call, dxcc, 0, 0, 1)) fail(conv); if (ncerts < 1) { fprintf(stderr, "No certificates available for %s\n", call); exit (EXIT_FAILURE); } if (type == UNKNOWN || type == CABRILLO) { if ((stat = tqsl_beginCabrilloConverter(&conv, argv[optind], certs, ncerts, loc)) != 0 && type == CABRILLO) fail(conv); } if (stat) { if (tqsl_beginADIFConverter(&conv, argv[optind], certs, ncerts, loc)) fail(conv); } tqsl_setConverterAllowDuplicates(conv, 0); optind++; ofile = (optind < argc) ? argv[optind] : "converted.tq8"; out = creat(ofile, 0660); if (out < 0) { fprintf(stderr, "Unable to open %s\n", ofile); exit (EXIT_FAILURE); } tqsl_setConverterAppName(conv, "converter-sample"); do { const char *gabbi = tqsl_getConverterGABBI(conv); if (gabbi) { haveout = 1; write(out, gabbi, strlen(gabbi)); continue; } if (tQSL_Error == TQSL_SIGNINIT_ERROR) { tQSL_Cert cert; if (tqsl_getConverterCert(conv, &cert)) fail(conv); if (tqsl_beginSigning(cert, 0, 0, 0)) fail(conv); continue; } if (tQSL_Error == TQSL_DUPLICATE_QSO) continue; break; } while (1); close(out); if (tQSL_Error != TQSL_NO_ERROR) fail(conv); else if (!haveout) fprintf(stderr, "Empty log file\n"); tqsl_converterCommit(conv); return EXIT_SUCCESS; } tqsl-2.0/src/config.xml0000664000076400007640000054004112231073120015117 0ustar rmurphyrmurphy AMTORFEC ASCI BPSK125 BPSK31 BPSK63 CHIP128 CHIP64 CLO DOMINOF FMHELL HELL80 HFSK ISCAT-A ISCAT-B JT4A JT4B JT4C JT4D JT4E JT4F JT4G JT65A JT65B JT65B2 JT65C JT65C2 JT9-1 JT9-10 JT9-2 JT9-30 JT9-5 LSB MTTY OP05 OP1 OP15 OP2 OP32 OP4 OP4H OP8 PAC PAC2 PAC3 PAX2 PCW PKT PSKAM10 PSKAM31 PSKAM50 PSKHELL QPSK125 QPSK31 QPSK63 THRB THRBX TOR USB 1.25CM 1.25M 10M 12M 13CM 15M 160M 17M 1MM 2.5MM 20M 2190M 23CM 2M 2MM 30M 33CM 3CM 40M 4M 4MM 60M 6CM 6M 6MM 70CM 80M 9CM SUBMM 7QP AADX-CW AADX-SSB AP-SPRINT ARI-DX ARRL-10 ARRL-160 ARRL-DX-CW ARRL-DX-SSB ARRL-RTTY ARRL-SCR ARRL-SS-CW ARRL-SS-SSB ARRL-UHF-AUG ARRL-VHF-JAN ARRL-VHF-JUN ARRL-VHF-SEP AZQP BARTG-RTTY BARTG-SPRINT CQ-160-CW CQ-160-SSB CQ-M CQ-VHF CQ-WPX-CW CQ-WPX-RTTY CQ-WPX-SSB CQ-WW-CW CQ-WW-RTTY CQ-WW-SSB DARC-WAEDC-CW DARC-WAEDC-RTTY DARC-WAEDC-SSB DE_QSO-PARTY EU Sprint EUHFC FCG-FQP HELVETIA IARU-HF IL QSO Party IN QSO Party JARTS-WW_RTTY JIDX-CW JIDX-SSB MI-QSO-PARTY MRRC-OhQP NA-SPRINT-CW NA-SPRINT-SSB NAQP-CW NAQP-RTTY NAQP-SSB NCCC-CQP NEQP NRAU-BALTIC-CW NRAU-BALTIC-SSB NY-QSO-PARTY OCEANIA-DX-CW OCEANIA-DX-SSB OK-OM-DX PACC RAC CANADA DAY RAC CANADA WINTER RADIO-WW-RTTY RAEM RDAC RDXC REF-160M REF-CW REF-SSB RSGB-160 RSGB-21/28 RSGB-80M-CC RSGB-80M-SPRINT RSGB-AFS-CW RSGB-AFS-SSB RSGB-CLUB-CALLS RSGB-COMMONWEALTH RSGB-IOTA RSGB-LOW-POWER RSGB-NFD RSGB-ROPOCO RSGB-SSB-FD SAC-CW SAC-SSB SARTG-RTTY SC-QSO-PARTY SCC RTTY SP-DX-RTTY SPDXContest STEW-PERRY State QSO Party - GA TARA-RTTY TMC-RTTY UBA-DX-CW UBA-DX-SSB VOLTA-RTTY Virginia QSO Party Wisconsin QSO Party -NONE- CANADA ABU AIL IS. (DELETED) AFGHANISTAN AGALEGA & ST BRANDON ISLANDS ALAND ISLAND ALASKA ALBANIA ALDABRA (DELETED) AMERICAN SAMOA AMSTERDAM & ST PAUL ISLAND ANDAMAN & NICOBAR ISLAND ANGUILLA ANTARCTICA ARMENIA ASIATIC RUSSIA AUCKLAND & CAMPBELL ISLAND AVES ISLAND AZERBAIJAN BAJO NUEVO (DELETED) BAKER HOWLAND ISLAND BALEARIC ISLAND PALAU BLENHEIM REEF (DELETED) BOUVET ISLAND BRITISH NORTH BORNEO (DELETED) BRITISH SOMALILAND (DELETED) BELARUS CANAL ZONE (DELETED) CANARY ISLANDS CELEBE & MOLUCCA IS (DELETED) CENTRAL KIRIBATI CEUTA & MELILLA CHAGOS ISLAND CHATHAM ISLAND CHRISTMAS ISLAND CLIPPERTON ISLAND COCOS ISLAND COCOS (KEELING) ISLAND COMORO ISLANDS (DELETED) CRETE CROZET ISLAND DAMAO, DIU (DELETED) DESECHEO ISLAND DESROCHES (DELETED) DODECANESE EAST MALAYSIA EASTER ISLAND EASTERN KIRIBATI EQUATORIAL GUINEA MEXICO ERITREA ESTONIA ETHIOPIA EUROPEAN RUSSIA FARQUHAR (DELETED) FERNANDO DE NORONHA FRENCH EQUATORIAL AFRICA (DELETED) FRENCH INDO-CHINA (DELETED) FRENCH WEST AFRICA (DELETED) BAHAMAS FRANZ JOSEF LAND BARBADOS FRENCH GUIANA BERMUDA BRITISH VIRGIN ISLAND BELIZE FRENCH INDIA (DELETED) KUWAIT/SAUDI ARABIA NEUT. ZONE (DELETED) CAYMAN ISLANDS CUBA GALAPAGOS ISLANDS DOMINICAN REPUBLIC EL SALVADOR GEORGIA GUATEMALA GRENADA HAITI GUADELOUPE HONDURAS GERMANY (DELETED) JAMAICA MARTINIQUE BONAIRE,CURACAO (NETH ANTILLES) (DELETED) NICARAGUA PANAMA TURKS & CAICOS ISLANDS TRINIDAD & TOBAGO ARUBA GEYSER REEF (DELETED) ANTIGUA & BARBUDA DOMINICA MONTSERRAT SAINT LUCIA SAINT VINCENT GLORIOSO ISLAND ARGENTINA GOA (DELETED) GOLD COAST TOGOLAND (DELETED) GUAM BOLIVIA GUANTANAMO BAY GUERNSEY GUINEA BRAZIL GUINEA-BISSAU HAWAII HEARD ISLAND CHILE IFNI (DELETED) ISLE OF MAN ITALIAN SOMALILAND (DELETED) COLOMBIA ITU HQ JAN MAYEN JAVA (DELETED) ECUADOR JERSEY JOHNSTON ISLAND JUAN DE NOVA, EUROPA JUAN FERNANDEZ ISLAND KALININGRAD KAMARAN ISLANDS (DELETED) KARELO-FINNISH REP (DELETED) GUYANA KAZAKHSTAN KERGUELEN ISLAND PARAGUAY KERMADEC ISLAND KINGMAN REEF KYRGYZSTAN PERU REPUBLIC OF KOREA KURE ISLAND KURIA MURIA ISLAND (DELETED) SURINAME FALKLAND ISLANDS LAKSHADWEEP ISLANDS LAOS URUGUAY LATVIA LITHUANIA LORD HOWE ISLAND VENEZUELA AZORES AUSTRALIA MALYJ VYSOTSKIJ ISLAND (DELETED) MACAO MACQUARIE ISLAND YEMEN ARAB REPUBLIC (DELETED) MALAYA (DELETED) NAURU VANUATU MALDIVES TONGA MALPELO ISLAND NEW CALEDONIA PAPUA NEW GUINEA MANCHURIA (DELETED) MAURITIUS ISLAND MARIANA ISLANDS MARKET REEF MARSHALL ISLANDS MAYOTTE ISLAND NEW ZEALAND MELLISH REEF PITCAIRN ISLAND MICRONESIA MIDWAY ISLAND FRENCH POLYNESIA FIJI ISLANDS MINAMI TORISHIMA MINERVA REEF (DELETED) MOLDOVA MOUNT ATHOS MOZAMBIQUE NAVASSA ISLAND NETHERLANDS BORNEO (DELETED) NETHERLANDS N GUINEA (DELETED) SOLOMON ISLANDS NEWFOUNDLAND LABRADOR (DELETED) NIGER NIUE NORFOLK ISLAND SAMOA NORTH COOK ISLANDS OGASAWARA OKINAWA (DELETED) OKINO TORI-SHIMA (DELETED) ANNOBON PALESTINE (DELETED) PALMYRA & JARVIS ISLANDS PAPUA TERRITORY (DELETED) PETER 1 ISLAND PORTUGUESE TIMOR (DELETED) PRINCE EDWARD & MARION ISLANDS PUERTO RICO ANDORRA REVILLAGIGEDO ASCENSION ISLAND AUSTRIA RODRIGUEZ ISLAND RUANDA-URUNDI (DELETED) BELGIUM SAAR (DELETED) SABLE ISLAND BULGARIA SAINT MARTIN CORSICA CYPRUS SAN ANDRES ISLAND SAN FELIX ISLAND CZECHOSLOVAKIA (DELETED) SAO TOME & PRINCIPE SARAWAK (DELETED) DENMARK FAROE ISLANDS ENGLAND FINLAND SARDINIA SAUDI ARABIA/IRAQ NEUT ZONE (DELETED) FRANCE SERRANA BANK & RONCADOR CAY (DELETED) GERMAN DEMOCRATIC REPUBLIC (DELETED) FEDERAL REPUBLIC OF GERMANY SIKKIM (DELETED) SOMALIA GIBRALTAR SOUTH COOK ISLANDS SOUTH GEORGIA ISLAND GREECE GREENLAND SOUTH ORKNEY ISLANDS HUNGARY SOUTH SANDWICH ISLANDS SOUTH SHETLAND ISLANDS ICELAND PEOPLE'S DEM REP OF YEMEN (DELETED) SOUTHERN SUDAN (DELETED) IRELAND SOV MILITARY ORDER OF MALTA SPRATLY ISLANDS ITALY SAINT KITTS & NEVIS SAINT HELENA LIECHTENSTEIN SAINT PAUL ISLAND SAINT PETER AND PAUL ROCKS LUXEMBOURG SINT MAARTEN, SABA, ST EUSTATIUS (DELETED) MADEIRA ISLANDS MALTA SUMATRA (DELETED) SVALBARD MONACO SWAN ISLAND (DELETED) TAJIKISTAN NETHERLANDS TANGIER (DELETED) NORTHERN IRELAND NORWAY TERRITORY OF NEW GUINEA (DELETED) TIBET (DELETED) POLAND TOKELAU ISLANDS TRIESTE (DELETED) PORTUGAL TRINDADE & MARTIM VAZ ISLANDS TRISTAN DA CUNHA & GOUGH IS ROMANIA TROMELIN ISLAND SAINT PIERRE & MIQUELON SAN MARINO SCOTLAND TURKMENISTAN SPAIN TUVALU U K BASES ON CYPRUS SWEDEN US VIRGIN ISLANDS UGANDA SWITZERLAND UKRAINE UNITED NATIONS HQ UNITED STATES OF AMERICA UZBEKISTAN VIET NAM WALES VATICAN CITY SERBIA WAKE ISLAND WALLIS & FUTUNA ISLAND WEST MALAYSIA WESTERN KIRIBATI WESTERN SAHARA WILLIS ISLAND BAHRAIN BANGLADESH BHUTAN ZANZIBAR (DELETED) COSTA RICA MYANMAR CAMBODIA SRI LANKA CHINA HONG KONG INDIA INDONESIA IRAN IRAQ ISRAEL JAPAN JORDAN DPRK (NORTH KOREA) BRUNEI KUWAIT LEBANON MONGOLIA NEPAL OMAN PAKISTAN PHILIPPINES QATAR SAUDI ARABIA SEYCHELLES ISLANDS SINGAPORE DJIBOUTI SYRIA TAIWAN THAILAND TURKEY UNITED ARAB EMIRATES ALGERIA ANGOLA BOTSWANA BURUNDI CAMEROON CENTRAL AFRICAN REPUBLIC CAPE VERDE CHAD COMOROS REPUBLIC OF THE CONGO DEM. REP. OF THE CONGO BENIN GABON THE GAMBIA GHANA COTE D'IVOIRE KENYA LESOTHO LIBERIA LIBYA MADAGASCAR MALAWI MALI MAURITANIA MOROCCO NIGERIA ZIMBABWE REUNION ISLAND RWANDA SENEGAL SIERRA LEONE ROTUMA REPUBLIC OF SOUTH AFRICA NAMIBIA SUDAN SWAZILAND TANZANIA TUNISIA EGYPT BURKINA FASO ZAMBIA TOGO WALVIS BAY (DELETED) CONWAY REEF BANABA ISLAND YEMEN PENGUIN ISLANDS (DELETED) CROATIA SLOVENIA BOSNIA-HERZEGOVINA MACEDONIA CZECH REPUBLIC SLOVAK REPUBLIC PRATAS ISLAND SCARBOROUGH REEF TEMOTU PROVINCE AUSTRAL ISLAND MARQUESAS ISLAND PALESTINE TIMOR - LESTE CHESTERFIELD IS. DUCIE ISLAND MONTENEGRO SWAINS ISLAND SAINT BARTHELEMY CURACAO SINT MAARTEN SABA & ST EUSTATIUS BONAIRE REPUBLIC OF SOUTH SUDAN Australian Capital Territory New South Wales Victoria Queensland South Australia Western Australia Tasmania Northern Territory Alberta British Columbia Manitoba New Brunswick Newfoundland Northwest Territories Nova Scotia Nunavut Ontario Prince Edward Island Quebec Saskatchewan Yukon Territory Anhui Beijing Chongqing Fujian Guangdong Gansu Guangxi Guizhou Henan Hubei Hebei Hainan Heilongjiang Hunan Jilin Jiangsu Jiangxi Liaoning Nei Mongol Ningxia Qinghai Sichuan Shandong Shanghai Shaanxi Shanxi Tianjin Xinjiang Xizang Yunnan Zhejiang Africa Asia Antarctica Europe North America Oceania South America KA Kaliningrad AB Aginsky Buryatsky Autonomous Okrug AL Altaysky Kray AM Amursk BA Bashkortostan BU Republic of Buryatia CB Chelyabinsk CK Chukotka Autonomous Okrug CT Zabaykalsky (Trans-Baikal) Krai EA Yevreyskaya Autonomous Oblast EW Evenkiysky Autonomous Okrug GA Gorny Altay HA Republic of Khakassia HK Khabarovsk HM Khanty-Mansyisky Autonomous Okrug IR Irkutsk JN Yamalo-Nenetsky Autonomous Okrug KE Kemerovo KJ Koryaksky Autonomous Okrug KK Krasnoyarsk KN Kurgan KT Kamchatka Krai MG Magadan NS Novosibirsk OB Orenburg OM Omsk PK Primorsk SL Sakhalin SV Sverdlovsk TM Taymyr Autonomous Okrug TN Tyumen TO Tomsk TU Republic of Tuva UO Ust-Ordynsky Autonomous Okrug YA Republic of Yakutia LO Leningrad region AD Republic of Adygeya AO Astrakhan AR Arkhangelsk BO Belgorod BR Bryansk CC Republic Chechnya CU Republic of Chuvashia DA Republic of Daghestan IN Republic of Ingushetia IV Ivanovo JA Yaroslavl KB Republic of Kabardino-Balkaria KC Republic of Karachaevo-Cherkessia KG Kaluga KI Kirov KL Republic of Karelia KM Republic of Kalmykia KO Komi KP Komi-Permyatsky Autonomous Okrug KR Krasnodar KS Kostroma KU Kursk LO Leningrad region LP Lipetsk MA Moscow MD Republic of Mordovia MO Moscow region MR Republic of Marij-El MU Murmansk NN Nizhny Novgorod NO Nenetsky Autonomous Okrug NV Novgorod OR Orel PE Penza PM Perm Krai PS Pskov RA Ryazan RO Rostov SA Saratov SM Smolensk SO Republic of Northern Ossetia SP St. Petersburg SR Samara ST Stavropol TA Republic of Tataria TB Tambov TL Tula TV Tver UD Republic of Udmurtia UL Ul'anovsk VG Volgograd VL Vladimir VO Vologda VR Voronezh AR Arkhangelsk Hawaii Alabama Arizona Arkansas California Colorado Connecticut Delaware District of Columbia Florida Georgia Idaho Illinois Indiana Iowa Kansas Kentucky Louisiana Maine Maryland Massachusetts Michigan Minnesota Mississippi Missouri Montana Nebraska Nevada New Hampshire New Jersey New Mexico New York North Carolina North Dakota Ohio Oklahoma Oregon Pennsylvania Rhode Island South Carolina South Dakota Tennessee Texas Utah Vermont Virginia Washington West Virginia Wisconsin Wyoming Alaska CALL DXCC GRIDSQUARE ITUZ CQZ IOTA ZERR US_STATE US_COUNTY ZERR US_STATE US_COUNTY ZERR CA_PROVINCE ZERR RU_OBLAST ZERR RU_OBLAST ZERR US_STATE US_COUNTY ZERR RU_OBLAST ZERR RU_OBLAST ZERR RU_OBLAST ZERR CN_PROVINCE ZERR AU_STATE ZERR AM AMTOR ATV CHIP CLOVER CONTESTI CW DATA DOMINO FAX FM FSK31 FSK441 GTOR HELL HFSK IMAGE ISCAT JT4 JT65 JT6M JT9 MFSK16 MFSK8 MINIRTTY MT63 OLIVIA OPERA PACKET PACTOR PAX PHONE PSK10 PSK125 PSK2K PSK31 PSK63 PSK63F PSKAM PSKFEC31 Q15 ROS RTTY RTTYM SSB SSTV THOR THROB VOI WINMOR WSPR Aurora-E Aurora Back scatter EchoLink Earth-Moon-Earth Sporadic E F2 Reflection Field Aligned Irregularities Ionoscatter IRLP Meteor scatter Rain scatter Satellite Trans-equatorial Tropospheric ducting lotw-logs@arrl.org Logbook of the World https://www.arrl.org/lotw/ AMSAT-OSCAR 10 AMSAT-OSCAR 13 AMSAT-OSCAR 16 OSCAR 21/RS-14 AMRAD-OSCAR 27 AMSAT-OSCAR 3 AMSAT-OSCAR 4 AMSAT-OSCAR 40 AMSAT-OSCAR 51 AMSAT-OSCAR 6 AMSAT-OSCAR 7 AMSAT-OSCAR 8 ARISS OSCAR 24 Delfi OSCAR-64 Fuji-OSCAR 12 Fuji-OSCAR 20 Fuji-OSCAR 29 Hope Oscar 68 Lusat-OSCAR 19 Navy-OSCAR 44 Radio Sputnik 1 Radio Sputnik 10 Radio Sputnik 11 Radio Sputnik 12 Radio Sputnik 13 Radio Sputnik 15 Radio Sputnik 2 Radio Sputnik 5 Radio Sputnik 6 Radio Sputnik 7 Radio Sputnik 8 Sunsat-OSCAR 35 Saudi-OSCAR 41 Saudi-OSCAR 50 Sumbandila Oscar 67 UOSAT-OSCAR 14 VUsat-OSCAR 52 tqsl-2.0/src/cabrillo.h0000664000076400007640000000746112231073120015074 0ustar rmurphyrmurphy/*************************************************************************** cabrillo.h - description ------------------- begin : Thu Dec 5 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __CABRILLO_H #define __CABRILLO_H #include "tqsllib.h" #undef CLIENT_STATIC #ifndef LOTW_SERVER #define CLIENT_STATIC static ///< Static linkage #else #define CLIENT_STATIC #endif /*! \file */ /** \defgroup Cabrillo Cabrillo API * * These functions and data structures provide a means of parsing a Cabrillo * file into its component fields. * * For convenience, the returned fields are identified using field names * from the \link ADIF ADIF \endlink specification. */ /** @{ */ #define TQSL_CABRILLO_MAX_FIELDS 12 ///< Max field count #define TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX 64 ///< Max field name length #define TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX 40 ///< Max field value length /// Cabrillo status values typedef enum { TQSL_CABRILLO_NO_ERROR, TQSL_CABRILLO_EOF, TQSL_CABRILLO_NO_START_RECORD, TQSL_CABRILLO_NO_CONTEST_RECORD, TQSL_CABRILLO_UNKNOWN_CONTEST, TQSL_CABRILLO_BAD_FIELD_DATA, TQSL_CABRILLO_EOR, } TQSL_CABRILLO_ERROR_TYPE; ///< Error type /*! \enum TQSL_CABRILLO_FREQ_TYPE * Frequency type: HF, VHF, or UNKNOWN */ typedef enum { TQSL_CABRILLO_HF, TQSL_CABRILLO_VHF, TQSL_CABRILLO_UNKNOWN, } TQSL_CABRILLO_FREQ_TYPE; // Minimum field number for callsign and default field number // For VHF, default should be 7. #define TQSL_MIN_CABRILLO_MAP_FIELD 5 ///< First possible call-worked field #define TQSL_DEF_CABRILLO_MAP_FIELD 8 ///< Default call-worked field /** Cabrillo field data: * * \li \c name - ADIF field name * \li \c value - Field content */ typedef struct { ///< Cabrillo field char name[TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX +1]; ///< Field name char value[TQSL_CABRILLO_FIELD_VALUE_LENGTH_MAX +1]; ///< Field value } tqsl_cabrilloField; typedef void * tQSL_Cabrillo; ///< Opaque cabrillo log type #ifdef __cplusplus extern "C" { #endif /** Get the Cabrillo error message that corresponds to a particular error value */ DLLEXPORT const char* CALLCONVENTION tqsl_cabrilloGetError(TQSL_CABRILLO_ERROR_TYPE err); /** Initialize a Cabrillo file for reading */ DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo(tQSL_Cabrillo *cabp, const char *filename); /** Get the Contest name as specified in the Cabrillo CONTEST line */ DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest(tQSL_Cabrillo cab, char *buf, int bufsiz); /** Get the Frequency type (HF or VHF) as determined by the contest */ DLLEXPORT int CALLCONVENTION tqsl_getCabrilloFreqType(tQSL_Cabrillo cab, TQSL_CABRILLO_FREQ_TYPE *type); /** Get the current line number (starting from 1) of the input file */ DLLEXPORT int CALLCONVENTION tqsl_getCabrilloLine(tQSL_Cabrillo cab, int *lineno); /** Get the text of the current Cabrillo record */ DLLEXPORT const char* CALLCONVENTION tqsl_getCabrilloRecordText(tQSL_Cabrillo cab); /** Get the next field of the Cabrillo record * * \c err is set to \c TQSL_CABRILLO_NO_ERROR or \c TQSL_CABRILLO_EOR (end-of-record) * if \c field was populated with data. If \c err == \c TQSL_CABRILLO_EOR, this * is the last field of the record. * * \c err == \c TQSL_CABRILLO_EOF when there is no more data available. */ DLLEXPORT int CALLCONVENTION tqsl_getCabrilloField(tQSL_Cabrillo cab, tqsl_cabrilloField *field, TQSL_CABRILLO_ERROR_TYPE *err); /** Finish reading a Cabrillo file and release its resources */ DLLEXPORT int CALLCONVENTION tqsl_endCabrillo(tQSL_Cabrillo *cabp); #ifdef __cplusplus } #endif /** @} */ #endif // __CABRILLO_H tqsl-2.0/src/cabrillo.cpp0000664000076400007640000004556112231073120015432 0ustar rmurphyrmurphy/*************************************************************************** cabrillo.cpp - description ------------------- begin : Thu Dec 5 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #define TQSLLIB_DEF #include "tqsllib.h" #include "tqslerrno.h" #include #include #include #include #include #include "winstrdefs.h" #define TQSL_CABRILLO_MAX_RECORD_LENGTH 120 DLLEXPORTDATA TQSL_CABRILLO_ERROR_TYPE tQSL_Cabrillo_Error; static char errmsgbuf[256]; static char errmsgdata[128]; struct TQSL_CABRILLO; static int freq_to_band(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp); static int freq_to_mhz(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp); static int mode_xlat(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp); static int time_fixer(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp); struct cabrillo_field_def { const char *name; int loc; int (*process)(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp); }; static cabrillo_field_def cabrillo_dummy[] = { { "CALL", 6, 0 }, { "BAND", 0, freq_to_band }, { "MODE", 1, mode_xlat }, { "QSO_DATE", 2, 0 }, { "TIME_ON", 3, time_fixer }, { "FREQ", 0, freq_to_mhz }, { "MYCALL", 4, 0 }, }; /* // Cabrillo QSO template specs // Call in field 6 static cabrillo_field_def cabrillo_c6[] = { { "BAND", 0, freq_to_band }, { "MODE", 1, mode_xlat }, { "QSO_DATE", 2, 0 }, { "TIME_ON", 3, time_fixer }, { "CALL", 6, 0 }, { "FREQ", 0, 0 }, { "MYCALL", 4, 0 }, }; // Call in field 7 static cabrillo_field_def cabrillo_c7[] = { { "BAND", 0, freq_to_band }, { "MODE", 1, mode_xlat }, { "QSO_DATE", 2, 0 }, { "TIME_ON", 3, time_fixer }, { "CALL", 7, 0 }, { "FREQ", 0, 0 }, { "MYCALL", 4, 0 }, }; // Call in field 8 static cabrillo_field_def cabrillo_c8[] = { { "BAND", 0, freq_to_band }, { "MODE", 1, mode_xlat }, { "QSO_DATE", 2, 0 }, { "TIME_ON", 3, time_fixer }, { "CALL", 8, 0 }, { "FREQ", 0, 0 }, { "MYCALL", 4, 0 }, }; // Call in field 9 static cabrillo_field_def cabrillo_c9[] = { { "BAND", 0, freq_to_band }, { "MODE", 1, mode_xlat }, { "QSO_DATE", 2, 0 }, { "TIME_ON", 3, time_fixer }, { "CALL", 9, 0 }, { "FREQ", 0, 0 }, { "MYCALL", 4, 0 }, }; */ struct cabrillo_contest { char *contest_name; TQSL_CABRILLO_FREQ_TYPE type; cabrillo_field_def *fields; int nfields; }; struct TQSL_CABRILLO { int sentinel; FILE *fp; char *filename; cabrillo_contest *contest; int field_idx; char rec[TQSL_CABRILLO_MAX_RECORD_LENGTH+1]; char *datap; int line_no; char *fields[TQSL_CABRILLO_MAX_FIELDS]; }; #define CAST_TQSL_CABRILLO(p) ((struct TQSL_CABRILLO *)p) static TQSL_CABRILLO * check_cabrillo(tQSL_Cabrillo cabp) { if (tqsl_init()) return 0; if (cabp == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 0; } if (CAST_TQSL_CABRILLO(cabp)->sentinel != 0x2449) return 0; return CAST_TQSL_CABRILLO(cabp); } static char * tqsl_parse_cabrillo_record(char *rec) { char *cp = strchr(rec, ':'); if (!cp) return 0; *cp++ = 0; if (strlen(rec) > TQSL_CABRILLO_FIELD_NAME_LENGTH_MAX) return 0; while (isspace(*cp)) cp++; char *sp; if ((sp = strchr(cp, '\r')) != 0) *sp = '\0'; if ((sp = strchr(cp, '\n')) != 0) *sp = '\0'; for (sp = cp + strlen(cp); sp != cp; ) { sp--; if (isspace(*sp)) *sp = '\0'; else break; } for (sp = rec; *sp; sp++) *sp = toupper(*sp); return cp; } static int freq_to_band(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp) { if (!strcasecmp(fp->value, "light")) { strcpy(fp->value, "SUBMM"); return 0; } int freq = strtol(fp->value, NULL, 10); const char *band = 0; if (freq < 30) { // Handle known CT misbehavior if (!strcmp(fp->value, "7")) freq = 7000; if (!strcmp(fp->value, "14")) freq = 14000; if (!strcmp(fp->value, "21")) freq = 21000; if (!strcmp(fp->value, "28")) freq = 28000; } if (freq >= 1800 && freq <= 2000) band = "160M"; else if (freq >= 3500 && freq <= 4000) band = "80M"; else if (freq >= 7000 && freq <= 7300) band = "40M"; else if (freq >= 10100 && freq <= 10150) band = "30M"; else if (freq >= 14000 && freq <= 14350) band = "20M"; else if (freq >= 18068 && freq <= 18168) band = "17M"; else if (freq >= 21000 && freq <= 21450) band = "15M"; else if (freq >= 24890 && freq <= 24990) band = "12M"; else if (freq >= 28000 && freq <= 29700) band = "10M"; else if (freq == 50) band = "6M"; else if (freq == 70) band = "4M"; else if (freq == 144) band = "2M"; else if (freq == 222) band = "1.25M"; else if (freq == 432) band = "70CM"; else if (freq == 902 || freq == 903) band = "33CM"; else if (!strcasecmp(fp->value, "1.2G") || !strcasecmp(fp->value, "1.2")) band = "23CM"; else if (!strcasecmp(fp->value, "2.3G") || !strcasecmp(fp->value, "2.3")) band = "13CM"; else if (!strcasecmp(fp->value, "3.4G") || !strcasecmp(fp->value, "3.4")) band = "9CM"; else if (!strcasecmp(fp->value, "5.7G") || !strcasecmp(fp->value, "5.7")) band = "6CM"; else if (!strcasecmp(fp->value, "10G") || !strcasecmp(fp->value, "10")) band = "3CM"; else if (!strcasecmp(fp->value, "24G") || !strcasecmp(fp->value, "24")) band = "1.25CM"; else if (!strcasecmp(fp->value, "47G") || !strcasecmp(fp->value, "47")) band = "6MM"; else if (!strcasecmp(fp->value, "75G") || !strcasecmp(fp->value, "75") || !strcasecmp(fp->value, "76G") || !strcasecmp(fp->value, "76")) band = "4MM"; else if (!strcasecmp(fp->value, "119G") || !strcasecmp(fp->value, "119")) band = "2.5MM"; else if (!strcasecmp(fp->value, "142G") || !strcasecmp(fp->value, "142")) band = "2MM"; else if (!strcasecmp(fp->value, "241G") || !strcasecmp(fp->value, "241")|| !strcasecmp(fp->value, "242G") || !strcasecmp(fp->value, "242")) band = "1MM"; else if (!strcasecmp(fp->value, "300G") || !strcasecmp(fp->value, "300")) band = "SUBMM"; if (band && cab->contest->type == TQSL_CABRILLO_UNKNOWN) { if (freq < 1000) cab->contest->type = TQSL_CABRILLO_VHF; else cab->contest->type = TQSL_CABRILLO_HF; } if (band == 0) return 1; strcpy(fp->value, band); return 0; } static int freq_to_mhz(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp) { if (!strcasecmp(fp->value, "light")) { return 0; } int freq = strtol(fp->value, NULL, 10); double freqmhz = freq; freqmhz /= 1000; if (freq < 30) { // Handle known CT misbehavior if (freq == 7) freqmhz = 7.0; if (freq == 14) freqmhz = 14.0; if (freq == 21) freqmhz = 21.0; if (freq == 28) freqmhz = 28.0; } // VHF+ if (!strcasecmp(fp->value, "50")) freqmhz = 50.0; else if (!strcasecmp(fp->value, "70")) freqmhz = 70.0; else if (!strcasecmp(fp->value, "144")) freqmhz = 144.0; else if (!strcasecmp(fp->value, "222")) freqmhz = 222.0; else if (!strcasecmp(fp->value, "432")) freqmhz = 432.0; else if (!strcasecmp(fp->value, "902") || !strcasecmp(fp->value, "903")) freqmhz = 902.0; else if (!strcasecmp(fp->value, "1.2G") || !strcasecmp(fp->value, "1.2")) freqmhz = 1240.0; else if (!strcasecmp(fp->value, "2.3G") || !strcasecmp(fp->value, "2.3")) freqmhz = 2300.0; else if (!strcasecmp(fp->value, "3.4G") || !strcasecmp(fp->value, "3.4")) freqmhz = 3300.0; else if (!strcasecmp(fp->value, "5.7G") || !strcasecmp(fp->value, "5.7")) freqmhz = 5650.0; else if (!strcasecmp(fp->value, "10G") || !strcasecmp(fp->value, "10")) freqmhz = 10000.0; else if (!strcasecmp(fp->value, "24G") || !strcasecmp(fp->value, "24")) freqmhz = 24000.0; else if (!strcasecmp(fp->value, "47G") || !strcasecmp(fp->value, "47")) freqmhz = 47000.0; else if (!strcasecmp(fp->value, "75G") || !strcasecmp(fp->value, "75") || !strcasecmp(fp->value, "76G") || !strcasecmp(fp->value, "76")) freqmhz = 75500.0; else if (!strcasecmp(fp->value, "119G") || !strcasecmp(fp->value, "119")) freqmhz = 119980.0; else if (!strcasecmp(fp->value, "142G") || !strcasecmp(fp->value, "142")) freqmhz = 142000.0; else if (!strcasecmp(fp->value, "241G") || !strcasecmp(fp->value, "241") || !strcasecmp(fp->value, "242G") || !strcasecmp(fp->value, "242")) freqmhz = 241000.0; else if (!strcasecmp(fp->value, "300G") || !strcasecmp(fp->value, "300")) freqmhz = 300000.0; if (freqmhz > 0 && cab->contest->type == TQSL_CABRILLO_UNKNOWN) { if (freqmhz >= 50.0) // VHF cab->contest->type = TQSL_CABRILLO_VHF; else cab->contest->type = TQSL_CABRILLO_HF; } char strfreq[100]; snprintf(strfreq, sizeof strfreq, "%#f", freqmhz); strcpy(fp->value, strfreq); return 0; } static int mode_xlat(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp) { static struct { const char *cmode; const char *gmode; } modes[] = { {"CW", "CW"}, {"PH", "SSB"}, {"FM", "FM"}, {"RY", "RTTY"} }; for (int i = 0; i < int(sizeof modes / sizeof modes[0]); i++) { if (!strcasecmp(fp->value, modes[i].cmode)) { strcpy(fp->value, modes[i].gmode); return 0; } } return 1; } static int time_fixer(TQSL_CABRILLO *cab, tqsl_cabrilloField *fp) { if (strlen(fp->value) == 0) return 0; char *cp; for (cp = fp->value; *cp; cp++) if (!isdigit(*cp)) break; if (*cp) return 1; snprintf(fp->value, sizeof fp->value, "%04d", (int) strtol(fp->value, NULL, 10)); return 0; } static void tqsl_free_cabrillo_contest(struct cabrillo_contest *c) { if (c->contest_name) free(c->contest_name); if (c->fields) free(c->fields); free(c); } static struct cabrillo_contest * tqsl_new_cabrillo_contest(const char *contest_name, int call_field, int contest_type) { cabrillo_contest *c = (cabrillo_contest *)calloc(1, sizeof (struct cabrillo_contest)); if (c == NULL) return NULL; if ((c->contest_name = (char *)malloc(strlen(contest_name)+1)) == NULL) { tqsl_free_cabrillo_contest(c); return NULL; } strcpy(c->contest_name, contest_name); c->type = (TQSL_CABRILLO_FREQ_TYPE)contest_type; if ((c->fields = (struct cabrillo_field_def *)calloc(1, sizeof cabrillo_dummy)) == NULL) { tqsl_free_cabrillo_contest(c); return NULL; } memcpy(c->fields, cabrillo_dummy, sizeof cabrillo_dummy); c->fields[0].loc = call_field-1; c->nfields = sizeof cabrillo_dummy / sizeof cabrillo_dummy[0]; return c; } static void tqsl_free_cab(struct TQSL_CABRILLO *cab) { if (!cab || cab->sentinel != 0x2449) return; cab->sentinel = 0; if (cab->filename) free(cab->filename); if (cab->fp) fclose(cab->fp); if (cab->contest) tqsl_free_cabrillo_contest(cab->contest); free(cab); } DLLEXPORT int CALLCONVENTION tqsl_beginCabrillo(tQSL_Cabrillo *cabp, const char *filename) { TQSL_CABRILLO_ERROR_TYPE terrno; if (filename == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } struct TQSL_CABRILLO *cab; cab = (struct TQSL_CABRILLO *)calloc(1, sizeof (struct TQSL_CABRILLO)); if (cab == NULL) { tQSL_Error = TQSL_ALLOC_ERROR; goto err; } cab->sentinel = 0x2449; cab->field_idx = -1; if ((cab->fp = fopen(filename, "r")) == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto err; } char *cp; terrno = TQSL_CABRILLO_NO_START_RECORD; while ((cp = fgets(cab->rec, sizeof cab->rec, cab->fp)) != 0) { cab->line_no++; if (tqsl_parse_cabrillo_record(cab->rec) != 0 && !strcmp(cab->rec, "START-OF-LOG")) break; } if (cp != 0) { terrno = TQSL_CABRILLO_NO_CONTEST_RECORD; while ((cp = fgets(cab->rec, sizeof cab->rec, cab->fp)) != 0) { cab->line_no++; char *vp; if ((vp = tqsl_parse_cabrillo_record(cab->rec)) != 0 && !strcmp(cab->rec, "CONTEST") && strtok(vp, " \t\r\n") != 0) { terrno = TQSL_CABRILLO_UNKNOWN_CONTEST; int callfield, contest_type; if (tqsl_getCabrilloMapEntry(vp, &callfield, &contest_type)) { // No defined contest with this name. // callfield comes back as 0 contest_type = TQSL_CABRILLO_UNKNOWN; } cab->contest = tqsl_new_cabrillo_contest(vp, callfield, contest_type); if (cab->contest == 0) { strncpy(errmsgdata, vp, sizeof errmsgdata); cp = 0; } break; } } } if (cp == 0) { if (ferror(cab->fp)) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto err; } tQSL_Cabrillo_Error = terrno; tQSL_Error = TQSL_CABRILLO_ERROR; goto err; } if ((cab->filename = (char *)malloc(strlen(filename)+1)) == NULL) { tQSL_Error = TQSL_ALLOC_ERROR; goto err; } strcpy(cab->filename, filename); *((struct TQSL_CABRILLO **)cabp) = cab; return 0; err: strncpy(tQSL_ErrorFile, filename, sizeof tQSL_ErrorFile); tQSL_ErrorFile[sizeof tQSL_ErrorFile-1] = 0; tqsl_free_cab(cab); return 1; } DLLEXPORT int CALLCONVENTION tqsl_endCabrillo(tQSL_Cabrillo *cabp) { TQSL_CABRILLO *cab; if (cabp == 0) return 0; cab = CAST_TQSL_CABRILLO(*cabp); if (!cab || cab->sentinel != 0x2449) return 0; tqsl_free_cab(cab); *cabp = 0; return 0; } DLLEXPORT const char* CALLCONVENTION tqsl_cabrilloGetError(TQSL_CABRILLO_ERROR_TYPE err) { const char *msg = 0; switch (err) { case TQSL_CABRILLO_NO_ERROR: msg = "Cabrillo success"; break; case TQSL_CABRILLO_EOF: msg = "Cabrillo end-of-file"; break; case TQSL_CABRILLO_EOR: msg = "Cabrillo end-of-record"; break; case TQSL_CABRILLO_NO_START_RECORD: msg = "Cabrillo missing START-OF-LOG record"; break; case TQSL_CABRILLO_NO_CONTEST_RECORD: msg = "Cabrillo missing CONTEST record"; break; case TQSL_CABRILLO_UNKNOWN_CONTEST: snprintf(errmsgbuf, sizeof errmsgbuf, "Cabrillo unknown CONTEST: %s", errmsgdata); msg = errmsgbuf; break; case TQSL_CABRILLO_BAD_FIELD_DATA: snprintf(errmsgbuf, sizeof errmsgbuf, "Cabrillo field data error in %s field", errmsgdata); msg = errmsgbuf; break; } if (!msg) { snprintf(errmsgbuf, sizeof errmsgbuf, "Cabrillo unknown error: %d", err); if (errmsgdata[0] != '\0') snprintf(errmsgbuf + strlen(errmsgbuf), sizeof errmsgbuf - strlen(errmsgbuf), " (%s)", errmsgdata); msg = errmsgbuf; } errmsgdata[0] = '\0'; return msg; } DLLEXPORT int CALLCONVENTION tqsl_getCabrilloField(tQSL_Cabrillo cabp, tqsl_cabrilloField *field, TQSL_CABRILLO_ERROR_TYPE *error) { TQSL_CABRILLO *cab; cabrillo_field_def *fp; const char *fielddat; if ((cab = check_cabrillo(cabp)) == 0) return 1; if (field == 0 || error == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (cab->datap == 0 || cab->field_idx < 0 || cab->field_idx >= cab->contest->nfields) { char *cp; while ((cp = fgets(cab->rec, sizeof cab->rec, cab->fp)) != 0) { cab->line_no++; cab->datap = tqsl_parse_cabrillo_record(cab->rec); if (cab->datap != 0) { if (!strcasecmp(cab->rec, "QSO")) { cab->field_idx = 0; char *fieldp = strtok(cab->datap, " \t\r\n"); memset(cab->fields, 0, sizeof cab->fields); for (int i = 0; fieldp && i < int(sizeof cab->fields / sizeof cab->fields[0]); i++) { cab->fields[i] = fieldp; fieldp = strtok(0, " \t\r\n"); } break; } else if (!strcasecmp(cab->rec, "END-OF-LOG")) { *error = TQSL_CABRILLO_EOF; return 0; } } } if (cp == 0) { if (ferror(cab->fp)) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; goto err; } else { *error = TQSL_CABRILLO_EOF; return 0; } } } // Record data is okay and field index is valid. fp = cab->contest->fields + cab->field_idx; strncpy(field->name, fp->name, sizeof field->name); if (fp->loc < 0) { // New contest for (int i = 6; i < TQSL_CABRILLO_MAX_FIELDS && cab->fields[i]; i++) { char *p = cab->fields[i]; // Simple parse: a callsign is at least 3 chars long // and has at least one digit and at least one letter // Nothing but alphnumeric and '/' allowed. // First, eliminate grid squares if (strlen(p) == 4) { if (isalpha(p[0]) && isalpha(p[1]) && isdigit(p[2]) && isdigit(p[3])) continue; } int nlet = 0, ndig = 0; for (; *p; p++) { if (isdigit(*p)) { ndig++; } else if (isalpha(*p)) { nlet++; } else if (*p != '/') { ndig = 0; nlet = 0; break; } } if (nlet > 0 && ndig > 0 && nlet+ndig > 3) { // OK, looks like a callsign. Is it possibly a gridsquare? if (strlen(p) == 6) { if ((isalpha(p[0]) && toupper(p[0]) < 'S') && (isalpha(p[1]) && toupper(p[1]) < 'S') && (isdigit(p[2]) && isdigit(p[3])) && (isalpha(p[4]) && toupper(p[4]) < 'Y') && (isalpha(p[5]) && toupper(p[5]) < 'Y')) continue; // Gridsquare. Don't use it. } if (fp->loc < 0) { // No callsign candidate yet fp->loc = i; } else { tQSL_Cabrillo_Error = TQSL_CABRILLO_UNKNOWN_CONTEST; tQSL_Error = TQSL_CABRILLO_ERROR; snprintf(errmsgdata, sizeof errmsgdata, "%s\nUnable to find a unique call-worked field.\n" "Please define a custom Cabrillo entry for this contest.\n", cab->contest->contest_name); goto err; } } } if (fp->loc < 0) { // Still can't find a call. Have to bail. tQSL_Cabrillo_Error = TQSL_CABRILLO_UNKNOWN_CONTEST; tQSL_Error = TQSL_CABRILLO_ERROR; snprintf(errmsgdata, sizeof errmsgdata, "%s\nUnable to find a valid call-worked field.\n" "Please define a custom Cabrillo entry for this contest.\n", cab->contest->contest_name); goto err; } } fielddat = cab->fields[fp->loc]; if (fielddat == 0) { tQSL_Cabrillo_Error = TQSL_CABRILLO_BAD_FIELD_DATA; tQSL_Error = TQSL_CABRILLO_ERROR; strncpy(errmsgdata, field->name, sizeof errmsgdata); goto err; } strncpy(field->value, fielddat, sizeof field->value); if (fp->process && fp->process(cab, field)) { tQSL_Cabrillo_Error = TQSL_CABRILLO_BAD_FIELD_DATA; tQSL_Error = TQSL_CABRILLO_ERROR; strncpy(errmsgdata, field->name, sizeof errmsgdata); goto err; } cab->field_idx++; if (cab->field_idx >= cab->contest->nfields) *error = TQSL_CABRILLO_EOR; else *error = TQSL_CABRILLO_NO_ERROR; return 0; err: strncpy(tQSL_ErrorFile, cab->filename, sizeof tQSL_ErrorFile); tQSL_ErrorFile[sizeof tQSL_ErrorFile-1] = 0; return 1; } DLLEXPORT int CALLCONVENTION tqsl_getCabrilloContest(tQSL_Cabrillo cabp, char *buf, int bufsiz) { TQSL_CABRILLO *cab; if ((cab = check_cabrillo(cabp)) == 0) return 1; if (buf == 0 || bufsiz <= 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } if (bufsiz < (int)strlen(cab->contest->contest_name)+1) { tQSL_Error = TQSL_BUFFER_ERROR; return 1; } strcpy(buf, cab->contest->contest_name); return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCabrilloFreqType(tQSL_Cabrillo cabp, TQSL_CABRILLO_FREQ_TYPE *type) { TQSL_CABRILLO *cab; if ((cab = check_cabrillo(cabp)) == 0) return 1; if (type == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *type = cab->contest->type; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getCabrilloLine(tQSL_Cabrillo cabp, int *lineno) { TQSL_CABRILLO *cab; if ((cab = check_cabrillo(cabp)) == 0) return 1; if (lineno == 0) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *lineno = cab->line_no; return 0; } DLLEXPORT const char* CALLCONVENTION tqsl_getCabrilloRecordText(tQSL_Cabrillo cabp) { TQSL_CABRILLO *cab; if ((cab = check_cabrillo(cabp)) == 0) return 0; return cab->rec; } tqsl-2.0/src/adif.h0000664000076400007640000001160012231073120014176 0ustar rmurphyrmurphy/*************************************************************************** adif.h - description ------------------- begin : Wed May 15 2002 copyright : (C) 2002 by ARRL email : MSimcik@localhost.localdomain revision : $Id$ ***************************************************************************/ #ifndef __ADIF_H #define __ADIF_H #include "tqsllib.h" #include #include /*! \file */ /** \defgroup ADIF ADIF API * * These functions and data structures provide a means of parsing an ADIF * file into its component fields, along with range-checking the field contents. */ /** @{ */ #define TQSL_ADIF_FIELD_NAME_LENGTH_MAX 64 ///< Max length of ADIF field #define TQSL_ADIF_FIELD_SIZE_LENGTH_MAX 10 ///< Max length of field name #define TQSL_ADIF_FIELD_TYPE_LENGTH_MAX 1 ///< Max length of field type /*! \enum TQSL_ADIF_BOOLEAN * Boolean type - TRUE/FALSE */ #ifndef TQSL_ADIF_BOOLEAN typedef enum { TQSL_FALSE, TQSL_TRUE } TQSL_ADIF_BOOLEAN; #endif typedef void * tQSL_ADIF; ///< Opaque ADIF type /// Specifies the type of range limits to apply to a field typedef enum { TQSL_ADIF_RANGE_TYPE_NONE, TQSL_ADIF_RANGE_TYPE_MINMAX, TQSL_ADIF_RANGE_TYPE_ENUMERATION } TQSL_ADIF_RANGE_TYPE; /// Response values returned from tqsl_getADIFField() typedef enum { TQSL_ADIF_GET_FIELD_SUCCESS, TQSL_ADIF_GET_FIELD_NO_NAME_MATCH, TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH, TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH, TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH, TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION, TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW, TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW, TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW, TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW, TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE, TQSL_ADIF_GET_FIELD_EOF } TQSL_ADIF_GET_FIELD_ERROR; /** An ADIF field definition */ typedef struct { char name[TQSL_ADIF_FIELD_NAME_LENGTH_MAX + 1]; ///< Field name char type[TQSL_ADIF_FIELD_TYPE_LENGTH_MAX + 1]; ///< Field type TQSL_ADIF_RANGE_TYPE rangeType; ///< Range type unsigned int max_length; ///< Max length long signed min_value; ///< Min value long signed max_value; ///< Max value const char **enumStrings; ///< Enumerated values void *userPointer; ///< user poitner } tqsl_adifFieldDefinitions; /** Field returned from parsing */ typedef struct { char name[TQSL_ADIF_FIELD_NAME_LENGTH_MAX + 1]; ///< Field name char size[TQSL_ADIF_FIELD_SIZE_LENGTH_MAX + 1]; ///< Size char type[TQSL_ADIF_FIELD_TYPE_LENGTH_MAX + 1]; ///< Type unsigned char *data; ///< data unsigned int adifNameIndex; ///< Name index void *userPointer; ///< User pointer } tqsl_adifFieldResults; /* function prototypes */ #ifdef __cplusplus extern "C" { #endif /** Get the ADIF error message that corresponds to a particular error value */ DLLEXPORT const char* CALLCONVENTION tqsl_adifGetError( TQSL_ADIF_GET_FIELD_ERROR status ); /** Initialize an ADIF file for reading */ DLLEXPORT int CALLCONVENTION tqsl_beginADIF(tQSL_ADIF *adifp, const char *filename); /** Get the next field from an ADIF file * * \li \c adif - ADIF handle returned from tqsl_beginADIF() * \li \c field - pointer to struct that contains the field data and description * \li \c status - pointer to returned status variable * \li \c adifFields - pointer to an array of field-definition structures. The last * item in the array should have an empty string as its \c name member. * \li \c typesDefined - pointer to an array of char pointers that define the * allowed field-type strings. The last item in the array should point to * an empty string. * \li \c allocator - pointer to a function that returns a pointer to a memory * block of the specified size. This function will be called at most one * time during a call to tqsl_getADIFField. The returned pointer will then * be used to populate the \c data member of \c field. The caller is * responsible for freeing this memory, if needed. */ DLLEXPORT int CALLCONVENTION tqsl_getADIFField(tQSL_ADIF adif, tqsl_adifFieldResults *field, TQSL_ADIF_GET_FIELD_ERROR *status, const tqsl_adifFieldDefinitions *adifFields, const char * const *typesDefined, unsigned char *(*allocator)(size_t) ); /** Get the current line number (starting from 1) of the input file */ DLLEXPORT int CALLCONVENTION tqsl_getADIFLine(tQSL_ADIF adif, int *lineno); /** End and release an ADIF file */ DLLEXPORT int CALLCONVENTION tqsl_endADIF(tQSL_ADIF *adifp); /** Form an ADIF field string. * * N.B. On systems that distinguish text-mode files from binary-mode files, * notably Windows, the text should be written in binary mode. */ DLLEXPORT int CALLCONVENTION tqsl_adifMakeField(const char *fieldname, char type, const unsigned char *value, int len, unsigned char *buf, int buflen); #ifdef __cplusplus } #endif /** @} */ #endif /* __ADIF_H */ tqsl-2.0/src/adif.cpp0000664000076400007640000003412712231073120014542 0ustar rmurphyrmurphy/*************************************************************************** adif.c - description ------------------- begin : Wed May 15 2002 copyright : (C) 2002 by ARRL email : MSimcik@localhost.localdomain revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #define TQSLLIB_DEF #include #include #include #include #include #include "tqsllib.h" #include "tqslerrno.h" #include "winstrdefs.h" typedef enum { TQSL_ADIF_STATE_BEGIN, TQSL_ADIF_STATE_GET_NAME, TQSL_ADIF_STATE_GET_SIZE, TQSL_ADIF_STATE_GET_TYPE, TQSL_ADIF_STATE_GET_DATA, TQSL_ADIF_STATE_DONE } TQSL_ADIF_STATE; struct TQSL_ADIF { int sentinel; FILE *fp; char *filename; int line_no; }; #define CAST_TQSL_ADIF(p) ((struct TQSL_ADIF *)p) static TQSL_ADIF * check_adif(tQSL_ADIF adif) { if (tqsl_init()) return 0; if (adif == 0) return 0; if (CAST_TQSL_ADIF(adif)->sentinel != 0x3345) return 0; return CAST_TQSL_ADIF(adif); } static void free_adif(TQSL_ADIF *adif) { if (adif && adif->sentinel == 0x3345) { adif->sentinel = 0; if (adif->filename) free(adif->filename); if (adif->fp) fclose(adif->fp); free(adif); } } DLLEXPORT int CALLCONVENTION tqsl_beginADIF(tQSL_ADIF *adifp, const char *filename) { if (filename == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } struct TQSL_ADIF *adif; adif = (struct TQSL_ADIF *)calloc(1, sizeof (struct TQSL_ADIF)); if (adif == NULL) { tQSL_Error = TQSL_ALLOC_ERROR; goto err; } adif->sentinel = 0x3345; if ((adif->fp = fopen(filename, "rb")) == NULL) { tQSL_Error = TQSL_SYSTEM_ERROR; tQSL_Errno = errno; strncpy(tQSL_ErrorFile, filename, sizeof tQSL_ErrorFile); tQSL_ErrorFile[sizeof tQSL_ErrorFile-1] = 0; goto err; } if ((adif->filename = (char *)malloc(strlen(filename)+1)) == NULL) { tQSL_Error = TQSL_ALLOC_ERROR; goto err; } strcpy(adif->filename, filename); *((struct TQSL_ADIF **)adifp) = adif; return 0; err: free_adif(adif); return 1; } DLLEXPORT int CALLCONVENTION tqsl_endADIF(tQSL_ADIF *adifp) { TQSL_ADIF *adif; if (adifp == 0) return 0; adif = CAST_TQSL_ADIF(*adifp); free_adif(adif); *adifp = 0; return 0; } DLLEXPORT int CALLCONVENTION tqsl_getADIFLine(tQSL_ADIF adifp, int *lineno) { TQSL_ADIF *adif; if (!(adif = check_adif(adifp))) return 1; if (lineno == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *lineno = adif->line_no; return 0; } static void strCatChar( char *string, int character ) { while (*string) string++; *string++ = character; *string = '\0'; } DLLEXPORT const char* CALLCONVENTION tqsl_adifGetError( TQSL_ADIF_GET_FIELD_ERROR status ) { const char *result; switch( status ) { case TQSL_ADIF_GET_FIELD_SUCCESS: result = (char *) "ADIF success"; break; case TQSL_ADIF_GET_FIELD_NO_NAME_MATCH: result = (char *) "ADIF field no name match"; break; case TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH: result = (char *) "ADIF field no type match"; break; case TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH: result = (char *) "ADIF field no range match"; break; case TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH: result = (char *) "ADIF field no enumeration match"; break; case TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION: result = (char *) "ADIF field no result allocation"; break; case TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW: result = (char *) "ADIF field name length overflow"; break; case TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW: result = (char *) "ADIF field data length overflow"; break; case TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW: result = (char *) "ADIF field size overflow"; break; case TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW: result = (char *) "ADIF field type overflow"; break; case TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE: result = (char *) "ADIF erroneously executing default state"; break; case TQSL_ADIF_GET_FIELD_EOF: result = (char *) "ADIF reached End of File"; break; default: result = (char *) "ADIF unknown error"; break; } return( result ); }; static TQSL_ADIF_GET_FIELD_ERROR tqsl_adifGetField( tqsl_adifFieldResults *field, FILE *filehandle, const tqsl_adifFieldDefinitions *adifFields, const char * const *typesDefined, unsigned char *(*allocator)(size_t), int *line_no ) { TQSL_ADIF_GET_FIELD_ERROR status; TQSL_ADIF_STATE adifState; int currentCharacter; unsigned int iIndex; unsigned int dataLength; unsigned int dataIndex = 0; TQSL_ADIF_BOOLEAN recordData; signed long dataValue; /* get the next name value pair */ status = TQSL_ADIF_GET_FIELD_SUCCESS; adifState = TQSL_ADIF_STATE_BEGIN; /* assume that we do not wish to record this data */ recordData = TQSL_FALSE; /* clear the field buffers */ field->name[0] = '\0'; field->size[0] = '\0'; field->type[0] = '\0'; field->data = NULL; field->adifNameIndex = 0; field->userPointer = NULL; while( adifState != TQSL_ADIF_STATE_DONE ) { if( EOF != ( currentCharacter = fgetc( filehandle ) ) ) { if (*line_no == 0) *line_no = 1; if (currentCharacter == '\n') (*line_no)++; switch( adifState ) { case TQSL_ADIF_STATE_BEGIN: /* GET STARTED */ /* find the field opening "<", ignoring everything else */ if( '<' == currentCharacter ) { adifState = TQSL_ADIF_STATE_GET_NAME; } break; case TQSL_ADIF_STATE_GET_NAME: /* GET FIELD NAME */ /* add field name characters to buffer, until '>' or ':' found */ if( ( '>' == currentCharacter ) || ( ':' == currentCharacter ) ) { /* find if the name is a match to a LoTW supported field name */ status = TQSL_ADIF_GET_FIELD_NO_NAME_MATCH; adifState = TQSL_ADIF_STATE_GET_SIZE; for( iIndex = 0; ( TQSL_ADIF_GET_FIELD_NO_NAME_MATCH == status ) && ( 0 != adifFields[iIndex].name[0] ); iIndex++ ) { /* case insensitive compare */ if( 0 == strcasecmp( field->name, adifFields[iIndex].name ) ) { /* set name index */ field->adifNameIndex = iIndex; /* copy user pointer */ field->userPointer = adifFields[iIndex].userPointer; /* since we know the name, record the data */ recordData = TQSL_TRUE; status = TQSL_ADIF_GET_FIELD_SUCCESS; } if( '>' == currentCharacter ) { adifState = TQSL_ADIF_STATE_DONE; } } } else if( strlen( field->name ) < TQSL_ADIF_FIELD_NAME_LENGTH_MAX ) { /* add to field match string */ strCatChar( field->name, currentCharacter ); } else { status = TQSL_ADIF_GET_FIELD_NAME_LENGTH_OVERFLOW; adifState = TQSL_ADIF_STATE_DONE; } break; case TQSL_ADIF_STATE_GET_SIZE: /* GET FIELD SIZE */ /* adding field size characters to buffer, until ':' or '>' found */ if( ( ':' == currentCharacter ) || ( '>' == currentCharacter ) ) { /* reset data copy offset */ dataIndex = 0; /* see if any size was read in */ if( 0 != field->size[0] ) { /* convert data size to integer */ dataLength = strtol(field->size, NULL, 10); } else { dataLength = 0; } if( ':' == currentCharacter ) { /* get the type */ adifState = TQSL_ADIF_STATE_GET_TYPE; } else { /* no explicit type, set to LoTW default */ strcpy( field->type, adifFields[( field->adifNameIndex )].type ); /* get the data */ adifState = dataLength == 0 ? TQSL_ADIF_STATE_DONE : TQSL_ADIF_STATE_GET_DATA; } /* only allocate if we care about the data */ if( recordData ) { if( dataLength <= adifFields[( field->adifNameIndex )].max_length ) { /* allocate space for data results, and ASCIIZ */ if( NULL != ( field->data = (*allocator)( dataLength + 1 ) ) ) { /* ASCIIZ terminator */ field->data[dataIndex] = 0; } else { status = TQSL_ADIF_GET_FIELD_NO_RESULT_ALLOCATION; adifState = TQSL_ADIF_STATE_DONE; } } else { status = TQSL_ADIF_GET_FIELD_DATA_LENGTH_OVERFLOW; adifState = TQSL_ADIF_STATE_DONE; } } } else if( strlen( field->size ) < TQSL_ADIF_FIELD_SIZE_LENGTH_MAX ) { /* add to field size string */ strCatChar( field->size, currentCharacter ); } else { status = TQSL_ADIF_GET_FIELD_SIZE_OVERFLOW; adifState = TQSL_ADIF_STATE_DONE; } break; case TQSL_ADIF_STATE_GET_TYPE: /* GET FIELD TYPE */ /* get the number of characters in the value data */ if( '>' == currentCharacter ) { /* check what type of field this is */ /* place default type in, if necessary */ if( 0 == field->type[0] ) { strcpy( field->type, adifFields[( field->adifNameIndex )].type ); adifState = dataLength == 0 ? TQSL_ADIF_STATE_DONE : TQSL_ADIF_STATE_GET_DATA; } else { /* find if the type is a match to a LoTW supported data type */ status = TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH; adifState = TQSL_ADIF_STATE_DONE; for( iIndex = 0; ( TQSL_ADIF_GET_FIELD_NO_TYPE_MATCH == status ) && ( 0 != typesDefined[iIndex][0]); iIndex++ ) { /* case insensitive compare */ if( 0 == strcasecmp( field->type, typesDefined[iIndex] ) ) { status = TQSL_ADIF_GET_FIELD_SUCCESS; adifState = dataLength == 0 ? TQSL_ADIF_STATE_DONE : TQSL_ADIF_STATE_GET_DATA; } } } } else if( strlen( field->type ) < TQSL_ADIF_FIELD_TYPE_LENGTH_MAX ) { /* add to field type string */ strCatChar( field->type, currentCharacter ); } else { status = TQSL_ADIF_GET_FIELD_TYPE_OVERFLOW; adifState = TQSL_ADIF_STATE_DONE; } break; case TQSL_ADIF_STATE_GET_DATA: /* GET DATA */ /* read in the prescribed number of characters to form the value */ if( 0 != dataLength-- ) { /* only record if we care about the data */ if( recordData ) { /* ASCIIZ copy that is tolerant of binary data too */ field->data[dataIndex++] = (unsigned char)currentCharacter; field->data[dataIndex] = 0; } if (0 == dataLength) adifState = TQSL_ADIF_STATE_DONE; } else { adifState = TQSL_ADIF_STATE_DONE; } break; case TQSL_ADIF_STATE_DONE: /* DONE, should never get here */ default: status = TQSL_ADIF_GET_FIELD_ERRONEOUS_STATE; adifState = TQSL_ADIF_STATE_DONE; break; } } else { status = TQSL_ADIF_GET_FIELD_EOF; adifState = TQSL_ADIF_STATE_DONE; } } if( TQSL_ADIF_GET_FIELD_SUCCESS == status ) { /* check data for enumeration match and range errors */ /* match enumeration */ switch( adifFields[( field->adifNameIndex )].rangeType ) { case TQSL_ADIF_RANGE_TYPE_NONE: break; case TQSL_ADIF_RANGE_TYPE_MINMAX: sscanf( (const char *)field->data, "%lu", &dataValue ); if( ( dataValue < adifFields[( field->adifNameIndex )].min_value ) || ( dataValue > adifFields[( field->adifNameIndex )].max_value ) ) { status = TQSL_ADIF_GET_FIELD_NO_RANGE_MATCH; } break; case TQSL_ADIF_RANGE_TYPE_ENUMERATION: status = TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH; for( iIndex = 0; ( status == TQSL_ADIF_GET_FIELD_NO_ENUMERATION_MATCH ) && ( 0 != adifFields[( field->adifNameIndex )].enumStrings[iIndex][0] ); iIndex++ ) { /* case insensitive compare */ if( field->data && (0 == strcasecmp( (const char *)field->data, adifFields[( field->adifNameIndex )].enumStrings[iIndex] ) ) ) { status = TQSL_ADIF_GET_FIELD_SUCCESS; } } break; } } return( status ); } DLLEXPORT int CALLCONVENTION tqsl_getADIFField(tQSL_ADIF adifp, tqsl_adifFieldResults *field, TQSL_ADIF_GET_FIELD_ERROR *status, const tqsl_adifFieldDefinitions *adifFields, const char * const *typesDefined, unsigned char *(*allocator)(size_t) ) { TQSL_ADIF *adif; if (!(adif = check_adif(adifp))) return 1; if (field == NULL || status == NULL || adifFields == NULL || typesDefined == NULL || allocator == NULL) { tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } *status = tqsl_adifGetField(field, adif->fp, adifFields, typesDefined, allocator, &(adif->line_no)); return 0; } static unsigned char * tqsl_condx_copy(const unsigned char *src, int slen, unsigned char *dest, int *len) { if (slen == 0) return dest; if (slen < 0) slen = strlen((const char *)src); if (*len < slen) { tQSL_Error = TQSL_BUFFER_ERROR; return NULL; } memcpy(dest, src, slen); *len -= slen; return dest+slen; } /* Output an ADIF field to a file descriptor. */ DLLEXPORT int CALLCONVENTION tqsl_adifMakeField(const char *fieldname, char type, const unsigned char *value, int len, unsigned char *buf, int buflen) { if (fieldname == NULL || buf == NULL || buflen <= 0) { /* Silly caller */ tQSL_Error = TQSL_ARGUMENT_ERROR; return 1; } unsigned char *cp; if ((cp = tqsl_condx_copy((const unsigned char *)"<", 1, buf, &buflen)) == NULL) return 1; if ((cp = tqsl_condx_copy((const unsigned char *)fieldname, -1, cp, &buflen)) == NULL) return 1; if (value != NULL && len < 0) len = strlen((const char *)value); if (value != NULL && len != 0) { char nbuf[20]; if ((cp = tqsl_condx_copy((const unsigned char *)":", 1, cp, &buflen)) == NULL) return 1; snprintf(nbuf, sizeof nbuf, "%d", len); if ((cp = tqsl_condx_copy((const unsigned char *)nbuf, -1, cp, &buflen)) == NULL) return 1; if (type && type != ' ' && type != '\0') { if ((cp = tqsl_condx_copy((const unsigned char *)":", 1, cp, &buflen)) == NULL) return 1; if ((cp = tqsl_condx_copy((const unsigned char *)&type, 1, cp, &buflen)) == NULL) return 1; } if ((cp = tqsl_condx_copy((const unsigned char *)">", 1, cp, &buflen)) == NULL) return 1; if ((cp = tqsl_condx_copy(value, len, cp, &buflen)) == NULL) return 1; } else if ((cp = tqsl_condx_copy((const unsigned char *)">", 1, cp, &buflen)) == NULL) return 1; if ((cp = tqsl_condx_copy((const unsigned char *)"", 1, cp, &buflen)) == NULL) return 1; return 0; } tqsl-2.0/src/LICENSE0000664000076400007640000000450712231073120014137 0ustar rmurphyrmurphyLicense Terms and Conditions Copyright (C) 2001-2003 American Radio Relay League, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Any redistribution of source code must retain the above copyright notice, this list of conditions and the disclaimer shown in Paragraph 5 (below). 2. Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the disclaimer shown in Paragraph 5 (below) in the documentation and/or other materials provided with the distribution. 3. Products derived from or including this software may not use "Logbook of the World" or "LoTW" or any other American Radio Relay League, Incorporated trademarks or servicemarks in their names without prior written permission of the ARRL. See Paragraph 6 (below) for contact information. 4. Use of this software does not imply endorsement by ARRL of products derived from or including this software and vendors may not claim such endorsement. 5. Disclaimer: This software is provided "as-is" without representation, guarantee or warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability or of fitness for a particular purpose. The entire risk as to the quality and performance of the software is solely with you. Should the software prove defective, you (and not the American Radio Relay League, its officers, directors, employees or agents) assume the entire cost of all necessary servicing, repair or correction. In no event will ARRL be liable to you or to any third party for any damages, whether direct or indirect, including lost profits, lost savings, or other incidental or consequential damages arising out of the use or inability to use such software, regardless of whether ARRL has been advised of the possibility of such damages. 6. Contact information: American Radio Relay League, Inc. Attn: Logbook of the World Manager 225 Main St Newington, CT 06111 voice: 860-594-0200 fax: 860-594-0259 email: logbook@arrl.org Worldwide Web: www.arrl.org This software consists of voluntary contributions made by many individuals on behalf of the ARRL. More information on the "Logbook of The World" project and the ARRL is available from the ARRL Web site at www.arrl.org. tqsl-2.0/src/Doxyfile0000775000076400007640000023426112231073120014645 0ustar rmurphyrmurphy# Doxyfile 1.8.3.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "TrustedQSL Library API" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = tqsllib-doc.h \ tqsllib.h \ tqslerrno.h \ adif.h \ cabrillo.h \ tqslconvert.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = tqsllib.css # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES tqsl-2.0/src/ChangeLog.txt0000664000076400007640000001212512231073120015515 0ustar rmurphyrmurphyTQSLLIB changes =============== 2.4 --- Fix atoi() calls throughout to use strtol() so that strings like 012 aren't treated as Octal due to the leading zeroes. Default Cabrillo field to 8, not 5. Fix OpenSSL workaround needed for 1.0.0c of OpenSSL so that it only applies to that release, not later releases with the fix already in place. Add new tqsllib APIs: Retrieve a named field from a station location Merge a station location definition into the database Add the ability to export station locations APIs to export and import certificates Base-64 encoded APIs to export and import duplicates database records Added an API to calculate the difference between dates Verify that the BAND and FREQ fields are consistent. Disallow freqencies outside of valid ranges for ham bands. This catches "10110" used (KHz) versus the ADIF required 10.110 (MHz). Always convert frequency values in Cabrillo logs to Megahertz independent of contest type (HF/VHF). Remove strcpy/strcat/sprintf and replace with strn* variants where possble. Allow FREQ=0 when BAND is set. Try to deduce worked call field for unknown Cabrillo file contest names. Update mode mapping in Cabrillo files to pass FM through as is and convert PH to SSB. When trying to deduce call-worked field, ensure that anything that looks gridsquare-like is skipped. Don't accept a log if there are two fields that look like callsigns. Relax lower limit for 30m, 17m, and 12m bands to allow 10MHz, 18MHz, and 24MHz to be allowed Recover from invalid files in the working directory (symlink loops) by detecting and removing them. These would cause database opens to fail while searching for recovery logs. Correctly handle permission problems and other system errors that occur when opening station data and certificate files. Strip spaces from entirely space-filled station location fields when creating signing data. Prior versions of tqsllib would not properly trim strings containing only spaces. Remove code that was trying to remove unnecessary transaction log files as that was causing duplicate detection to fail. 2.3 --- Add a mechanism to the location definition process to allow enforcement of proper zone number combinations. A status message is returned to allow the caller to report illogical selections. Duplicate checking database. No changes necessary for exising code. However new or updated code is strongly encouraged to enable duplicate checking and commit or discard a particular signing instance as appropriate tqsllib now built with MSVC on Windows. ABI compatility with the previous MinGW-built version is maintained. tqsllib and the rest of TrustedQSL now built with the CMake build system Fixed several bugs, crashes, and potential vulnerabilities ** Windows 98 support has been dropped. This will be one of the last releases to support Windows 2000. ** This will be one of the last releases to support OS X on PowerPC systems. 2.2 --- Fixed bug in handling of certificates with long serial numbers (typically root certs). Added workaround for OpenSSL 1.0a bug. 2.1 --- Prompt user to save their certificate after importing a .tq6 signed certificate. Fix filtering of superceded certificates so they are not displayed by default. Don't allow certificate import to overwrite a newer certificate. Require selection of states for US, provinces for Canada (with ability to override when not appropriate.) Handle Alaskan administratitive areas by allowing them to be selected while outputting the correct county name in the station data exported with a signed log. Added support for specifying zone numbers for entities, states, and provinces Force proper zones for entities, states when possible. Update configuration file to correspond to ADIF specifications for county names. Ignore expired certificates during import/export when an expired CA certificate is signed by a valid root cert. Support OpenSSL 0.9 through 1.0 beta. Fix security bug in certificate validation. 2.0 --- The Windows DLL has changed to use __stdcall. This makes it incompatible with previous versions of the DLL, necessitating a change in major version number. openssl 0.9.6 or 0.9.7 is now required; earlier versions are not supported. 1.6 --- Fixed a bug in the .p12 file generation under openssl 0.9.7. Thanks to Kenji 'Joe' Rikitake, JJ1BDX for the fix. Fixed a bug in tqsl_get_cert_ext that under some circumstances caused return of unterminated strings. 1.5 --- Added MacOS support. Converted build scripts to make full use of autoconf/automake. Fixed some GCC 3.x compiler warnings. 1.4 --- Fixed bug in ADIF converter where input file wasn't being opened in binary mode. Several error conditions in tqsl_getConverterGABBI caused the converter to loop on the same erroneous record. 1.3 --- Fixed a bug in the comparison of configuration file version numbers. Added tqsl_verifyDataBlock function. 1.2 --- Added tqsl_getSatellite and tqsl_getPropagationMode config functions. Added support for conversion of ADIF BAND_RX, FREQ_RX, PROP_MODE and SAT_NAME fields. 1.1 --- ADIF converter was rejecting BAND field > 5 characters, but the valid 1.25cm value is 6 characters long. tqsl-2.0/src/CMakeLists.txt0000664000076400007640000000634412231073120015673 0ustar rmurphyrmurphyproject (tqsllib) set(OSX_ARCH i386 CACHE STRING "Architectures to build for OSX") string(REPLACE " " ";" CMAKE_OSX_ARCHITECTURES ${OSX_ARCH}) if(WIN32) add_definitions(-DXML_STATIC) endif() find_package(EXPAT REQUIRED) find_package(OpenSSL REQUIRED) find_package(ZLIB REQUIRED) FIND_PACKAGE(BDB REQUIRED) set(TQSLLIB_VERSION_MAJOR 2) set(TQSLLIB_VERSION_MINOR 4) set(TQSLLIB_VERSION "${TQSLLIB_VERSION_MAJOR}.${TQSLLIB_VERSION_MINOR}") add_definitions(-DTQSLLIB_VERSION_MAJOR=${TQSLLIB_VERSION_MAJOR}) add_definitions(-DTQSLLIB_VERSION_MINOR=${TQSLLIB_VERSION_MINOR}) option(TQSLLIB_STATIC "Build static tqsllib" OFF) if (${TQSLLIB_STATIC}) set(TQSLLIBTYPE STATIC) else() set(TQSLLIBTYPE SHARED) endif() if(WIN32) set(TQSLLIB_RCFILE "tqsllib.rc") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TQSLLIB_RCFILE}.in" "${CMAKE_CURRENT_SOURCE_DIR}/${TQSLLIB_RCFILE}") set(TQSLLIBNAME "tqsllib2") #for compatibility with existing software else() set(TQSLLIBNAME "tqsllib") endif() set(TQSLLIB_SRC tqsllib.cpp openssl_cert.cpp adif.cpp xml.cpp location.cpp tqslconvert.cpp cabrillo.cpp) set(TQSLLIB_HDR xml.h openssl_cert.h tqslexc.h tqsllib.h tqslerrno.h cabrillo.h adif.h tqslconvert.h) if(APPLE) find_library(CARBON_LIBRARY Carbon) find_path(CARBON_INCLUDE_DIR Carbon.h) endif() if(WIN32) #def file for correct 2.x exports set(TQSLLIB_SRC ${TQSLLIB_SRC} "tqsllib2.def") endif() add_library(${TQSLLIBNAME} ${TQSLLIBTYPE} ${TQSLLIB_SRC} ${TQSLLIB_HDR} ${TQSLLIB_RCFILE}) target_link_libraries(${TQSLLIBNAME} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${ZLIB_LIBRARIES} ${BDB_LIBRARIES} ${CARBON_LIBRARY}) include_directories(${OPENSSL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${EXPAT_INCLUDE_DIR} ${BDB_INCLUDE_DIR} ${CARBON_INCLUDE_DIR}) if(NOT APPLE AND NOT WIN32) set_source_files_properties(location.cpp PROPERTIES COMPILE_DEFINITIONS CONFDIR="${CMAKE_INSTALL_PREFIX}/share/TrustedQSL/") set(HEADERS_TO_INSTALL tqsllib.h tqslerrno.h cabrillo.h adif.h tqslconvert.h) install(TARGETS tqsllib DESTINATION lib) install(FILES config.xml DESTINATION share/TrustedQSL) install(FILES ${HEADERS_TO_INSTALL} DESTINATION include) endif() option(BUILD_ALL_EXTRAPROGS "Build all extra programs") if(BUILD_ALL_EXTRAPROGS) set(BUILD_GENCRQ ON) set(BUILD_LOADCERT ON) set(BUILD_STATIONLOC ON) set(BUILD_CONVERTER ON) if(WIN32 AND (BUILD_GENCRQ OR BUILD_LOADCERT OR BUILD_STATIONLOC OR BUILD_CONVERTER)) message("I can't build the tqsllib programs on Windows yet. Disabling them...") set(BUILD_GENCRQ OFF) set(BUILD_LOADCERT OFF) set(BUILD_STATIONLOC OFF) set(BUILD_CONVERTER OFF) endif() else() option(BUILD_GENCRQ "Build gen_crq") option(BUILD_LOADCERT "Build load_cert") option(BUILD_STATIONLOC "Build station_loc") option(BUILD_CONVERTER "Build converter") endif(BUILD_ALL_EXTRAPROGS) if(BUILD_GENCRQ) add_executable(gen_crq gen_crq.cpp) target_link_libraries(gen_crq ${TQSLLIBNAME}) endif(BUILD_GENCRQ) if(BUILD_LOADCERT) add_executable(load_cert load_cert.cpp) target_link_libraries(load_cert ${TQSLLIBNAME}) endif(BUILD_LOADCERT) if(BUILD_STATIONLOC) add_executable(station_loc station_loc.cpp) target_link_libraries(station_loc ${TQSLLIBNAME}) endif(BUILD_STATIONLOC) if(BUILD_CONVERTER) add_executable(converter converter.cpp) target_link_libraries(converter ${TQSLLIBNAME}) endif(BUILD_CONVERTER) tqsl-2.0/src/.project0000664000076400007640000000443612231073120014602 0ustar rmurphyrmurphy tqsllib org.eclipse.cdt.managedbuilder.core.genmakebuilder clean,full,incremental, ?name? org.eclipse.cdt.make.core.append_environment true org.eclipse.cdt.make.core.autoBuildTarget all org.eclipse.cdt.make.core.buildArguments org.eclipse.cdt.make.core.buildCommand make org.eclipse.cdt.make.core.cleanBuildTarget clean org.eclipse.cdt.make.core.contents org.eclipse.cdt.make.core.activeConfigSettings org.eclipse.cdt.make.core.enableAutoBuild false org.eclipse.cdt.make.core.enableCleanBuild true org.eclipse.cdt.make.core.enableFullBuild true org.eclipse.cdt.make.core.fullBuildTarget all org.eclipse.cdt.make.core.stopOnError true org.eclipse.cdt.make.core.useDefaultBuildCmd true org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder full,incremental, org.eclipse.cdt.core.cnature org.eclipse.cdt.core.ccnature org.eclipse.cdt.managedbuilder.core.managedBuildNature org.eclipse.cdt.managedbuilder.core.ScannerConfigNature tqsl-2.0/src/.gitignore0000664000076400007640000000014612231073120015115 0ustar rmurphyrmurphy#linux-specific products libtqsllib.so #Windows build artifacts Debug Release #OSX binaries *.dylib tqsl-2.0/src/.cproject0000664000076400007640000002615512231073120014747 0ustar rmurphyrmurphy tqsl-2.0/osx_createdmg.sh0000775000076400007640000000220712231073120015521 0ustar rmurphyrmurphy#!/bin/sh TQSLVER=`cat apps/tqslversion.ver` TQSLLIBPATH=`pwd`/src/libtqsllib.dylib WORKDIR=`mktemp -d /tmp/tqsl.XXXXX` || exit 1 /bin/echo -n "Copying files to image directory... " cp apps/ChangeLog.txt $WORKDIR/ChangeLog.txt cp LICENSE.txt $WORKDIR/ cp apps/quick "$WORKDIR/Quick Start.txt" mkdir $WORKDIR/TrustedQSL cp -r apps/tqsl.app $WORKDIR/TrustedQSL /bin/echo "done" /bin/echo -n "Installing the libraries and tweaking the binaries to look for them... " for app in tqsl do cp $TQSLLIBPATH $WORKDIR/TrustedQSL/$app.app/Contents/MacOS install_name_tool -change $TQSLLIBPATH @executable_path/libtqsllib.dylib $WORKDIR/TrustedQSL/$app.app/Contents/MacOS/$app cp src/config.xml $WORKDIR/TrustedQSL/$app.app/Contents/Resources done /bin/echo "done" /bin/echo -n "Installing the help... " cp -r apps/help/tqslapp $WORKDIR/TrustedQSL/tqsl.app/Contents/Resources/Help /bin/echo "done" /bin/echo "Creating the disk image..." #hdiutil uses dots to show progress hdiutil create -ov -srcfolder $WORKDIR -volname "TrustedQSL v$TQSLVER" "tqsl-$TQSLVER.dmg" /bin/echo -n "Cleaning up temporary files.. " rm -r $WORKDIR /bin/echo "Finished!" tqsl-2.0/linux-uninstall.sh0000775000076400007640000000014212231073120016037 0ustar rmurphyrmurphy#!/bin/sh tr '\n' '\0' < install_manifest.txt | xargs -0 sudo rm #some of the files have spaces tqsl-2.0/linux-make-tarball.sh0000775000076400007640000000213412231073120016365 0ustar rmurphyrmurphy#!/bin/sh if [ $# -eq 0 ] || [ $# -gt 2 ]; then echo "usage: $0 [tree-ish] name" echo " This script will create a git-free tarball of the source directory" echo " with the build id appropriately substituted, just like CMake" echo " does if it can find git." echo echo " 'name' will become a tarball called name.tar.gz" echo " containing the archive" exit 0 fi; #is git directory? if [ ! -d ".git" ]; then echo "Working directory is not a git directory!" exit 1 fi # we will extract to a temp dir to make build id TEMPDIR=`mktemp -d` || exit 1 TREEISH="HEAD" if [ $# -eq 2 ]; then # we use this as a tree-ish TREEISH="$1" shift; fi OUTNAME=$1 git archive --format=tar --prefix="$OUTNAME/" $TREEISH | (cd $TEMPDIR && tar xf -) || exit 1 DESC=`git describe $TREEISH` VER=`git show $TREEISH:apps/tqslversion.ver` sed -e s/@BUILD@/pkg-$DESC/ -e s/@TQSLVERSION@/$VER/ $TEMPDIR/$OUTNAME/apps/tqslbuild.h.in > $TEMPDIR/$OUTNAME/apps/tqslbuild.h dos2unix -q $TEMPDIR/$OUTNAME/README WD=`pwd` (cd $TEMPDIR && tar zcf $WD/$OUTNAME.tar.gz $OUTNAME) rm -R $TEMPDIR tqsl-2.0/html/0000775000076400007640000000000012231073120013301 5ustar rmurphyrmurphytqsl-2.0/html/trustedqsl/0000775000076400007640000000000012231073120015513 5ustar rmurphyrmurphytqsl-2.0/html/trustedqsl/vendors.html0000664000076400007640000000073512231073120020066 0ustar rmurphyrmurphy

Logbook Vendors that plan to support LoTW and TrustedQSL

 

CSS Log Windows Logging and Database Software

World Class Logging DXbase

CT Contesting Logging Program by K1EA

Ordered by the announce date of plan support.

tqsl-2.0/html/trustedqsl/userguide.html0000664000076400007640000000332012231073120020373 0ustar rmurphyrmurphy Trusted QSL Programming Guide

The Trusted QSL SDK has been created with the concept that there should be a secure and trusted way to exchange E-QSL cards. To this end TQSL library and tools was created. Too avoid any one entity from having control over this powerful system, the sources for all the libraries and tools are release under the GNU Lessor GNU Public License or (LGPL) In short is says that your can do anything your want with the source provided you don't try to prevent others from doing the same. The design goals for this product was fairly simple:

Goals

  • Secure - At least 700 bits
    1. Authentication - Must be able to for the receiver of a message to ascertain its origin.
    2. Integrity - Must be able to verify that the message hasn't been changed or substituted.
    3. Nonrepudiation - A sender should not be able to falsely deny later that he sent a message
  • Programmer Friendly - Easy to add existing program
  • Portable - Source should compile just about any OS
  • User Friendly - Should be easy for CAs and end users.

Installation

  1. First your must get and compile OpenSSL
  2. Build the TrustedQSL library. On Linux you can use the Makefile.
  3. Build example command line program.
  4. Test example program tqverify with command tqverify -f README -s README.sig
tqsl-2.0/html/trustedqsl/tqsl_api.html0000664000076400007640000000173712231073120020225 0ustar rmurphyrmurphy

Trusted QSL API

 

struct PubInfo

{ char name[NAME_SIZE]; char callSign[CALLSIGN_SIZE]; char pubkey[KEY_SIZE]; }; struct CertInfo { PubInfo pubKeyInfo; char CA[CA_SIZE]; char CAUrl[URL_SIZE]; char expiration[DATE_SIZE]; char CASignature[SIGN_SIZE]; };

 

int tQSL_genKeyPair(char *secretKeyRing, char *pubKeyRing, struct KeyInfo *keyInfo);

int tQSL_deleteKey(char *keyRing,struct keyId);

int tQSL_genCert(struct pubKeyId kid,struct KeyId keyId,struct CertInfo cert);

int tQSL_signMessage(struct KeyId keyid,char *secretKeyRing,char *message,char *sign);

int tQSL_authMessage(struct KeyId keyid,char *pubKeyRing,char *message,char *sign);

 

tqsl-2.0/html/trustedqsl/project_plan.html0000664000076400007640000001637712231073120021077 0ustar rmurphyrmurphy TrustedQSL Project Plan and Requirements

Introduction

The goal of the TrustedQSL project is to provide an open source API and frame work to support the exchange of signed digital QSL called TrustedQSLs or tQSLs for short.  This includes the tools for implement a PKI (Public Key Infrastructure) based upon the OpenSSL crypto library.  Soon after the project started ARRL contact us about using TrustedQSL as the client/PKI library for the Logbook Of The World project.   We worked out our minor difference in the design concept and agreed to work together.  The rest is history as they say.  Now the question is where do we go from here?  I have carved up the project in what I believe is a good grouping of subprojects. 

The rest of the document will talk about the different subproject TrustedQSL project.

Trusted Gabbi (Global Amateur Interchange)  Formats

Discussion:


There are currently many different interchange formats that are being used by amateur radio today. By far the most popular is ADIF (Amateur Data Interchange Format) for good reason. It is a very elegant, robust, and easy to read as raw data. It has many of the features found in XML without the need for special libraries and their associated learning curve. Having said that ADIF does have a short coming. It doesn't have any concept of record type. Today discussions with the ADIF development group hasn't been fruitful. Therefore to meet the requires of this project the standard must be forked. The new standard will be called XADIF. It is hoped that the two standards will be merged at some point in the future. Therefore a design goal is for Gabbi (Global Amateur Interchange) format to be backward compatible with ADIF. This turns out to be fairly easy to do by declaring the QSO/Logbook record as the default record type.

Requirements:

  • RecType Field. This field will determine the record type
  • An algorithm for determining the signing order of the fields must be specified.  
  • In addition the currently define QSO/Logbook record, QSL and Station Records must be defined.
  • Field definitions is only significant to that record.  For example a GRID_SQUARE field on a QSO would refer to the contact station grid square.  GRID_SQUARE on a station record would refer to the grid square of the station submitting the QSL
  • A new field or possibly as well define virtual field (ie: call and number of seconds since epoch) which can be common to all records and required for tQSL records will be the GUID (Global Unique ID entifier).  This is in order that different records can be uniquely connected to other records in a portable and database independent way.
  • C/C++ functions that parse and create record strings.
  • Create a memory object that can store and sign a record.

Task:

  1. Define specification for tQSL Records
  2. Define specification for a trusted QTH/station record
  3. Define specification Trusted Delegation record (deferred)
  4. Create functions and/or class to parse, format, read and write Gabbi records.
  5. Create API usage document for #4

Public Key Infrastructure (PKI) Functions

Discussion:

The PKI functions is the heart of TrustedQSL.  It allows LoTW and others to authenticate tQSL using public key digital signature PKDS technology PKI are by there very nature complex and many of the policy issues are address by the LoTW design document.  The scope of this document is to provide the API functions required to support a PKI such as LoTW will require.  It is beyond the scope of this project to define any of the procedures or policies for the operation of a CA.

Currently most PKDS uses the RSA encryption Algorithm, however in many countries the use of strong encryption software is illegal to use, own, import and/or export.  Because of this the initial release will use the DSS (Digital Signature Standard) for created and authentication of digital signatures.  The low level design will be able to support RSA in the event that laws change such as would permit the free use of RSA. DSA (Digital Signature Algorithms) claims to be able to be used for digital signatures, therefore there is no known restrictions placed on it by any government.

PKDS are relative simple in nature requiring only basic math to compute.  What makes PKDS complex and hard to deal with is the uses of big numbers.  Most computers today are 32 bits, some are 64 bits and a few special purpose computers are 128 bits.  The smallest number used by DSA is 160 bits and goes up to 1024 bits.  Therefore it takes special routines to deal with these big numbers.  Fortunately another open source project OpenSSL has taken care of all the low level work.  There is two important things that makes the OpenSSL project appealing.  1) The licenses does plan any restrictions on product that uses any of the OpenSSL libraries, unlike the GPL license that requires the release of all source.  2) It is native C code and has been ported to every major platform/OS including Win32, Mac, Linux and Unix.  It doesn't not however support 16 bit OS such as MS-DOS.  Also there is no direct support for Java.  It is believed that Java support can be done with some of the encryption class that are available for Java.

Task: 

  1. Crypto support libraries and ports.
    The OpenSSL library is in itself a large library. Most of the functions provide by the OpenSSL crypto library will not be used by TrustedQSL. To make it as simple as possible for software vendors, the library should be reduce to a subset of functions that will be used directly or indirectly by TrustedQSL API. This is most important for Win32 platform because of the large base of users, but should also be done for Mac as well. Linux isn't a issue because OpenSSL comes fairly standard on Linux or can be compiled and installed without any trouble.
  2. Key Management
  3. Cert, CertReq and CRL Management
  4. TrustedQSL API library
  5. Programmers Guide to TrustedQSL/LoTW
  6. Cert and digital signature format

Create class/libraries for different transport protocols

  1. HTTP Upload
  2. SNAIL Mail support
  3. Create a method to send a tQSL message as an attachment
  4. Create a http client that will format and send tQSL messages

Create sample client programs that uses TrustedQSL library

  1. Format translator ADIF->Gabbi
  2. Cabrillo->Gabbi
  3. Stand alone tQSL
tqsl-2.0/html/trustedqsl/php.html0000664000076400007640000000005612231073120017171 0ustar rmurphyrmurphy tqsl-2.0/html/trustedqsl/newindex.html0000664000076400007640000000767112231073120020235 0ustar rmurphyrmurphyTrusted QSLs FAQ Page

Trusted QSL Home

Work in progress.

Our Mission

The mission of the TrustedQSL Group is to keep QSL and E-QSL open and free activities for amateur radio operators by promoting Digital Signature Algorithm (DSA).

Our Goal

Our goal is to set the standards and create computer API libraries and the tools required to implement the Trusted DSA model.  The standards and source codes will be licensed using the Lessor GNU Public License. 


Currently there are two ways to handle E-QSL:
1.The Central Logbook model which grants you access to a central logbook server via a trusted process.
2. DSA. In this case a trusted third party signs you a unique public key that becomes a certifcate.  This allows the prinacpal to sign other messages with his private key that can only be validated with the signed certificate.  Just like a notary public does care or try to validate what you signed just that it was indeed you that signed it.  Certificates perform the same functions.

The Trusted QSL Group supports the DSA process. We don't think that a central logbook server is in keeping with the sprit of amateur radio because it requires a large trusted central staff to maintain it.  Also in the words of "Highlander"  there can only be one.  If there were more than one QSL processing server, then an amateur would have to join them all to insure that their contacts received credit. If there is only one then there could be no competition for the service.  We feel that this is a very BAD thing. 

Using an open standard with open sources for a PKDS provides a model which no single entity can become the end all of trusted QSL.  Any group wishing to become a Certification Authority (CA) can do so.  The trust of that CA lies in the award sponsor.  Award sponsors may have requirements for the CA to meet before they become trusted.  This is as it should be.  We envision a very large number of CAs being formed to meet the needs of the Amateurs.

This means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and then make money off of them.  The only sources that they would be required to release on demand would the sources to the libraries.  This could be done by pointing them to our web site.

Our mission is to set the standards and create computer API libraries and tools require to implement the Trusted PKDS model.  The standard and source code will be licensed using the Lessor GNU Public License.  Which simply means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and then make money off of them.  The only sources that they would be required to release on demand would the sources to the Trusted QSL libraries.  This could be done by pointing them to our web site.

Directory

FAQ

Mailing List (reflector)

OpenSSL Project Without there greate open source product this project wouldn't have been where it is today.

Downloads TrustedQSL project site at www.sourceForge.net

Documentation (WIP)

Copyright 2001 - Trusted QSL Group.

 

tqsl-2.0/html/trustedqsl/mailing.html0000664000076400007640000000134212231073120020021 0ustar rmurphyrmurphy
Subscribe to TrustedQSL
Powered by groups.yahoo.com

tqsl-2.0/html/trustedqsl/license.txt0000664000076400007640000000737112231073120017706 0ustar rmurphyrmurphy /* ====================================================================
 * Copyright (c) 2001 American Radio Relay League, Inc. (ARRL) and
 *      Darryl Wagoner WA1GON.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistribution of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistribution in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the ARRL and Darryl
 *    Wagoner WA1GON for use in the ARRL Logbook Of The World
 *    project (http://www.trustedQSL.org)."  Also acknowledgment of
 *    the OpenSSL Project.
 *
 * 4. The names "Logbook of The World" and "ARRL" must not be used as
 *    an endorsement of products derived from this software without
 *    prior written permission. For written permission, please contact
 *    jbloom@arrl.org.
 *
 * 5. Products derived from this software may not be called "LoTW"
 *    nor may "LoTW" appear in their names without prior written
 *    permission of the ARRL.
 *
 * 6. Redistribution of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the ARRL and
 *    Darryl Wagoner WA1GON for use in the Logbook of The World project
 *
 * THIS SOFTWARE IS PROVIDED BY THE  ARRL ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ARRL OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the ARRL.  For more information on
 * the "Logbook of The World" project  and the ARRL project,
 * please see <http://www.arrl.org/>.
 *
 */
tqsl-2.0/html/trustedqsl/index.html0000664000076400007640000000537012231073120017515 0ustar rmurphyrmurphyTrusted QSLs FAQ Page

Trusted QSL Home

WIP (Work in progress).

Our Mission

The mission of the Trusted QSL Group is to keep QSL and E-QSL open and free activities for amateur radio operators by promoting Digital Signature Algorithm (DSA).

Our Goal

Our goal is to set the standards and create computer API libraries and the tools required to implement the Trusted DSA model.  The standards and source codes will be licensed using the Opening Source License. 


 

TrustedQSL is an open source licenses, this means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and then make money off of them.  The only sources that they would be required to release on demand would the sources to the libraries.  This could be done by pointing them to our web site.

Our mission is to set the standards and create computer API libraries and tools require to implement the Trusted PKDS model.  The standard and source code will be licensed using the Apache/BSD open source license.  Which simply means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and makng money. The only sources that they would be required to release on demand would be the sources to the Trusted QSL libraries.  This could be done by pointing them to our web site.

Directory

FAQ

LoTW/TrustQSL PKI client project

Mailing List (reflector)

OpenSSL Project Without their great open source product this project wouldn't be where it is today.

  SourceForge Logo TrustedQSL project site at www.sourceForge.net

Documentation (WIP)

ARRL LoTW Design Document

Copyright 2001 - Trusted QSL Group.

 

tqsl-2.0/html/trustedqsl/index-new.html0000664000076400007640000000724012231073120020302 0ustar rmurphyrmurphyTrusted QSLs FAQ Page

Trusted QSL Home

Work in progress.

Our Mission

The mission of the Trusted QSL Group is to keep QSL and E-QSL open and free activities for amateur radio operators by promoting Digital Signature Algorithm (DSA).

Our Goal

Our goal is to set the standards and create computer API libraries and the tools required to implement the Trusted DSA model.  The standards and source codes will be licensed using the Lessor GNU Public License. 


Currently there are two ways to handle E-QSL:
1.The Central Logbook model which grants you access to a central logbook server via a trusted process.
2. DSA. In this case a trusted third party assigns you a unique public key which allows you to sign any number of messages.

The Trusted QSL Group supports the DSA process. We don't think that a central logbook server is in keeping with the sprit of amateur radio because it requires a large trusted central staff to maintain it.  Also in the words of "Highlander"  there can only be one.  If there were more than one QSL processing server, then an amateur would have to join them all to insure that their contacts received credit. If there is only one then there could be no competition for the service.  We feel that this is a very BAD thing. 

Using an open standard with open sources for a PKDS provides a model which no single entity can become the end all of trusted QSL.  Any group wishing to become a Certification Authority (CA) can do so.  The trust of that CA lies in the award sponsor.  Award sponsors may have requirements for the CA to meet before they become trusted.  This is as it should be.  We envision a very large number of CAs being formed to meet the needs of the Amateurs.

This means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and then make money off of them.  The only sources that they would be required to release on demand would the sources to the libraries.  This could be done by pointing them to our web site.

Our mission is to set the standards and create computer API libraries and tools require to implement the Trusted PKDS model.  The standard and source code will be licensed using the Lessor GNU Public License.  Which simply means that you can use it for how every you wish as long as you do not attempt to prevent others from doing the same.   This doesn't prevent log book authors from using the libraries and then make money off of them.  The only sources that they would be required to release on demand would the sources to the Trusted QSL libraries.  This could be done by pointing them to our web site.

Directory

FAQ

Mailing List (reflector)

OpenSSL Project Without there greate open source product this project wouldn't have been where it is today.

Downloads TrustedQSL project site at www.sourceForge.net

Documentation (WIP)

Copyright 2001 - Trusted QSL Group.

 

tqsl-2.0/html/trustedqsl/gloss.html0000664000076400007640000000611012231073120017526 0ustar rmurphyrmurphy Glossary

Authentication - Being able to validate that a messages is from who it claims to be from. An intruder should not be able to masquerade as someone else.

Big Numbers - Very large numbers used in digital encryption and signatures. Big numbers those larger than 2^128 or 128 bits integer. For comparison the number of atoms in the planet(Earth) is 2^170 or 170 bits integer.

CA - Certifying Authority

Cert - Short for certificate

Certificate - A special format of a public key which has been signed by a Certifying Authority

Certifying Authority - A trusted entity that signs public keys

Digital Signature - A special hash or signature which is create using the private key and can only be validate using the matching public key.

Gabbi - Global Amateur Interchange format. This is the format that logbooks use to send tQSL data to LoTW servers.

Integrity - Being able to validate that the message hasn't been altered.

Message - Any message or data that is to be signed, such a QSL or public key

Nonredudiation - A sender should not be able to falsely deny later that he sent a message.

PKDS - Public Key Digital Signature. 

PKI - Public Key Infrastructure.  Because of the trust is require in using a PK system it requires a complex infrastructure which is called PKI.

Prime Numbers - Numbers that can only be divided by by itself and 1.

Principal - The person originating the message

Private key - A key which is used to sign messages which must be kept private

Public key - A key which can only be used to validate messages which has been signed with the matching private key.

Secret key - A key which is used in single key encryption systems. A private key should be stored encrypted with a secret key.

Because this digital signature and encryption protocols has many players standard names call dramatic personae have been given to them.  Because we are only concern with digital signatures and certificates has been shorten to include only those we need.

Dramatis Personae

Alice First participant in all the all protocols
Bob Second participant in the all protocols
Mallory Malicious active attacker
Trent Trusted arbitrator
Peggy QSL service provider
Victor Award sponsor verifier

tqsl-2.0/html/trustedqsl/format_design.html0000775000076400007640000000614412231073120021232 0ustar rmurphyrmurphy TrustedQSL High Level Design Notes

TrustedQSL High Level Virtual Record Design Notes

by
Michael Keane K1MK
k1mk@alum.mit.edu

  1. Built-In (or Spec Defined) Signed Field
    • The name of this field is included in a TBD list of field names defined in the Gabbi specification.
    • Value of this field is incorporated into "virtual record" used for calculating digital signature
    • External representations of the value of this field shall be encoded using a TBD set of formatting rules given in the Gabbi
    • The formatting rules must result in an unambiguous bi-directionalmapping between a data value and its unique external represestation.
    • Database design must save the value of this field.
    • Database design may employ internal representations for storing the value of the field that differ from the external representation. E.g., numeric values maye be stored as a binary number rather than as a string of digit characters.
    • Only ASCII characters shall be used in field name and in the external representation of the value of this field [TBR]

  2. Built-In (or Spec Defined) Unsigned Field
    • The name of this field is included in a TBD list of field names defined in the Gabbi specification.
    • Field name shall also employ a TBD mechanism designating this as an "unsigned" field
    • Value of field is ommitted from the "virtual record" used for calculating digital signature
    • Database design may decline to save this field
    • Only ASCII characters shall be used in field name
    • Any valid Unicode characters may be used in the field value [TBR]

  3. User Defined Signed Field
    • Field name is not in the union of the lists of signed and unsigned fields defined in the Gabbi spec
    • Value of field incorporated into "virtual record" for calculating digital signature
    • Database design must save the unprocessed octet strings representing this field's name and its value. These strings shall be saved in the functional equivalent of a table
    • Any valid Unicode characters may be used in the field name and field value [TBR]

  4. User Defined Unsigned Field
    • Field name is not in the union of the lists of signed and unsigned fields defined in the Gabbi specification
    • Field name shall also employ a TBD mechanism designating this as an "unsigned" field
    • Value of field is ommitted from the "virtual record" used for calculating digital signature
    • Database design may decline to save this field
    • Any valid Unicode characters may be used in the field name and field value [TBR]
tqsl-2.0/html/trustedqsl/faq.html0000664000076400007640000001652012231073120017154 0ustar rmurphyrmurphyTrusted QSLs FAQ Page

Trusted QSL FAQ

  1. Q. What is the difference between E-QSLs and tQSLs?
    A.    tQSL is a special form of E-QSL that has been signed by the originator with a strong digital signature.

  2. Q. What type of service does TrustedQSL.org offer?
    A. TrustedQSL.org doesn't really offer services. We provides information about TrustedQSL system and Open Source tools.

  3. Q. Is DSA (Digtial Signature Algorithm) really secure?
    A. Yes, the only known attack against DSA is brute force. The public key is 1024 bits long. (talk about big numbers)

  4. Q. What is wrong with the www.eQSL.cc ?
    A. First the tQSL does NOT exclude the use of a logbook server such as eQSL.cc or LoTW, it just add a strong third party trust protocol and removes the server for being the trusted arbitrator.  In fact LoTW will use TrustedQSL libraries to protect the system.

  5. Q. What is a Certification Authority(CA) and why are they important?
    A.   A public key is just a very large number.  In itself it has no meaning except that it has a matching private key.  The trusted CA takes the public using a trusted means such as postal mail or other secure means and wraps it up into a signed certiicate.  If there is any question about the certifcate being authenicate, it can be validate with the CA's certificate.

  6. Q. Who grants CA status?
    A.   Any person or group can become a CA.  It is the award sponsors who must endorse the CA as being trusted for their program.  It is outside the scope of this group to set policy for the award sponsors.

  7. Q. Who are the CAs?
    A.   Currently isn't any CAs because the software isn't finished, but ARRL will be the first CA.  Since they are a major award sponsor they should be ones to grant CA status.   TrustedQSL.ORG will issue "TEST" Certificate, but trustedQSL isn't going to be in the certificate business.

  8. Q. Why should we trust TrustedQSL.org?
    A. There is no need to trust TrustedQSL.org. We just provide open source tools.

  9. Q. What is a certificate (cert)?  Is it the same as a public key?
    A. A cert contains the public key, call sign and other information, plus a signature of the CA that signed and endorse the public key.

  10. Q. What can I sign with my cert?
    A. Nothing. Certs are only for validating signatures. You use a private key to sign a message. Any message can be signed.

  11. Q. What is to stop an untrusted party from becoming a CA?
    A. Anyone can become a CA. The award sponsors has to endorse a CA before it has any trust.

  12. Q. What happens if my cert get stolen?
    A. It doesn't matter. It is public information used to validate your signature. You can't anything bad with it.

  13. Q. What happens if my secret key get stolen?
    A. This is a problem. You will need to contact your CA to have them revoke it.

  14. Q. What is the down side of DSA signature?
    A. Public key signatures systems can be complex and hard to undertand. Our goal is to make it as simple as possible. The other down side is that public keys has to be certificated which requires a little effort.

  15. Q.   If digital signatures and certs are complex why force the users to use them?
    A.  The most complex issue that users will have to deal with is authenication.  Using PKI isn't what is complex.  Even if ARRL used a standard password model the authenication would be the same. 

  16. Q. Can paper cards have a DSA signature?
    A. Yes, it could be done with bar code or printed on the card, but there isn't any current plan to support paper cards.
  17. Q. Do I need to be connected to the Internet to sign QSLs?
    A. No. TrustedQSL can be signed and send by any means. Included but not limited to packet radio, floppy disk, CD-R/RW, Paper QSL cards.

  18. Q. Do I need to be connected to the Internet to validate tQSLs?
    A . No, you just need a trusted means to obtain the CAs certs.

  19. Q. What is Open Source? Why is it important to TrustedQSLs to be open source?
    A.   Open Source concept is where the copyright holder wishes that the source code be open to anyone to use.  There are different types of open source licenses.  Some open source licenses requires that any derived work also be open source.  TrustedQSL uses a much less restrictive licenses.  We want for proprietor software vendors to use our libraries and our licenses allows them to do so without a licenses fee or requirement to disclose their source code.  For tQSL to become the standard much the ADIF is for format, then nothing should kept vendors of software logbooks from using it. One way to do this is to make the source and the standard open. Anyone can use it without fee.

  20. Q. Your effort duplicates commercial product. Products such as Adobe Acrobat, while not free, do offer digital signatures with non-repudiation today. These are now legal to use in commerce.
    A. See last answer.

  21. Q. The system you propose is certainly open to fraud, in that a group of users could easily conspire. Perhaps this won't happen, but we've seen cases of this among VEs, which is troubling.
    A. It can happen. Another solution would be for a major groups such as the ARRL to become CAs. Any system will not be perfect. Just ask Verisign and Microsoft.

  22. Q.   Will ARRL and other award sponsors accept tQSL?
    A. TrustedQSL has been selected as the PKI for the ARRL LoTW. 
  23. Q. You guys are doing some cool stuff. Can I be apart of it?
    A.Sure join the TrustedQSL reflector and drop me a line wa1gon@arrl.net and tell me a little about yourself.

tqsl-2.0/html/trustedqsl/apiguide.html0000664000076400007640000000060312231073120020167 0ustar rmurphyrmurphy

TrustedQSL API Programming Guide

03/25/2001

The TrustedQSL API is a set libary to allow signing of messages.  Messages in digital signature terms is an unit of data that the princible wish to protect the intergity and be authenicated. 

tqsl-2.0/html/trustedqsl/adif.htm0000664000076400007640000031441012231073120017133 0ustar rmurphyrmurphy Amateur Data Interchange Format Specifications

Amateur Data Interchange Format 1.0

(ADIF)

Specifications

Ever since software has become a part of amateur radio, there have been as many data formats as there have been ham radio software programmers. Hams have struggled with converting data among various formats. Several hams have been discussing such a standard via an Internet discussion. In early 1996 KK7A promoted the idea of a standard for exchange of ham data. An internet reflector was set up for discussing such a standard. WF1B and WN4AZY, as publishers of commercial ham radio software, have taken the best suggestions from this discussion and formed a proposal. Ray introduced it at the 1996 Dayton hamvention. Within a year, this proposal has adapted adopted by most software publishers. We wish to thank everyone who has contributed to this effort.

ADIF is infinitely extensible--it will never be outgrown. It can handle binary as well as text data. New data elements may be added to this specification without "breaking" older implementations. It may be easily programmed in any language. The data itself is easily read by eye, and may implemented so as to be transferred via Internet without any encoding.

 

Purpose:

Provide a standard interchange independent of operating system or programming language for amateur data that will permit easy and direct transfer of data conforming to the standard between various amateur programs as well awards and contest sponsors.

 

Data to be Interchanged:

The ADIF standard must not be limited to log data. It should incorporate other categories such as awards multiplier lists, packet spot data, contest rules, etc., and must be expandable to incorporate any new type of data that may appear in the future as the hobby grows and changes. However, as of version 1.0, only specifications for log data have been implemented. Anyone wishing to interchange other types of data will still find these specifications helpful. All that is necessary to transfer other types of data is to apply to ADIF a definition of fields and records to be transferred.

 

ADIF components:

ADIF consists of three components:

1. Physical specifications--a specification of how fields and records are stored.

2. Field type definitions--Specification of how a particular type of data is stored. For instance, DATE should be stored with ASCII characters in the format YYYYMMDD. Examples of other possible data types are Numeric, Windows .BMP picture, binary data containing unspecified non-textual data, or freeform text containing multiple lines.

3. Field definitions--a list of data elements (Call, QSO Date, DXCC country, etc.), and a description of valid values. Each field has a name that is from one to ten characters long. The field name may include the characters A-Z, 0-9, and _, but must begin with a letter. (This is for easy transfer with xBase and other popular existing data formats).

4. File definitions--a description of a category of data. For instance, log data is defined as all data resulting from a QSO, including exchanged info plus any data related specifically to a QSO, such as band/mode, comments, traffic exchanged during the QSO, awards tracking info, and contest scoring info. A category will include a list of fields supported by the ADIF standard for each category. Each record in the file will contain one or more of the supported fields.

Additional fields that are not part of the ADIF specification for the file may be added by those creating ADIF files. This will permit export of user-defined fields. However, there is of course no guarantee that these undocumented fields will be imported by a program reading ADIF files, or that a chosen name may not be used for another purpose and imported into the wrong field in future ADIF specifications. Therefore, creators of ADIF files are encouraged to cooperate when adding new fields to so as to derive maximum benefit from ADIF.

 

1. Physical Specifications:

Each data field is preceded by a field name and length enclosed in angle brackets. The name and length are separated by a colon. The field name may be in upper, lower, or mixed case. Case is insignificant. For instance, CALL, Call, or call are equivalent. The length specification is ASCII text in display format, and may be of any non-negative value. The data follows the closing angle bracket. For example:

<CALL:6>WN4AZY

 

Records are made up of multiple fields and terminated with <EOR> or <eor> as an end-of-record marker. For example:

<call:6>WN4AZY<band:3>20M<mode:4>RTTY<qso_date:8>19960513<time_on:4>1305<eor>

 

An optional field type indicator may follow the field length, separated by a colon: For example:

<qso_date:8:d>19960513

 

The field type indicator may be in upper, lower, or mixed case. A field type indicator is optional. For instance, the Field Definition for QSO_DATE specifies that the field is always of type Date, so it is not necessary to repeat it here. However, when exporting user-defined fields that are not part of the ADIF specification, a type indicator will assist anyone attempting to import the data.

Any number of characters of any value except < may be added after a fields data or <eor> and before the start of the next field. This is typically carriage returns and/or line-feeds to make the file easier to read in a text viewer. For example:

<call:6>WN4AZY<band:3>20M<mode:4>RTTY
<qso_date:8:d>19960513<time_on:4>1305<eor>

<call:5>N6MRQ<band:2>2M<mode:2>FM
<qso_date:8:d>19961231<time_on:6>235959<eor>

 

In this example, a new line is inserted in the middle of each record, and two newlines are inserted at the end of each record. This makes long records easy to read in a text editor.

Optional header information may be included before the actual data in the file. To include optional header info, the first character of the file must be something other than <. Any amount of header info of any value except <eoh> may be included. The header info must be terminated with <eoh>. Any number of characters of any value except < may follow <eoh>. The first < after <eoh> is the start of the first field of the first data record in the file. Here is an example:

this data was exported using WF1B RTTY version 9, conforming to ADIF standard specification version 9.99<eoh>

<call:4>aa1a...

If the first character of a file is <, it is presumed to be the first field of the first data record.

The ADIF version may be included in the header info as follows: <adif_ver:4>1.00 is included as part of the header specification, an importing program can easily determine the ADIF version used to create the file. Note that this must not be at the beginning of the header info, because < as the first character indicates that there is no header.

It is important for the programmer importing ADIF data to note that any number of characters of any value may follow the actual data in a field. For example, carriage return/linefeed, or just a line feed. There is nothing in the specifications to prevent an exporter from placing a comment after the actual data. Therefore, after reading a fields data based on the length specification, the programmer should read and discard characters until the start of a new field (<) or <eor> is encountered.

There is no specification for the order in which fields appear. They may appear in any order. Unused fields may be omitted entirely. Therefore, each record will not necessarily have the same fields. The specification does not prohibit a zero-length field, so those writing import programs should allow for this.

There is no specification for field length or maximum field length in the Physical Specifications. Unless there is a length specification in the Field Definition, exporters simply export all data in their field. Importers import as much data as their program can accept.

Note that while these examples have all been of simple ASCII fields, the specification permits data of any type or length. It could be easily used to transfer pictures or text documents, for instance.

 

2. Field Type Definitions:

Type

Description

Date A date specification in YYYYMMDD format
   
Time A time specification. May be 6 characters long (HHMMSS) if seconds are included, 4 characters (HHMM) if seconds are not included. Time is in 24-hour format, from 0000 to 235959. A zero-length field or omission of the field indicates an empty time value.
   
M Multi-line text field. For xBase MEMO and similar data.
   
C (Character) So far everyone who has written an export program has not specified a type for character data. However, it is included in the specifications for consistency.

 

3. Field Definitions:

Name Type Comment
ADDRESS M As it will appear on the mailing label
AGE N  
ARRL_SECT C  
BAND C 160M, 80M, 40M, 30M, 20M, 17M, 15M, 12M, 10M, 6M, 2M, 70CM,23CM...see table below
CALL C  
CNTY C US County in the format STATE,COUNTY. For example GA,BARROW. Use CQ County list
COMMENT C Comment field for QSO
CONT C Continent: NA,SA,EU,AF,OC,AS
CONTEST_ID C Contest Indentifier -- SS, ARRLVHF, ARRLDX, etc.
CQZ N CQ Zone
DXCC N Numeric identifiers from ARRL. See table below
FREQ N in Megahertz
GRIDSQUARE C 4, 6, or 8 or however many characters
IOTA C HYPHEN MUST BE INCLUDED. Example: NA-001 IOTA PROVIDES DISK IN THIS FORMAT
ITUZ N ITU Zone
MODE C SSB,CW,RTTY,TOR,PKT,AM,FM,SSTV,ATV,PAC=PACTOR,CLO=CLOVER
NAME C  
NOTES M Long text for digital copy, third party traffic, etc.
OPERATOR C Callsign of person logging the QSO
PFX C WPX prefix
PROP_MODE C  
QSLMSG M Personal message to appear on qsl card
QSLRDATE D QSL Rcvd Date
QSLSDATE D QSL Sent Date
QSL_RCVD C Y=Yes, N=No, R=Requested, I=Ignore or Invalid
QSL_SENT C Y=Yes, N=No, R=Requested, I=Ignore or Invalid
QSL_VIA C  
QSO_DATE D YYYYMMDD in UTC
QTH C  
RST_RCVD C  
RST_SENT C  
RX_PWR N Power of other station in Watts
SAT_MODE C Satellite Mode
SAT_NAME C Name of satellite
SRX N Received serial number for a contest QSO
STATE C US state
STX N Transmitted serial number for a contest QSO
TEN_TEN N  
TIME_OFF C HHMM or HHMMSS in UTC
TIME_ON C HHMM or HHMMSS in UTC
TX_PWR N Power of this station in watts
VE_PROV C 2-letter abbreviations: AB, BC, MB, NB, NF, NS, NT, ON, PE, QC, SK, YT

Band designations:

Band Frequency
160m  
80m  
40m  
30m  
20m  
17m  
15m  
12m  
10m  
6m  
2m  
1.25m 220MHz
70cm 432
35cm 902
23cm 1300
13cm 2300
9cm 3300
6cm 5660
3cm 10000
1.25cm 24000
6mm 47 GHz
4mm 75
2.5mm 120
2mm 142
1mm 241
   

 

DXCC country codes:

Handling transfer of DXCC(tm) country info has been a common problem due to lack of an official list. The ARRL maintains everyone's DXCC status using numeric codes. We have adopted their codes for ADIF transfer of data. We wish to thank the ARRL for making this list available.

Code Country Deleted
1 CANADA  
2 ABU AIL IS Y
3 AFGHANISTAN  
4 AGALEGA & ST BRANDON  
5 ALAND IS  
6 ALASKA  
7 ALBANIA  
8 ALDABRA Y
9 AMERICAN SAMOA  
10 AMSTERDAM & ST PAUL  
11 ANDAMAN & NICOBAR IS  
12 ANGUILLA  
13 ANTARCTICA  
14 ARMENIA  
15 ASIATIC RUSSIA  
16 AUCKLAND & CAMPBELL  
17 AVES ISLAND  
18 AZERBAIJAN  
19 BAJO NUEVO Y
20 BAKER, HOWLAND IS  
21 BALEARIC IS  
22 BELAU (T8)  
23 BLENHEIM REEF Y
24 BOUVET  
25 BRITISH N. BORENO Y
26 BRITISH SOMALI Y
27 BELARUS  
28 CANAL ZONE Y
29 CANARY IS  
30 CELEBE/MOLUCCA IS Y
31 C KIRIBATI  
32 CEUTA & MELILLA  
33 CHAGOS  
34 CHATHAM IS  
35 CHRISTMAS IS  
36 CLIPPERTON IS  
37 COCOS ISLAND  
38 COCOS-KEELING IS  
39 COMOROS (FB8) Y
40 CRETE  
41 CROZET  
42 DAMAO, DUI Y
43 DESECHEO IS  
44 DESROCHES Y
45 DODECANESE  
46 EAST MALAYSIA  
47 EASTER IS  
48 EASTERN KIRIBATI  
49 EQUATORIAL GUINEA  
50 MEXICO  
51 ERITREA  
52 ESTONIA  
53 ETHIOPIA  
54 EUROPEAN RUSSIA  
55 FARQUHAR Y
56 FERNANDO DE NORONHA  
57 FRENCH EQ. AFRICA Y
58 FRENCH INDO-CHINA Y
59 FRENCH WEST AFRICA Y
60 BAHAMAS  
61 FRANZ JOSEF LAND  
62 BARBADOS  
63 FRENCH GUIANA  
64 BERMUDA  
65 BRITISH VIRGIN IS  
66 BELIZE  
67 FRENCH INDIA Y
68 SAUDI/KUWAIT N.Z. Y
69 CAYMAN ISLANDS  
70 CUBA ADIF:CM  
71 GALAPAGOS  
72 DOMINICAN REPUBLIC  
74 EL SALVADOR  
75 GEORGIA  
76 GUATEMALA  
77 GRENADA  
78 HAITI  
79 GUADELOUPE  
80 HONDURAS  
81 GERMANY Y
82 JAMAICA  
84 MARTINIQUE  
85 BONAIRE,CURACAO  
86 NICARAGUA  
88 PANAMA  
89 TURKS & CAICOS IS  
90 TRINIDAD & TOBAGO  
91 ARUBA  
93 GEYSER REEF Y
94 ANTIGUA & BARBUDA  
95 DOMINICA  
96 MONTSERRAT  
97 ST LUCIA  
98 ST VINCENT  
99 GLORIOSO IS  
100 ARGENTINA  
101 GOA Y
102 GOLD COAST/TOGOLND Y
103 GUAM  
104 BOLIVIA  
105 GUANTANAMO BAY  
106 GUERNSEY  
107 REPUBLIC OF GUINEA  
108 BRAZIL  
109 GUINEA-BISSAU  
110 HAWAII  
111 HEARD IS  
112 CHILE  
113 IFNI Y
114 ISLE OF MAN  
115 ITALIAN SOMALI Y
116 COLOMBIA  
117 ITU GENEVA  
118 JAN MAYEN  
119 JAVA Y
120 ECUADOR  
122 JERSEY  
123 JOHNSTON IS  
124 JUAN DE NOVA  
125 JUAN FERNANDEZ  
126 KALININGRAD  
127 KAMARAN IS Y
128 KARELO-FINN REP Y
129 GUYANA  
130 KAZAKHSTAN  
131 KERGUELEN  
132 PARAGUAY  
133 KERMADEC  
134 KINGMAN REEF  
135 KYRGYZSTAN  
136 PERU  
137 SOUTH KOREA  
138 KURE ISLAND  
139 KURIA MURIA IS Y
140 SURINAME  
141 FALKLAND IS  
142 LACCADIVE ISLANDS  
143 LAOS  
144 URUGUAY  
145 LATVIA  
146 LITHUANIA  
147 LORD HOWE IS  
148 VENEZUELA  
149 AZORES  
150 AUSTRALIA  
151 MALYJ VYSOTSKI IS (R1MV)  
152 MACAO  
153 MACQUARIE IS  
154 YEMEN ARAB REP Y
155 MALAYA Y
157 NAURU  
158 VANUATU  
159 MALDIVE IS  
160 TONGA  
161 MALPELO IS  
162 NEW CALEDONIA  
163 PAPUA NEW GUINEA  
164 MANCHURIA Y
165 MAURITIUS IS  
166 MARIANA IS  
167 MARKET REEF  
168 MARSHALL IS  
169 MAYOTTE  
170 NEW ZEALAND  
171 MELLISH REEF  
172 PITCAIRN IS  
173 MICRONESIA  
174 MIDWAY IS  
175 FRENCH POLYNESIA  
176 FIJI  
177 MINAMI TORISHIMA  
178 MINERVA REEF Y
179 MOLDAVIA  
180 MT ATHOS (SY)  
181 MOZAMBIQUE  
182 NAVASSA IS  
183 DUTCH BORNEO Y
184 NETHER N. GUNIEA Y
185 SOLOMON ISLANDS  
186 NEWFOUNDLAND/LAB Y
187 NIGER  
188 NIUE  
189 NORFOLK IS  
190 WESTERN SAMOA  
191 N COOK IS  
192 OGASAWARA  
193 OKINAWA Y
194 OKINO TORI-SHIMA Y
195 PAGALU (ANNOBAR IS)  
196 PALESTINE Y
197 PALMYRA & JARVIS IS  
198 PAPUA TERR Y
199 PETER I IS  
200 PORTUGUESE TIMOR Y
201 PRINCE EDWARD & MARION  
202 PUERTO RICO  
203 ANDORRA  
204 REVILLA GIGEDO  
205 ASCENSION ISLAND  
206 AUSTRIA  
207 RODRIGUEZ IS  
208 RUANDA-URUNDI Y
209 BELGIUM  
210 SAAR Y
211 SABLE ISLAND  
212 BULGARIA  
213 SAINT MARTIN (FJ)  
214 CORSICA  
215 CYPRUS  
216 SAN ANDREAS & PROVIDENCIA  
217 SAN FELIX  
218 CZECHOSLOVAKIA Y
219 SAO TOME & PRINCIPE  
220 SARAWAK Y
221 DENMARK  
222 FAROE IS  
223 ENGLAND  
224 FINLAND  
225 SARDINIA  
226 SAUDI/IRAQ N.Z. Y
227 FRANCE  
228 SERRANA BANK Y
229 GERMAN DEM. REP. Y
230 FED REP OF GERMANY  
231 SIKKIM Y
232 SOMALI  
233 GIBRALTAR  
234 S COOK IS  
235 SOUTH GEORGIA IS  
236 GREECE  
237 GREENLAND  
238 SOUTH ORKNEY IS  
239 HUNGARY  
240 SOUTH SANDWICH ISLANDS  
241 SOUTH SHETLAND ISLANDS  
242 ICELAND  
243 DEM REP OF YEMEN Y
244 SOUTHERN SUDAN  
245 IRELAND  
246 MALTA, SOVERIGN  
247 SPRATLY IS  
248 ITALY  
249 ST KITTS & NEVIS  
250 ST HELENA IS  
251 LIECHTENSTEIN  
252 ST PAUL ISLAND  
253 ST PETER & ST PAUL RKS  
254 LUXEMBOURG  
255 ST MAARTEN  
256 MADEIRA IS  
257 MALTA  
258 SUMATRA Y
259 SVALBARD IS  
260 MONACO  
261 SWAN ISLAND Y
262 TADZHIKISTAN  
263 NETHERLANDS  
264 TANGIER Y
265 NORTHERN IRELAND  
266 NORWAY  
267 TERR NEW GUINEA Y
268 TIBET Y
269 POLAND  
270 TOKELAU IS  
271 TRIESTE Y
272 PORTUGAL  
273 TRINDADE & MARTIN  
274 TRISTAN DA CUNHA  
275 ROMANIA  
276 TROMELIN  
277 ST PIERRE & MIQUELON  
278 SAN MARINO  
279 SCOTLAND  
280 TURKMENISTAN  
281 SPAIN  
282 TUVALU  
283 UK BASES ON CYPRUS  
284 SWEDEN  
285 VIRGIN IS  
286 UGANDA  
287 SWITZERLAND  
288 UKRAINE  
289 HQ UNITED NATIONS  
291 UNITED STATES  
292 UZBEKISTAN  
293 VIETNAM  
294 WALES  
295 VATICAN  
296 YUGOSLAVIA  
297 WAKE IS  
298 WALLIS & FUTUNA  
299 WEST MALAYSIA  
301 W KIRIBATI  
302 WESTERN SAHARA  
303 WILLIS IS  
304 BAHRAIN  
305 BANGLADESH  
306 BHUTAN  
307 ZANZIBAR Y
308 COSTA RICA  
309 MYANMAR  
312 KAMPUCHEA (CAMBODIA)  
315 SRI LANKA  
318 CHINA  
321 HONG KONG  
324 INDIA  
327 INDONESIA  
330 IRAN  
333 IRAQ  
336 ISRAEL  
339 JAPAN  
342 JORDAN  
345 BRUNEI  
348 KUWAIT  
354 LEBANON  
363 MONGOLIA  
369 NEPAL  
370 OMAN  
372 PAKISTAN  
375 PHILIPPINES  
376 QATAR  
378 SAUDI ARABIA  
379 SEYCHELLES  
381 SINGAPORE  
382 DJIBOUTI  
384 SYRIA  
386 TAIWAN  
387 THAILAND  
390 TURKEY  
391 UNITED ARAB EMIRATES  
400 ALGERIA  
401 ANGOLA  
402 BOTSWANA  
404 BURUNDI  
406 CAMEROON  
408 CENTRAL AFRICAN  
409 CAPE VERDE  
410 CHAD  
411 COMOROS (D6)  
412 CONGO  
414 ZAIRE  
416 BENIN  
420 GABON  
422 THE GAMBIA  
424 GHANA  
428 IVORY COAST  
430 KENYA  
432 LESOTHO  
433 NORTH KOREA (HP)  
434 LIBERIA  
436 LIBYA  
438 MADAGASCAR  
440 MALAWI  
442 MALI  
444 MAURITANIA  
446 MOROCCO  
450 NIGERIA  
452 ZIMBABWE  
453 REUNION  
454 RWANDA  
456 SENEGAL  
458 SIERRA LEONE  
460 ROTUMA IS  
462 SOUTH AFRICA  
464 NAMIBIA  
466 SUDAN  
468 SWAZILAND  
470 TANZANIA  
474 TUNISIA  
478 EGYPT  
480 BURKINA-FASO  
482 ZAMBIA  
483 TOGO  
488 WALVIS BAY Y
489 CONWAY REEF  
490 BANABA ISLAND  
492 YEMEN  
493 PENGUIN ISLANDS Y
497 CROATIA  
499 SLOVENIA  
501 BOSNIA-HERZEGOVINA  
502 MACEDONIA  
503 CZECH REPUBLIC  
504 SLOVAK REPUBLIC  
505 PRATAS IS  
506 SCARBOROUGH REEF  

 

4. File Definitions:

A log record is the data resulting from logging one QSO. ADIF does not specify a minimum required set of fields for log data. Although a record should contain at least :

Call
QSO_Date
Time_On
Band
Mode

it is permissible to export data with any of these items missing.

 

ADIF, xBase and other formats

As xBase languages and utilities are very popular (perhaps the most popular) for data handling applications, many parties to the ADIF proposal discussion favored using xBase files as the physical specification. However, this standard was not selected, since it is not easily used by those not using an xBase language, and lacks the flexibility and extensibility that ADIF features. However, a de-facto secondary xBase specification exists. Those wishing to use xBase files that will be compatible with each other may simply use ADIF field and record specifications.

We encourage development of public-domain utilities being made available that convert ADIF/xBase files as well as other popular data formats such as Lotus 123, Paradox, MS Access, etc.

 

Usage of ADIF and limitations

In order to maintain the integrity of ADIF and public confidence therein, these guidelines must be followed by anyone wishing to support ADIF.

ADIF may be freely used by any individual or organization, non-profit or commercial. Anyone claiming "ADIF compatibility" or "ADIF support", or other language with similar meaning, must be able to import and export ADIF data.

Of course data import is not necessary or desirable for all programs. For example, in the case of contesting-only packages, the user will probably want to export the contest data for use in a general logger, but not care about importing data. Authors of such packages shall state they provide "ADIF export compatibility" or "ADIF export support", or other language with similar meaning.

Writing a software package that imports ADIF but cannot export ADIF is not within keeping of the spirit and intent of ADIF. Such a package cannot truthfully claim to be ADIF compatible or to support ADIF. Authors of programs that only import must state that they support "ADIF import compatibility" or "ADIF import support", or language with similar meaning.

Packages that export and import ADIF may state that they support "ADIF import and export" or a similar phrase. However, any claims of ADIF support without any qualifiers shall mean that the program imports and exports.

Export programs shall be written in good faith so that the data will be of maximum usefulness to the user of the data. Products that export data in such a manner that its usefulness is limited, for example by exporting only a few fields or using non-standard formats or names for fields, cannot claim ADIF compatibility. Export programs should include all data in the file to be exported. If an author has fields that are not in the field list of the ADIF specification, he may export the fields by choosing the most obvious field name, and making a reasonable attempt to notify other ADIF supporters--for example via the ADIF mailing list reflector. In time there will probably be an official standards committee that will maintain the field list.

 

ADIF Mailing List Reflector and Web sites

Those with Internet email may participate in the ADIF discussion.

A number of amateurs have been discussing the difficulty in transferring QSO data between the various ham radio software packages that are available, and the desirability of having a standard format so that data can be easily transferred between any two programs. This mailing list has been set up to facilitate the formation of such a specification.

Any software developer or any ham who wishes to contribute to this discussion is welcome to participate.

You may subscribe to these mailing lists by filling out a form at the ADIF web page (http://www.hosenose.com/adif). You may also subscribe via email as described below.

To subscribe to the ADIF Mailing List, send a message to:

listserv@hosenose.com

In the SUBJECT field, enter

SUBSCRIBE ADIF

You will be sent a confirmation along with additional information within 24-48 hours of subscribing.

This web site also contains links to other publishers who support ADIF.

For any questions about this specification, contact us!

 

Ray Ortgiesen, WF1B
Wyvern Technology, Inc.
35 Colvintown Road
Coventry, RI 02816-8509

401-823-RTTY
401-822-0554 Fax
http://www.wf1b.com/
E-Mail: wf1b@wf1b.com
RTTY Contest Reflector: wf1b-rtty@wf1b.com

Publisher of the popular WF1B RTTY contesting program.

 

Dennis Hevener, WN4AZY
Personal Database Applications
1323 Center Dr.
Auburn, GA 30011-3318

770-307-1511
770-307-0760 Fax
pda@hosenose.com
http://www.hosenose.com/

Makers of LOGic ham radio software, SARTek universal antenna rotator interface, and other products for the computer in the shack.

10-Jun-1998 http://www.hosenose.com/adif/adif.html

tqsl-2.0/html/trustedqsl/GAbbI/0000775000076400007640000000000012231073120016417 5ustar rmurphyrmurphytqsl-2.0/html/trustedqsl/GAbbI/gabbi.htm0000664000076400007640000062672412231073120020216 0ustar rmurphyrmurphy Trusted GAbbI

Trusted GAbbI

(Global Amateur Interchange)

Format

May 20, 2002

Version 0.25

By Darryl Wagoner, WA1GON

wa1gon@arrl.net

and

Michael Keane, K1MK

k1mk@alum.mit.edu

2002 Trusted QSL and The American Radio Relay League

Discussion

A basic philosophy guiding data interchange is: “Be conservative in what you generate; be liberal in what you accept.” Following this precept, the affirmative obligation falls upon the sender to covert data, which may be stored in a local or proprietary format, into the specified  format for interchange prior to transmission to the recipient.

Thus, one will find in this document that the strictest  requirements for formatting and content are levied upon the GAbbI writer. A GAbbI reader on the other hand, is allowed to be more tolerant and less absolutist when applying these rules and deciding what constitutes valid data that it might  be willing to accept.

The  acceptance of non-compliant data is wholly at the discretion of the receiver. In addition  to  being liberal in what it accepts,  a GAbbI reader would be well advised to also keep in mind another principle when deciding how to dispose of malformed fields and records: “First, do no harm.”

1.   Physical Specifications

Files

       A logical file shall be composed of a  header area and a data area..

       The header area shall proceed the data area.

       The header area shall consist of zero or more records and be terminated by an end of header tag.

       The data area shall consist of zero or more records and be terminated by an end of file tag.

Records

       Records shall be composed of zero or more fields.

       Records shall be separated by record separator tags.

Character Set

       The "character set" shall be ISO/IEC 10646-1:2000 UCS ("Unicode Version 3.0")

       Default encoding of characters shall be UTF-8

       Readers may support UTF-16 encoding [TBR]

o      A GAbbI file object that is encoded in UTF-16 shall begin with a two octet signature of #xFEFF (Zero Width No-Break Space; Byte Order Mark)

       A compliant GAbbI reader shall check for the BOM signature. If the BOM signature is encountered indicating that the following file object is UTF-16 encoded and the reader cannot process UTF-16, the reader shall generate a fatal error

Fields

<Field_Name:Field_Length[:Field_Type]>Field_Value

E.g., <Call:4>K1MK

Field_Name — A sequence of one (1) to thirty-two (32) [TBR] characters from the set: [A-Za-z0-9/.?_+:=!@#$%^&*-] [TBR]. In determining equivalence and uniqueness Field_Names shall be treated as case insensitive,  i.e. CALL, call, Call  and CaLl are equivalent Field_Names.

Use of Field_Names beginning with the character sequences GABBI_ and SIGN_ shall be reserved for use in the specification. All other legal Field_Names may be used for local field definitions created by users.

Field_Length — Specification of the length of Field_Value in Unicode characters (not bytes or octets and not symbols or graphemes). The specification is a non-negative decimal integer with no leading zeros and shall be constructed from the characters [0-9].

Field_Type (Optional) A specification of the type of the field value. Treated as case insensitive.

Field_Value— A sequence of Field_Length characters that represents the value of the field.

Separator Tags

As with field names, separator tags shall be treated as case insensitive.

<eoh> — End of header area. <eoh> shall be present in every GAbbI file object. <eoh> signals the end of the header area and start of the data area.

<eor> — End of physical record.

<eof>— End of logical file. <eof> shall be present in every GAbbI file object. <eof> signals the end of the data area. Upon encountering <eof> a GAbbI reader shall reset its internal state; a new GAbbI header may follow immediately (or physical EOF may follow).

2. Field Type Definitions

Type

Designator

Description

Base64

6

Base 64 encoded number (binary string). Line length of base64 encoded objects shall be limited to 72 characters and lines shall be broken by use of end-of-line character(s). Legal characters that may appear in the value field are [A-Za-z0-9./=].

Binary

B

Fixed point (integer) number in base 210 (binary) representation. Written in big-endian order, starting with most significant bit. Legal characters that may appear in the value field are [0-1-].

Character

C

Character string. Valid characters that may appear in the value field are the set of displayable characters (printable characters plus <SP> and <HT>). [TBR]

Date

D

Date in ISO 8601 format. Extended format i.e., YYYY-MM-DD , is preferred but basic format, YYYYMMDD, is permissible but its use is deprecated. Valid characters that may appear in the value field are [0-9-][1] .

Enumeration

E

A character string from an enumerated list of character strings. The comparison of a Field_Value to an enumerated value is case insensitive. Valid characters that may appear in the value field are the set of displayable characters (printable characters plus <SP> and <HT>). [TBR]

Floating Point

F

Floating-point number in base 1010 (decimal) representation. Legal characters that may appear in the value field are [0-9.-].

Hexadecimal

H

Fixed point (integer) number in base 1610 (hexadecimal) representation. Legal characters that may appear in the value field are [0-9A-F-].

Integer

I

Fixed point (integer) number in base 1010 (decimal) representation. Legal characters that may appear in the value field are [0-9-].

Multi-Line

M

Character string. Legal characters that may appear in the value field are displayable characters. An implementation independent end-of-line delimiter (the two character sequence <CR><NL>) shall be transmitted to signal logical line breaks. [TBR]

Numeric

N

A general format number. Use of N is deprecated; field types IBOH or F are the preferred alternatives.

Octal

O

Fixed-point (integer) number in base 810 (octal) representation. Legal characters that may appear in the value field are [0-7-].

Time

T

Time in ISO 8601 format. Extended format i.e., hh:mm:ssZ is preferred, but basic format, hhmmssZ, and basic format with reduced precision, hhmmZ, are also permissible. Should the time zone designator ‘Z’ be omitted, UTC shall be assumed. Legal characters that may appear in the value field are [0-9A-Z:].

3. Field Definitions

tCERT (Identity certificate) Record

Each GAbbI file shall contain at least one tCERT record. 

Name

Type

Required

Max Size (chars)

Description

CERTIFICATE

6

Y

2048

X.509 v3 identity certificate. Base64 encoded distinguished encoding representation (DER) of the certificate. 

CERT_UID

I

Y

1

A one digit locally unique identifier (UID) for this tCERT record. Unique within a GAbbI logical file.

REC_TYPE

E

Y

10

Always "tCERT". This declares the record to be an identity certificate record.

tCONTACT (Trusted Contact) Record

The tCONTACT record contains information that is unique to a specific contact. Note that most of the fields are required. This is because these fields can be expected to differ for each contact. For the sake of transmission and reception efficiency, the information that is shared in common by several contacts is grouped together and placed into a tSTATION record. The information contained in the tSTATION record is included in the virtual QSL record by means of the STATION_GUID field. Each GAbbI file shall contain at least one tCONTACT record. 

Name

Type

Required

Category

Max Size (chars)

Description

BAND

E

Y

 

6

The band on which contact took place. Describes a two-way (non-crossband) contact[2]. Format for interchange is the band designation in upper case See Table 1 for a list of the legal values for the enumeration.

CALL

C

Y

 

15

The call sign of station contacted. Call sign is insensitive to case. Legal values for characters that may appear in a call sign are [A-Z0-9/].

CERT_UID

I

Y

 

1

This is a one digit locally unique identifier (UID) of  the tCERT record containing a copy of  the certificate used to sign the logical record. Unique within a GAbbI logical file.

FREQ

F

N

 

8

Frequency. Describes a two-way (non-crossband) contact[3] . Format for interchange shall be frequency in MHz with no greater than 100 mHz precision. A decimal point shall be included. There shall be no leading zeros; there shall be no trailing zeroes after the last significant digit. 

If the precise frequency is unknown use the Frequency listed in Table 1 for the band may be used.

MODE

E

Y

 

6

Mode. Describes a two-way (non-crossmode) contact. Format for interchange is the mode identifier in upper case. See Table 2 for a list of the legal values for the enumeration.

QSL

E

N

 

3

A value of “PSE” shall indicate that a confirmation is requested in reply; a value of “TNX” shall indicate that a response is not necessary

QSO_DATE

D

Y

 

8

Date in ISO 8601 format. Extended format i.e., YYYY-MM-DD, is the preferred format. Basic format, YYYYMMDD, is permissible but its use is deprecated

QSO_TIME

T

Y

 

9

UTC Time in ISO 8601 format. Extended format, hh:mm:ssZ, is the preferred format. Both basic format, hhmmssZ, and basic format with reduced precision, hhmmZ, are permissible but their use is deprecated. In the event that the time zone designator ‘Z’ is omitted, UTC shall be assumed

REC_TYPE

E

Y

 

10

Always "tCONTACT". This declares the record to be a Trusted Contact record.

REMARKS

M

N

 

256

Operator remarks regarding this contact.

RST_SENT

C

N

 

8

Signal Report Sent. Comparison of values of RST_SENT is insensitive to case. 

SIGN_LOTW_V1.0

6

Y

Signature

172

This is the ARRL LOTW v1.0 digital signature of this record. See Appendix A for the specific of this signing rule. Maximum field size based on 1024-bit key and base64 encoding

STATION_UID

I

Y

 

2

This is a two digit (locally) Unique Identifier (UID) of the tSTATION record associated with this tCONTACT record. Unique within a GAbbI logical file.

tHEADER (GAbbI Header) Record

The tHEADER record is optional but one GAbbI header record should be present in each GAbbI file.

Name

Type

Required

Max Size (chars)

Description

CATEGORY

E

Y

4

Declares category of data in this file. To indicate trusted (digitally signed) QSL data the value of CATEGORY shall be "tQSL"

GAbbI_#_CONTACT_RECS

I

N

4

Number of tCONTACT records that can be expected to follow in this logical file. Use is optional, but if present, the value shall be correct. Reader may issue an error message if the number of valid tCONTACT records received is different from the value declared in the header 

GAbbI_#_STATION_RECS

I

N

2

Number of tSTATION records that can be expected to follow in this logical file. Use is optional, but if present, the value shall be correct. Reader may issue an error message if the number of valid tSTATION records received is different from the value declared in the header 

GAbbI_CREATED_BY

C

N

64

Name and version of program creating this file.

GAbbI_CREATED_ON

C

N

20

ISO 8601 Date & Time that file was created.

GAbbI_MESSAGE_DIGEST

E

N

5

Message digest algorithm: SHA-1 (default) or MD5[5].

GAbbI_SENDER

C

N

15

The call sign of station creating the file. SENDER may differ from the value of the CALL field in tSTATION records in certain cases, such as a QSL Manager

GAbbI_SIGN_ALOGORITHM

E

N

5

Digital signature key type algorithm: RSA (default), DSA or ECDSA[5]

GAbbI_VERSION

C

Y

4

GAbbI version

REC_TYPE

E

Y

10

Always "tHEADER". This declares the record to be a GAbbI header record.

tSTATION (Trusted Station) Record

The tSTATION record contains information that is common to a set of logical QSL records; each logical QSL record provides the trusted (signed) set of information needed to confirm a QSO. Each GAbbI file shall contain at least one tSTATION record

When a field appears in a tSTATION record, it specifies the default value for the field in each logical record, which references a tSTATION record via the STATION_GUID field.  In constructing the logical QSL record from the tSTATION and tCONTACT records, the order of precedence shall be: appearance of a field in the tCONTACT record will supersede any default value for that field that may have been established by the appearance of the same field in the linked tSTATION record. 

Name

Type

Required

Category

Max Size (chars)

Description

CALL

C

Y

 

15

Call sign used by the station reporting this contact. Call sign is insensitive to case. Legal value for call sign characters are [A-Z0-9/].

CL_CITY

E

N

Sub_Gov3

6

Chilean Municipality (“Comuna”). Format for interchange shall be the 5 or 6  digit code for the municipality. Consult list. from Federachi for the legal values of the enumeration.

CONT

E

N

 

2

Continent. Format for interchange shall be the two-letter abbreviation in upper case. See Table 5 for legal values of the enumeration.

CQZ

E

N

 

2

CQ Zone. Format for interchange shall be two numeric characters and must include any leading zero. (01  CQZ  40)

CZ_DISTRICT

E

N

 

3

Czech district (“okres”). Interchange format is a three letter abbreviation; consult list from CRC for the legal values of the enumeration.

DIG

I

N

 

5

Diplom Interessen Gruppe (DIG) member number.

DOK

E

N

 

3

DARC District Location Code (DOK). DOK is a three (3) character string consisting of one (1) alpha character [A-IK-Z] and two (2) digits (see DARC list).

DXCC

E

Y

 

3

ARRL DX Century Club. Numeric identifiers from the ARRL. Format for interchange shall be three digits and must include any leading zeroes. See Table 6 for legal values.

EMAIL_ADDRESS

C

N

 

64

Electronic mail address to use for contacting this station or operator

GRIDSQUARE

C

N

 

6

Either the 4 character or the 6 character Maidenhead grid square designator is acceptable. Format for interchanges shall be AANN and AANNaa. Comparison of values of GRIDSQUARE is insensitive to case. For stations located on grid intersections, multiple instances of the  GRIDSQUARE field may appear in a single  tSTATION record, up to a maximum of four.

IOTA

E

N

 

6

RSGB Islands on the Air (IOTA) Program reference number. Format for interchange shall be six characters consisting of a two-letter continental abbreviation in upper case immediately followed by a hyphen immediately followed by three numeric characters that must include any leading zeroes. Comparison of IOTA designators shall be case insensitive. Consult the RSGB IOTA Program reference numbers list for legal values of the enumeration.

ITUZ

E

N

 

2

ITU Zone. Format for interchange shall be two numeric characters and must include any leading zero. (01  ITUZ 75)

JAG

I

N

 

5

Japan Award Hunters Group member number

JP_CITY

E

N

Sub_Gov2

4

Japanese city ("shi"). Format for interchange is the JCC reference number for the city from JARL list: four numeric digits including any leading zeros. N.B.: JARL’s internal numbering scheme for prefectures differs from ISO 3166-2.

JP_GUN

E

N

Sub_Gov2

5

Japanese gun (county). Format for interchange is the JCG reference number for the gun from JARL list: five numeric digits including any leading zeros. N.B.: JARL’s internal numbering scheme for prefectures differs from ISO 3166-2.

LOCATION

C

N

 

64

Geographical location[6]of the station. E.g., “Summit of Mt. Mitchell”, “Santa Catalina Island”, “Parque Nacional  Torres del Paine”

MAILING_ADDRESS

M

N

 

256

Postal Mailing address to contact this station; should be internationalized

NZ_COUNTY

E

N

Sub_Gov2

5

New Zealand county. Format for interchange is the NZ county as enumerated in FIPS Pub. 10-4.

OPERATOR

C

N

 

15

Operator of the station given in CALL field of the tSTATION record. Typically this field would be used for a guest operator or multiple operators using a single call sign. Call sign is insensitive to case. Legal value for call sign characters are [A-Z0-9/].

POSTAL_CODE

C

N

 

10

National postal code (for use as an awards counter).

REC_TYPE

E

Y

 

10

Always "tSTATION". This declares the record to be a Trusted Station record.

REPEATER[8]

C

N

 

15

Call sign of terrestrial repeater used in making this contact. Call sign is insensitive to case. Legal values for call sign characters are [A-Z0-9/].

RIG

M

N

 

256

Description of radios, antennas, ancillary equipment, etc.

SAT_MODE[7]

E

N

 

5

Format for interchange shall be the designator for satellite transponder mode, e.g. A, B, J… If the SAT_MODE field is present, the SAT_NAME  field shall also be present. See Table 7 for legal values of the enumeration.

SAT_NAME

E

N

 

5

Format for interchange shall be the designation of the satellite used in upper case (RS-10, AO-10, FO-20, etc.). See Table 7 legal values of the enumeration.

SDOK

C

N

 

8

DARC Sonder-DOK. Distinctive (or “special”) DOK, for special events, is a string of up to 8 characters (see DARC  list, frequently updated)

SK_DISTRICT

E

N

 

3

Slovak district (“okres”). Interchange format is a three letter abbreviation; consult list from CRC for the legal values of the enumeration.

SUB_GOV1

E

N

Sub_Gov1 

6

The top-level administrative subdivision of a country as specified in ISO 3166-2:1998. The SUB_GOV1 subdivision might be a State (USA), a Province (Canada; Spain), an Oblast (Russia), a Canton (Switzerland), a County (Great Britain; Ireland), a Prefecture (Japan), etc. The enumeration of this subdivision shall be as given in ISO 3166-2.

In instances where no administrative subdivision is specified in ISO 3166-2, the administrative subdivision and its enumeration listed in  FIPS Pub. 10-4 may be substituted, if one exists. An enumerated value from FIPS Pub. 10-4 is distinguishable from an ISO 3166-2 enumerated value by the absence of a hyphen (‘-‘)  in the FIPS Pub. 10-4 enumerated value and the presence of a hyphen (‘-‘)  in the ISO 3166-2 enumerated value.

SUB_GOV2

C

N

 Sub_Gov2

64

The administrative subdivision that is “subordinate” to  the subdivision in SUB_GOV1. Examples of SUB_GOV2 are a County/Parish (USA), a Gun (Japan), a City (Japan), etc. The value of SUB_GOV2 is a non-enumerated character string that shall be treated as case insensitive. If a record contains the field SUB_GOV2, then the record shall also contain the filed SUB_GOV1. One or more fields of category Sub_Gov2 may appear within a single record.

SUB_GOV3

C

N

 Sub_Gov3

64

The administrative subdivision that is “subordinate” to the subdivision in SUB_GOV2. Examples include Municipality (Chile), City, Town ,Village, etc. The value of SUB_GOV3 is a non-enumerated character string that shall be treated as case insensitive. If a record contains the SUB_GOV3 field, then the SUB_GOV1 field shall be present and one or more fields of category Sub_Gov2 may be present in the record. One or more fields of category Sub_Gov3 may appear in a single record.

STATION_TYPE

E

N

 

12

See Table 8 for legal values of the enumeration.

STATION_UID

I

Y

 

2

This is a two digit (locally) Unique ID (UID) of this tSTATION record. Unique within a GAbbI logical file.

TX_PWR

F

N

 

8

Transmitter power. Format for interchange shall be transmitter output power in watts (W) with no greater than 1 mW precision. A decimal point shall be included. There shall be no leading zeros; there shall be no trailing zeroes after the last significant digit. 

URL

C

N

 

256

Universal Resource Locator (URL) that will provide further information on this station. 

US_COUNTY

E

N

Sub_Gov2

5

US County. The value is a five (5) character  code composed of the two-letter state alpha code from FIPS Pub. 5-2 followed by  the three digit numeric code for the county (or independent city) from FIPS Pub. 6-4. E.g., Autauga County, Alabama is represented as AL001 and Apache County, Arizona is represented as AZ001. For stations located on a county line, two instances of the US_COUNTY  field may appear within a tSTATION or tCONTACT record.

WAE

E

N

 

3

Worked All Europe entity. Three digit numeric identifier from DARC WAE list

Common Fields

This field is common to all record types. The field is identical both in its name and its meaning to more than one record type. 

Name

Type

Required

Max Size (chars)

Description

REC_TYPE

E

N

15

This defines the type of record. The default is QSO record

4. File Definition

Record Types

Record 

Description

tCERT

Identity certificate. This record shall be placed in the header area preceding  the <eoh> tag. 

tCONTACT

This record contains the unique information describing a QSO. All tCONTACT records shall be in the data area, following the <eoh> tag. 

tHEADER

This indicates a logical header record. This record shall be placed in the header area preceding the <eoh> tag. 

tSTATION

This record contains the common information describing a series of QSOs. Typically, this is information that describes the sender and his/her station. All tSTATION records shall be placed in the header area preceding the <eoh> tag. 

QSO

This is also the standard logbook format. All QSO records shall be in the data area, following the <eoh> tag. To maintain backward compatibility, this is the default record type.

Categories

Implicit rules are associated with some fields; at least one extra parameter (in addition to Type, Signed, Required & Maximum Size) must be provided in order to specify fields that fall into these categories: 

Name

Super-Category

Sub-Category

Parameters

Sub_Gov2

Sub_Gov1

Sub_Gov3

If a field  in the Sub_Gov2 category is of Enumeration (E) type, a list of the enumerated values shall be provided. Each enumerated value for a field  in the Sub_Gov2 category shall be associated with an enumerated value in a field of the superior category (Sub_Gov1). 

Sub_Gov3

Sub_Gov2

or

Sub_Gov1

If a field  in the Sub_Gov3 category is of Enumeration (E) type, a list of the enumerated values shall be provided. Each enumerated value for a field  in the Sub_Gov3 category shall be associated with an enumerated value in field of a super-category (Sub_Gov2 or Sub_Gov1). 

Signature

A specific signing rule (which fields are signed; in what order do fields appear) must be specified.

Sub_Gov1, Sub_Gov2 & Sub_Gov3

The fields which describe administrative subdivisions constitute an implicit hierarchy beginning at the level of DXCC entity:

+---DXCC|
     +---Sub_Gov1
            |
            +---Sub_Gov2
                   |
                   +---Sub_Gov3

If a GAbbI writer specifies the value for a field from the "Sub_Gov" hierarchy, the writer shall also specify a fully consistent set of values for all the superior fields in the hierarchy up to and including DXCC entity.

A reader shall treat the appearance of a single field from the "Sub_Gov" hierarchy as an implicit specification of a value for each of the superior fields in the hierarchy up to and including DXCC entity. E.g.US_COUNTY == HI001 (Hawaii County) should be interpreted by a reader as specifying SUB_GOV1 == US-HI (State of Hawaii) and DXCC == 110 (Hawaii) in addition to the county; and JP_CITY == 2701 (Kobe) should be read as specifying SUB_GOV1 == JP-28  (Hygo Prefecture) and DXCC == 339 (Japan) in addition to the city. When more than one field in the "Sub_Gov" hierarchy appears in a record, the values specified implicitly and explicitly at every level of the hierarchy shall be identical. In the event an inconsistency amongst the fields of the "Sub_Gov" hierarchy is detected, the reader shall issue an error message and may discard the record.

The values of the SUB_GOV2 and SUB_GOV3 fields  are non-enumerated character strings. Enumerations for administrative subdivisions below the top-level are typically not found in standardized sources such as ISO 3166-2 and FIPS Pub. 10-4. Field which are members of category Sub_Gov2 and category Sub_Gov3 and which have an enumerated field value shall have a uniquely distinguished field name that shall begin with the ISO 3166-1:1997 alpha-2 (two-letter) code element followed by an underscore ("_").

GAbbI Sample File


[1]Illegal characters encountered while scanning a field are to be ignored. The field length shall be interpreted as the number of valid characters to be read. If while scanning a field, the reader encounters an illegal character other than an end-of-line character (<CR> or <NL>), the reader shall issue a warning. If a start of field delimiter ‘<’ is encountered before the expected end of field, the reader shall reject the field being read and issue a warning. 

N.B.: GAbbI is only weakly armored against line folding and provides no protection at all against gratuitous character re-mapping that can be introduced by the transport layer, especially e-mail. A prudent precaution would be to encode a GAbbI object using base64 prior to transport via e-mail. This encoding is mandatory if UTF-8 characters beyond the 7-bit ASCII character set are to be exchanged. 

[2] To indicate a cross-band contact the pair of fields: BAND_RX and BAND_TX shall be used. If the BAND field appears in a record then neither BAND_RX nor BAND_TX may appear. If either the BAND_RX or BAND_TX field appears, then both fields must appear. 

[3] To indicate a split-frequency contact the pair of fields: FREQ_RX and FREQ_TX shall be used. If the FREQ field appears in a record then neither FREQ_RX nor FREQ_TX may appear. If either the FREQ_RX or FREQ_TX field appears, then both fields must appear.  All cross-band contacts are split-frequency; not every split-frequency contact is crossband.

[4] To indicate a cross-mode contact the pair of fields: MODE_RX and MODE_TX shall be used. If the MODE field appears in a record then neither MODE_RX nor MODE_TX may appear. If either the MODE_RX or MODE_TX field appears, then both fields must appear. 

[5] A compliant GAbbI reader shall support SHA-1 message digest and RSA signatures. Readers may optionally support the MD5 message digest and/or DSA and ECDSA signatures. The GAbbI header declarations cue the reader on which algorithms will be used in the file. Which combination of digest and key type were actually used for a given signature is implicitly specified via the SIGN_XXX family of fields on a signature-by-signature basis. If a reader is presented with data signed using a public key algorithm that the reader does not support, the reader shall generate a fatal error. 

[6]”Geographic location” should not correspond to a specific governmental or administrative subdivision such as a  town or village. Location within an administrative subdivision should be indicated by use of one or more “SUB_GOV#” fields. 

[7] If needed for an explicit declaration, the non-callsign value of "NONE" for REPEATER shall be permitted. 

[8] Setting SAT_MODE equal to  "EME" shall indicate an Earth-Moon-Earth (moonbounce) contact. The corresponding SAT_NAME shall be "MOON".

 

tqsl-2.0/html/trustedqsl/GAbbI/TableStation_Types.htm0000664000076400007640000001045712231073120022715 0ustar rmurphyrmurphy Station Types

Table 8 – Station Types

Station Type

Description

AERONAUTICAL

An aeronautical station is located aboard an aircraft and is operated while the aircraft is airborne. 

LAND

A land station is located on land whether fixed or mobile.

MARITIME

A maritime station located on board a ship or boat on the water, whiter the vessel is at anchor or underway, within sovereign territorial waters or on the high seas. 

 

tqsl-2.0/html/trustedqsl/GAbbI/TableSatellites.htm0000664000076400007640000007467012231073120022230 0ustar rmurphyrmurphy Satellites & Modes

Table 7 – Satellite & Mode Designations

 


Satellite

Mode(s)

AO-3

2

AO-4

J

AO-6

A

AO-7

A, B

AO-8

A, J

AO-10

B

FO-12

JD

AO-13

B, S

UO-14

B

AO-16

JD

WO-18

JD

LO-19

JD

FO-20

JA, JD

AO-21

JA, JD

UO-22

JD

KO-23

JD

AO-24

B, S

KO-25

JD

IO-26

JD

AO-27

B

PO-28

JD

FO-29

JA, JD

MO-30

JD

TO-31

JD

SO-35

BD, JD

UO-36

JD

AO-40

U/S2, L/S2

U/S1, L/S1

SO-41

JD

SO-42

JD

MO-46

JD

RS-1

A

RS-2

A

RS-5

A

RS-6

A

RS-7

A

RS-8

A

RS-10

A

RS-11

A

RS-12

A, T, KA, KT

RS-13

A, T, KA, KT

RS-15

A

RS-14

JA, JD


 


 

tqsl-2.0/html/trustedqsl/GAbbI/TableModes.htm0000664000076400007640000013602112231073120021153 0ustar rmurphyrmurphy TableModes

Table 2 - Mode Designations

Code

Mode

ITU-R

Notes

AM

Double-sideband amplitude modulated telephony

A3E

 

AMTOR

Amateur Teleprinting Over Radio

J2B or F1B

BFSK

ATV

Fast Scan Television

A3F

 

CLOVER

Clover

500HJ2B

 

CLOVR2

Clover II

 

 

CW

Continuous wave telegraphy

A1A

 

DATA

Digital

3rd letter B

 

FAX

Facsimile

3rd letter C

 

FM

Frequency modulated telephony

F3E

 

FSK31

FSK31

J2E or F1B

 BPSK

FSK441

WSJT meteor scatter mode

J2B

4-FSK

GTOR

Golay-TOR (G-TOR)

 J2B

 

HELL

Hellschreiber

J2C or A1C

 

IMAGE

TV or FAX

3rd letter C or F

 

JT44

WSJT moonbounce mode

J2B

44-FSK

MFSK16

Multiple Frequency Shift Keying

316HJ2B

16-FSK

MFSK8

Multiple Frequency Shift Keying

J2B

32-FSK

MS188

MIL-STD 188-110B

J2B

39-OFDM DQPSK

MT63

MT-63

1KJ2B

64-OFDM BDPSK

MTTY

Minimum Shift Keying (MSK) RTTY

J2B or F1B

 BFSK

PACKET

Packet

J2B or F1B

BFSK

PACTOR

PACTOR

J2B or F1B

BFSK

PACTR2

PACTOR II

J2B

2-OFDM DQPSK

PHONE

Voice telephony

3rd letter E

 

PSK125

PSK125F

J2B

 

PSK31

PSK31

J2B or G1B

 

PSK63

PSK63F

100HJ2B

BPSK

Q15X25

Q15X25 (NEWQPSK)

J2B

15-OFDM DQPSK

QPSK31

Quadrature PSK31

J2B or G1B

QPSK

RTTY

Baudot Radioteletype

F1B or J2B

 

S4285

NATO STANdardization AGreement (STANAG) 4285

 J2B

MFSK

SSB

Single-sideband, suppressed carrier telephony

J3E

 

SSTV

Slow Scan Television

J2F

 

THORB

THROB

J2B

9-FSK

 

tqsl-2.0/html/trustedqsl/GAbbI/TableDXCC.htm0000664000076400007640000067207712231073120020645 0ustar rmurphyrmurphy Table DXCC

Table 6 - DXCCTM Entity Codes


Code

Country

3

Afghanistan

4

Agalega & St. Brandon

5

Aland Islands

6

Alaska

7

Albania

400

Algeria

9

American Samoa

10

Amsterdam & St. Paul

11

Andaman & Nicobar Islands

203

Andorra

401

Angola

12

Anguilla

195

Annobar Island

(Pagalu)

13

Antarctica

94

Antigua & Barbuda

100

Argentina

14

Armenia

91

Aruba

205

Ascension Island

15

Asiatic Russia

16

Auckland & Campbell

Austral Islands

150

Australia

206

Austria

17

Aves Island

18

Azerbaijan

149

Azores

60

Bahamas

304

Bahrain

20

Baker & Howland Islands

21

Balearic Islands

490

Banaba Island

305

Bangladesh

62

Barbados

27

Belarus

22

Belau

209

Belgium

66

Belize

416

Benin

64

Bermuda

306

Bhutan

104

Bolivia

85

Bonaire, Curacao

(Netherlands Antilles)

501

Bosnia-Herzegovina

402

Botswana

24

Bouvet

108

Brazil

65

British Virgin Islands

345

Brunei

212

Bulgaria

480

Burkina-Faso

404

Burundi

31

C Kiribati

(Br. Phoenix Is.)

406

Cameroon

1

Canada

29

Canary Islands

409

Cape Verde

69

Cayman Islands

408

Central Africa

32

Ceuta & Melilla

410

Chad

33

Chagos

34

Chatham Island

Chesterfield Islands

112

Chile

318

China

35

Christmas Island

36

Clipperton Island

37

Cocos Island

38

Cocos-Keeling Islands

116

Colombia

411

Comoros

412

Congo

489

Conway Reef

214

Corsica

308

Costa Rica

40

Crete

497

Croatia

41

Crozet

70

Cuba

215

Cyprus

503

Czech Republic

221

Denmark

43

Desecheo Island

382

Djibouti

45

Dodecanese

95

Dominica

72

Dominican Republic

433

DPR of Korea

Ducie Island

48

E. Kiribati (Line Is.)

46

East Malaysia

47

Easter Island

120

Ecuador

478

Egypt

74

El Salvador

223

England

49

Equatorial Guinea

51

Eritrea

52

Estonia

53

Ethiopia

54

European Russia

141

Falkland Islands

222

Faroe Islands

230

Fed Rep Of Germany

56

Fernando De Noronha

176

Fiji

224

Finland

227

France

61

Franz Josef Land

63

French Guiana

175

French Polynesia

420

Gabon

71

Galapagos

75

Georgia

424

Ghana

233

Gibraltar

99

Glorioso Islands

236

Greece

237

Greenland

77

Grenada

79

Guadeloupe

103

Guam

105

Guantanamo Bay

76

Guatemala

106

Guernsey

109

Guinea-Bissau

129

Guyana

78

Haiti

110

Hawaii

111

Heard Island

80

Honduras

321

Hong Kong

289

HQ United Nations

239

Hungary

242

Iceland

324

India

327

Indonesia

330

Iran

333

Iraq

245

Ireland

114

Isle Of Man

336

Israel

248

Italy

117

ITU Geneva

428

Ivory Coast

82

Jamaica

118

Jan Mayen

339

Japan

122

Jersey

123

Johnston Island

342

Jordan

124

Juan De Nova

125

Juan Fernandez Islands

126

Kaliningrad

312

Kampuchea

(Cambodia)

130

Kazakhstan

430

Kenya

131

Kerguelen Islands

133

Kermadec

134

Kingman Reef

138

Kure Island

348

Kuwait

135

Kyrgyzstan

142

Laccadive Islands

143

Laos

145

Latvia

354

Lebanon

432

Lesotho

434

Liberia

436

Libya

251

Liechtenstein

146

Lithuania

147

Lord Howe Island

254

Luxembourg

152

Macao

502

Macedonia

153

Macquarie Island

438

Madagascar

256

Madeira Islands

440

Malawi

159

Maldive Island

442

Mali

161

Malpelo Island

257

Malta

246

Malta, Soverign

151

Malyj Vysotski Island 

166

Mariana Islands

167

Market Reef

Marquesas Islands

168

Marshall Islands

84

Martinique

444

Mauritania

165

Mauritius

169

Mayotte

171

Mellish Reef

50

Mexico

173

Micronesia

174

Midway Island

177

Minami Torishima

179

Moldovia

260

Monaco

363

Mongolia

96

Montserrat

446

Morocco

181

Mozambique

180

Mt. Athos

309

Myanmar

191

N Cook Islands

464

Namibia

157

Nauru

182

Navassa Island

369

Nepal

263

Netherlands

162

New Caledonia

170

New Zealand

86

Nicaragua

187

Niger

450

Nigeria

188

Niue

189

Norfolk Island

265

Northern Ireland

266

Norway

192

Ogasawara

370

Oman

372

Pakistan

Palestine

197

Palmyra & Jarvis Islands

88

Panama

163

Papua New Guinea

132

Paraguay

136

Peru

199

Peter I Island

375

Philippines

172

Pitcairn Island

269

Poland

272

Portugal

505

Pratas Island

201

Prince Edward & Marion Islands

202

Puerto Rico

376

Qatar

107

Republic Of Guinea

137

Republic of Korea

453

Reunion

204

Revilla Gigedo

207

Rodriguez Island

275

Romania

460

Rotuma Island

454

Rwanda

234

S Cook Islands

211

Sable Island

213

Saint Martin

216

San Andreas & Providencia

217

San Felix

278

San Marino

219

Sao Tome & Principe

225

Sardinia

378

Saudi Arabia

506

Scarborough Reef

279

Scotland

456

Senegal

379

Seychelles

458

Sierra Leone

381

Singapore

504

Slovak Republic

499

Slovenia

185

Solomon Islands

232

Somali

462

South Africa

235

South Georgia Island

238

South Orkney Islands

240

South Sandwich Islands

241

South Shetland Islands

244

Southern Sudan

281

Spain

247

Spratly Islands

315

Sri Lanka

250

St. Helena Island

249

St. Kitts & Nevis

97

St. Lucia

255

St. Maarten

252

St. Paul Island

253

St. Peter & St. Paul Rocks

277

St. Pierre & Miquelon

98

St. Vincent

466

Sudan

140

Suriname

259

Svalbard Island

468

Swaziland

284

Sweden

287

Switzerland

384

Syria

262

Tadzhikistan

386

Taiwan

470

Tanzania

Temotu Province

387

Thailand

422

The Gambia

483

Togo

270

Tokelau Islands

160

Tonga

273

Trindade & Martin

90

Trinidad & Tobago

274

Tristan Da Cunha

276

Tromelin

474

Tunisia

390

Turkey

280

Turkmenistan

89

Turks & Caicos Islands

282

Tuvalu

286

Uganda

283

UK Bases On Cyprus

288

Ukraine

391

United Arab Emirates

291

United States

UNTAET (E. Timor)

144

Uruguay

292

Uzbekistan

158

Vanuatu

295

Vatican

148

Venezuela

293

Vietnam

285

Virgin Islands

301

W. Kiribati (Gilbert Is.)

297

Wake Island

294

Wales

298

Wallis & Futuna Islands

299

West Malaysia

302

Western Sahara

190

Western Samoa

303

Willis Island

492

Yemen

296

Yugoslavia

414

Zaire

482

Zambia

452

Zimbabwe

Deleted Countries

Code

Country

2

Abu Ail Islands

8

Aldabra

19

Bajo Nuevo

23

Blenheim Reef

25

British N. Boreno

26

British Somali

28

Canal Zone

30

Celebe & Molucca Islands

39

Comoros

218

Czechoslovakia

42

Damao, Dui

243

Dem Rep Of Yemen

44

Desroches

183

Dutch Borneo

55

Farquhar

57

French Eq. Africa

67

French India

58

French Indo-China

59

French West Africa

229

German Dem. Rep.

81

Germany

93

Geyser Reef

101

Goa

102

Gold Coast/Togoland

113

Ifni

115

Italian Somali

119

Java

127

Kamaran Islands

128

Karelo-Finn Rep

139

Kuria Muria Island

155

Malaya

164

Manchuria

178

Minerva Reef

184

Netherlands N. Guniea

186

Newfoundland/Labrador

193

Okinawa

194

Okino Tori-Shima

196

Palestine

198

Papua Terr

493

Penguin Islands

200

Portuguese Timor

208

Ruanda-Urundi

210

Saar

220

Sarawak

226

Saudi/Iraq Neutral Zone

68

Saudi/Kuwait Neutral Zone

228

Serrana Bank

231

Sikkim

258

Sumatra

261

Swan Island

264

Tangier

267

Terr New Guinea

268

Tibet

271

Trieste

488

Walvis Bay

154

Yemen Arab Rep

307

Zanzibar


 


 

tqsl-2.0/html/trustedqsl/GAbbI/TableContinents.htm0000664000076400007640000001333712231073120022234 0ustar rmurphyrmurphy Continents

Table 5 - Continent

Designator

Continent

AF

Africa

AS

Asia

AN

Antarctica

EU

Europe

NA

North America

OC

Oceania

SA

South America

 

tqsl-2.0/html/trustedqsl/GAbbI/TableBand.htm0000664000076400007640000005305212231073120020752 0ustar rmurphyrmurphy Bands

Table 1 - Band Designations & Default Frequencies


Band

Frequency

160M

1.8 MHz

80M

3.5 MHz

40M

7. MHz

30M

10.1 MHz

20M

14. MHz

17M

18.068 MHz

15M

21. MHz

12M

24.89 MHz

10M

28. MHz

6M

50. MHz

4M

70. MHz

2M

144. MHz

1.25M

222. MHz

70CM

432. MHz

33CM

903. MHz

23CM

1296. MHz

13CM

2304. MHz

9CM

3456. MHz

6CM

5760. MHz

3CM

10368. MHz

1.25CM

24192. MHz

6MM

47040. MHz

4MM

80000. MHz

2.5MM

120000. MHz

2MM

145000. MHz

1MM

241000. MHz

SUBMM

322000. MHz


 

tqsl-2.0/html/trustedqsl/GAbbI/GAbbISample.htm0000664000076400007640000004303412231073120021203 0ustar rmurphyrmurphy Sample GAbbI File

/* 

 

Trusted Global Amateur Interchange Format Data for LOTW 

*/

 

<category:4>tQSL

 

<Rec_Type:6>Header

GAbbI header record, all fields are optional 

<GAbbI_Version:4>1.00

GAbbI Version 

<GAbbI_#_STATION_Recs:1>1

Optional, but shall be correct if present 

<GAbbI_#_CONTACT_Recs:1>1

Optional, but shall be correct if present 

<GAbbI_Sender:4>K1MK

 

<GAbbI_Created_By:12>CT2LoTW 1.00 

Name and version of log program 

<GAbbI_Created_On:20>2001-11-30T00:10:00Z 

ISO 8601 Date & Time 

<GAbbI_Sig_Algorithm:3>RSA

RSA (default), DSA or ECDSA 

<eor>

End of GAbbI header record 

 

 

<Rec_Type:8>tSTATION

The tSTATION record

<Call:4>K1MK

In the tSTATION record, the Call field is "My" call 

<DXCC:3>291

DXCC Entity

<State:5>US-CT

U.S. State 

<Cnty:5>CT005

U.S. County 

<CQZ:2>05 

CQ Zone 

<ITUZ:2>08 

ITU Zone 

<GridSquare:6>FN31ko 

Maidenhead Grid Square 

<Station_GUID:1>1

Format of UID/GUID is still TBD 

<Cert_GUID:10>0123456789

Format of Certificate # is still TBD 

<eor>

End of tSTATION record

<eoh>

End of header area 

 

 

<Rec_Type:8>tCONTACT

The tCONTACT record

<Call:5>CN8WW

Here the CALL field is "His" call 

<Band:4>160M

Band is required

<Freq:6>1.8271

Frequency in MHz is optional 

<QSO_Date:10>2001-11-27

YYYY-MM-DD 

<QSO_Time:9>00:00:15Z

HH:MM:[SS]Z (UTC) 

<Mode:2>CW

2 x Mode 

<RST_Sent:3>599

RST 

<Station_GUID:1>1

Format of UID/GUID still TBD 

<LoTW_Sign:172>ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqratuvwxyz0123456789./ABC
DEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr
stuvwxyz0123456789./ABCDEFGHIJKLMNOPQRSTU
VWXYZabcdefghijklmnop==

Signature w/1024-bit RSA key

<eor>

End of tCONTACT record 

<eof>

End of GAbbI logical file object 

 

 

 

 

tqsl-2.0/html/trustedqsl/GAbbI/AppendixA.htm0000664000076400007640000007213612231073120021013 0ustar rmurphyrmurphy Appendix 1 ARRL Logbok of the World (LOTW)

Appendix A ARRL Logbook of the World (LOTW)

Digital Signature Rule, Version 1.0

Signed Fields

REC_TYPE

tSTATION

tCONTACT

Field

 

Field

 

CALL

Required

BAND

Required

CONT

Optional

CALL

Required

CQZ

Optional

FREQ

Optional

CZ_DISTRICT

Optional

MODE

Required

DOK

Optional

QSO_DATE

Required

DXCC

Required

QSO_TIME

Required

GRIDSQUARE

Optional

RST_SENT

Optional

IOTA

Optional

 

 

ITUZ

Optional

 

 

JA_CITY

Optional

 

 

JA_GUN

Optional

 

 

NZ_COUNTY

Optional

 

 

REPEATER

Optional

 

 

SAT_NAME

Optional

 

 

SAT_MODE

Optional

 

 

SDOK

Optional

 

 

SK_DISTRICT

Optional

 

 

STATION_TYPE

Optional

 

 

SUB_GOV1

Optional

 

 

SUB_GOV2

Optional

 

 

SUB_GOV3

Optional

 

 

TX_PWR

Optional

 

 

US_COUNTY

Optional

 

 

WAE

Optional

 

 

 

Construction of the Signed Material

  1. The object to be signed is a character string that shall be created by concatenation of the field_values of  the fields designated  for signing under this rule (see above) that are present in a virtual QSL record.
  2. No white space or other delimiters shall be inserted between adjacent field_values when forming the string.
  3. The order in which field_values are placed in the string shall be as follows:
    1. First are the  field_values from the tSTATION record in order of an alphanumeric sorting of the field_name corresponding to each field_value.
    2. The tSTATION field_values are followed by  the  field_values from the tCONTACT  record again in order of an alphanumeric sorting of the field_name corresponding to each field_value.
    3. In the event that the same field_name occurs more than once within a  record, the relative ordering of the field_values for a non-unique field_name is determined by an  alphanumeric sorting of these field_values.
  4. No place holders or other padding shall be inserted in the string to account for optional fields that are not present  in the record being signed.
  5. A terminating null, a byte count or any other implementation dependent string delimiter or string length indicator shall not be considered to be a part of the character string being signed.

Signature

Key Type

Rivest, Shamir & Abelson Public Key Algorithm (RSA);

see ANSI X9.31-1998.

Key Length

1024 bits

Message Digest Algorithm

Secure Hash Algorithm (SHA-1); see FIPS-180-1.

 

tqsl-2.0/html/tqslapi.html0000775000076400007640000002367012231073120015657 0ustar rmurphyrmurphy

TrustedQSL C API

by Darryl Wagoner WA1GON

and

Jon Bloom KE3Z

Last update: 04 June 2002

Summary  

The TrustedQSL C API is a set of C++ methods with an ANSI C calling interface.  The API has both high level and low level functions.  For our purposes the differences being that low level functions are called by the high level functions.  For the most part the application programmer doesn't need to call the low level functions unless they wish to mimic a high level function.   One possible example might be create a new trusted file format or validating TrustedQSL from a database.

Requirements

Discussions

PKI Discussion

==============

When a certificate request is generated, the key pair is stored in a file in the key ring directory, with the private key encrypted via an operator-supplied pass phrase.

There are three certificate files in the certificate store: a file containing user certificates, a file containing CA certificates, and a file containing trusted (root) certificates.

When a certificate file is received, the root and CA certificates are first saved in their respective files. Then any user certificates are stored iff (1) their signatures can be verified using the available CA and root certificates, and (2) the public key in the certificate matches a key pair that's in the key ring. Matching user certificates are saved in the user-certificate file.

Note that certificates are opaque objects at the API level. And the application program never messes with -- or even sees -- the key pairs. It just passes the certificate objects supplied by tqsl_selectCertificates back to the library when it needs to sign or verify something, and the library takes care of selecting the private key needed.

Another detail that probably bears mention is that if a root certificate is being added, the operator should be prompted to accept it.

By the way, the code for a good chunk of the above is written and partially tested. :-)

Signing Discussion

==================

I don't think functions to sign ADIF or Cabrillo file belong in the core tQSL library. A separate utility (or library) that uses the tQSL library to convert an ADIF or Cabrillo file to Gabbi would be better. As several people have pointed out, ADIF is something of a moving target whose future direction is uncertain. To a lesser degree, the same is true of Cabrillo. It would be better to separate those functions from the core library IMHO.

We also need additional functions to create the Gabbi file of QSLs. Here's my cut:

< P >  

The application wanting to create a Gabbi submission of a log would do something like:

tQSL_Gabbi *g = tqsl_beginGabbi(<initialization parameters>);


<build station record>

tQSL_Cert **c = tqsl_selectCertificate(callsign, <qso date from first log record>, NULL);

if (<number_of_certs> > 1)

{

<select issuer to use for signing>

}

tqsl_Cert *cur_c = NULL;

for <each_log_record> {

<build contact record>

if (cur_c != NULL) {

if (!tqsl_checkCertificate(cur_c, callsign, qso_date)) {

tqsl_freeCertificate(cur_c);

cur_c = NULL;

}

}

if (cur_c == NULL) {

tqsl_Cert **c = tqsl_selectCertificates(callsign, qso_date, issuer);

if (*c == NULL) {

<no matching certs - can't sign this record>

}

cur_c = *c;

tqsl_beginSignVerify(cur_c);

}

tqsl_addGabbiQSLRecord(g, station, contact, cur_c);

}

tqsl_endGabbi();

if (cur_c != NULL) {

tqsl_freeCertificate(cur_c);

}

That leaves out quite a bit of detail, of course, but it shows the program flow as seen by the application.List of Functions and data structures.

All functions of the TrustedQSL API will be prefixed with tqsl_ and data structures will be prefixed with tQSL_. The C API will be only a set up of C wrappers for C++ class which will do the work. Data objects are opaque objects which can't be access except thru TrustedQSL functions.

Function categories

PKI functions:

tqsl_beginSignVerify(cert) - Using a callback to get the password, decrypts a copy of the private key which is kept in memory. (If has already been called with no intervening tqsl_endSignVerify, this becomes a no-op.)

tqsl_checkCertificate(cert, callsign, qso_date) - Returns TRUE if cert is valid for signing a QSO with the specified callsign and QSO date

tsql_createCertReq() - Generate key pair and certificate request file to send to CA. Uses a callback to get encryption pass phrase.

tqsl_endSignVerify(cert) - Blanks (zeroes) the copy of the unencrypted private key in memory.

tsql_freeCertificate(cert) - Frees any resources acquired by the library for the certificate object. Certificate object must not be used after this call. Implicitly calls tsql_endSignVerify.

tqsl_importCertFile() - Import a file of certificates. The file may consist of user, CA and/or root certificates. (See discussion below.)

tqsl_readCert() - Low level function, maybe private to API. Read Certificate (and add to certificate key ring ?)

tqsl_readPrivateKey() - Low level, and may use call back to vendor function.  Read a private key from private key ring. 

tqsl_rsaGenKey() - Create a RSA key pair.

tqsl_writePrivateKey() - Write a private key to private key ring.  Call back for pass phrase.

tqsl_selectCertificates(callsign, qso_date, issuer, with_expired) - Select one or more matching user certificates. Only active certs are returned unless with_expired == TRUE. If all three selection parameters are supplied and with_expired == FALSE, either 0 or 1 certificate will be returned: a certificate that can be used to sign a QSO with those parameters.

tqsl_sign* - TBD singing functions.

tqsl_signQSLRecord(tStation *, tContact *,tKeys *) - Low level function to sign a QSL record.  This will call the low level function tqsl_sign and tqsl_verify .

tqsl_validateTQSLRecord* - Low level function to validates a trustedQSL record.

Gabbi Signing Functions

tQSL_Gabbi g = tqsl_beginGabbi() - Initializes the Gabbi output. (What this exactly means is TBD, but at minimum it emits the Gabbi header. Have to set up the output stream/file, too.)

tqsl_addGabbiQSLRecord(tQSL_Gabbi*, tQSL_Station*, tQSL_Contact*, tQSL_Cert*) - Forms GABBI station, contact (w/signature) and cert records, as needed, and outputs them. This calls the low level function tqsl_signQSLRecord.

tqsl_endGabbi(tQSL_Gabbi*) - Cleans up the Gabbi output.

tqsl_validateGabbiQslFile(inputfile)  - Read a Gabbi file and validate the tQSL information.  Calls the low level function tqsl_validateTQSLRecord.

tqsl_validateGabbiEnumFile(inputfile) - Read and validate a Gabbi format enum file.

tqsl_validateGabbiSigListFile(inputfile) - Read and validate a Gabbi format signature list file.

Enumeration and Record Functions

tQSL_contact *tqsl_createContact() - return pointer to new contact record.

tQSL_signingList *tqsl_createSigningList() - returns pointer to a new signing list record. This is an object the has a list of fields for an award sponsor that must be signed if present. This list will also specify the required files for the award sponsor. This list is signed by the awards sponsor.

tQSL_station *tqsl_createStation() - returns pointer to a new station record.

tqsl_enumFields() - Returns a list of available field names.

tqsl_freeContact(tQSL_contact *) - frees the contact record.

tqsl_freeStation(tQSL_station *) - frees the station record.

tqsl_fieldType(tQSL_Station *, fieldName) - Given a field_name (from the list returned by enum_fields), returns:

  1.  A field type,

  2.  a maximum length,

  3.  an "enumerated" flag.

tqsl_setField(tQSL_Station, fieldName, value) - set the value of a field in the station_record that's being built. Parsing Functions:

 

Helper Functions. 

Helper functions are outside the TrustedQSL API, but maybe included for completeness. 

tqsl_signAdifFile(tQSL_station *,tQSL_privateKey, char *filename, char *gabbiOut,error Call back, tKeys) - Read in and sign each record of an ADIF file and write a corresponding Gabbi record to the output file.

tqsl_signCabrilloFile(tQSL_station *,tQSL_privateKey, char *filename, char *gabbiOut,error Callback, tKeys) - Read in and sign each record of an Cabrillo file and write a corresponding Gabbi record to the output file.

tqsl-2.0/html/README0000664000076400007640000000041112231073120014155 0ustar rmurphyrmurphyNOTE: Much of the documentation in this directory is historical. The embedded documentation in the source code should be considered authoritative. Still, what's here gives some background that may be useful to understanding the TrustedQSL concepts. KE3Z - 5/30/03 tqsl-2.0/cmakemodules/0000775000076400007640000000000012231073120015006 5ustar rmurphyrmurphytqsl-2.0/cmakemodules/FindZLIB.cmake0000664000076400007640000001007012231073120017347 0ustar rmurphyrmurphy#Copied from cmake-2.8 because we want to find the static library on Windows # - Find zlib # Find the native ZLIB includes and library. # Once done this will define # # ZLIB_INCLUDE_DIRS - where to find zlib.h, etc. # ZLIB_LIBRARIES - List of libraries when using zlib. # ZLIB_FOUND - True if zlib found. # # ZLIB_VERSION_STRING - The version of zlib found (x.y.z) # ZLIB_VERSION_MAJOR - The major version of zlib # ZLIB_VERSION_MINOR - The minor version of zlib # ZLIB_VERSION_PATCH - The patch version of zlib # ZLIB_VERSION_TWEAK - The tweak version of zlib # # The following variable are provided for backward compatibility # # ZLIB_MAJOR_VERSION - The major version of zlib # ZLIB_MINOR_VERSION - The minor version of zlib # ZLIB_PATCH_VERSION - The patch version of zlib #============================================================================= # Copyright 2001-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) FIND_PATH(ZLIB_INCLUDE_DIR zlib.h "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/include" "C:\\zlib\\" "C:\\zlib-1.2.8\\" "C:\\zlib-1.2.7\\" ) SET(ZLIB_NAMES_DBG zlibd zlibd1 zlibstaticd) set(ZLIB_NAMES_REL z zlib zdll zlib1 zlibstatic) if(WIN32) set(ZLIB_NAMES_DBG zlibstaticd ${ZLIB_NAMES_DBG}) #prefer static on windows set(ZLIB_NAMES_REL zlibstatic ${ZLIB_NAMES_REL}) else() set(ZLIB_NAMES_DBG ${ZLIB_NAMES_DBG} zlibstaticd) set(ZLIB_NAMES_REL ${ZLIB_NAMES_REL} zlibstatic) endif() FIND_LIBRARY(ZLIB_LIBRARY_DBG NAMES ${ZLIB_NAMES_DBG} PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/lib" "C:\\zlib\\Debug" "C:\\zlib-1.2.8\\Debug" "C:\\zlib-1.2.7\\Debug" ) FIND_LIBRARY(ZLIB_LIBRARY_REL NAMES ${ZLIB_NAMES_REL} PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Zlib;InstallPath]/lib" "C:\\zlib\\Release" "C:\\zlib-1.2.8\\Release" "C:\\zlib-1.2.7\\Release" ) MARK_AS_ADVANCED(ZLIB_LIBRARY_DBG ZLIB_LIBRARY_REL ZLIB_INCLUDE_DIR) IF(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") FILE(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") STRING(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") STRING(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") STRING(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") SET(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") # only append a TWEAK version if it exists: SET(ZLIB_VERSION_TWEAK "") IF( "${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$") SET(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") SET(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}") ENDIF( "${ZLIB_H}" MATCHES "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$") SET(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") SET(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") SET(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") ENDIF() # handle the QUIETLY and REQUIRED arguments and set ZLIB_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB REQUIRED_VARS ZLIB_INCLUDE_DIR ZLIB_LIBRARY_REL # rel should always be there VERSION_VAR ZLIB_VERSION_STRING) IF(ZLIB_FOUND) SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) if(ZLIB_LIBRARY_DBG) set(ZLIB_LIBRARIES debug ${ZLIB_LIBRARY_DBG} optimized ${ZLIB_LIBRARY_REL}) else() SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY_REL}) endif() ENDIF() tqsl-2.0/cmakemodules/FindCURL.cmake0000664000076400007640000000422212231073120017356 0ustar rmurphyrmurphy#KC2YWE - Copied from 2.8 dist and modified # - Find curl # Find the native CURL headers and libraries. # # CURL_INCLUDE_DIRS - where to find curl/curl.h, etc. # CURL_LIBRARIES - List of libraries when using curl. # CURL_FOUND - True if curl found. #============================================================================= # Copyright 2006-2009 Kitware, Inc. # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) # Look for the header file. FIND_PATH(CURL_INCLUDE_DIR curl/curl.h #for windows, there has to be a better way "C:\\curl\\include\\" "C:\\curl-7.31.0\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\include" "C:\\curl-7.29.0\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\include" "C:\\curl-7.28.1\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\include" ) MARK_AS_ADVANCED(CURL_INCLUDE_DIR) # Look for the library. FIND_LIBRARY(CURL_LIBRARY NAMES curl # Windows MSVC prebuilts: curllib libcurl_a libcurl libcurl_imp curllib_static PATHS "C:\\curl-7.31.0\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\lib" #winssl "C:\\curl-7.29.0\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\lib" #winssl "C:\\curl-7.28.1\\builds\\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl\\lib" #winssl "C:\\curl\\lib\\" "C:\\curl-7.28.1\\lib\\" ) MARK_AS_ADVANCED(CURL_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL DEFAULT_MSG CURL_LIBRARY CURL_INCLUDE_DIR) IF(CURL_FOUND) SET(CURL_LIBRARIES ${CURL_LIBRARY}) SET(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) ENDIF(CURL_FOUND) tqsl-2.0/cmakemodules/FindBDB.cmake0000664000076400007640000000266212231073120017206 0ustar rmurphyrmurphy# Find Berkeley DB # Look for the header file. if(APPLE) #exclude obsolete default OSX db FIND_PATH(BDB_INCLUDE_DIR db.h NO_DEFAULT_PATH PATHS "/usr/local/BerkeleyDB.6.0/include" "/usr/local/BerkeleyDB.5.3/include" "${BDB_PREFIX}/include" ) else() FIND_PATH(BDB_INCLUDE_DIR db.h #windows dirs (to be determined) "C:\\db-6.0.20\\build_windows" "C:\\db-5.3.21\\build_windows" ) endif() MARK_AS_ADVANCED(BDB_INCLUDE_DIR) # Look for the library. FIND_LIBRARY(BDB_LIBRARY NAMES db #windows build products #prefer small version libdb_small60s libdb60s libdb6-0.3 libdb6-0.so libdb_small53s libdb53s libdb5-5.3 libdb5-5.so PATHS "C:\\db-6.0.20\\build_windows\\Win32\\Static Release\\" "C:\\db-6.0.20\\build_windows\\Win32\\Static_Release\\" #vc08 adds underscore "C:\\db-5.3.21\\build_windows\\Win32\\Static Release\\" "C:\\db-5.3.21\\build_windows\\Win32\\Static_Release\\" #vc08 adds underscore #OSX (and probably other unix) src build "/usr/local/BerkeleyDB.6.0/lib" "/usr/local/BerkeleyDB.5.3/lib" "${BDB_PREFIX}/lib" "${BDB_PREFIX}" ) MARK_AS_ADVANCED(BDB_LIBRARY) # handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(BDB DEFAULT_MSG BDB_LIBRARY BDB_INCLUDE_DIR) IF(BDB_FOUND) SET(BDB_LIBRARIES ${BDB_LIBRARY}) SET(BDB_INCLUDE_DIRS ${BDB_INCLUDE_DIR}) ENDIF(BDB_FOUND) tqsl-2.0/apps/0000775000076400007640000000000012231074305013306 5ustar rmurphyrmurphytqsl-2.0/apps/tqslbuild.h0000664000076400007640000000011612231074305015460 0ustar rmurphyrmurphy// Define the build of TQSL #define VERSION "2.0" #define BUILD "[pkg-v2.0]" tqsl-2.0/apps/wxutil.h0000664000076400007640000000172112231073120015006 0ustar rmurphyrmurphy/*************************************************************************** wxutil.h - description ------------------- begin : Thu Aug 14 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __wxutil_h #define __wxutil_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #if wxCHECK_VERSION(2, 5, 0) #define TQ_WXCLOSEEVENT wxCloseEvent #define TQ_WXTEXTEVENT wxCommandEvent #define TQ_WXCOOKIE wxTreeItemIdValue #else #define TQ_WXCLOSEEVENT wxCommandEvent #define TQ_WXTEXTEVENT wxEvent #define TQ_WXCOOKIE long #endif wxSize getTextSize(wxWindow *win); #endif // __wxutil_h tqsl-2.0/apps/wxutil.cpp0000664000076400007640000000133312231073120015340 0ustar rmurphyrmurphy/*************************************************************************** wxutil.cpp - description ------------------- begin : Thu Aug 14 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wxutil.h" wxSize getTextSize(wxWindow *win) { wxClientDC dc(win); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT("M")), &char_width, &char_height); return wxSize(char_width, char_height); } tqsl-2.0/apps/util.h0000664000076400007640000000166012231073120014431 0ustar rmurphyrmurphy/*************************************************************************** util.h - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __util_h #define __util_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif class CertTreeItemData; class LocTreeItemData; void displayCertProperties(CertTreeItemData *item, wxWindow *parent = 0); void displayLocProperties(LocTreeItemData *item, wxWindow *parent = 0); int getPassword(char *buf, int bufsiz, void *); void displayTQSLError(const char *pre); wxMenu *makeCertificateMenu(bool enable, bool keyonly = false); wxMenu *makeLocationMenu(bool enable); #endif // __util_h tqsl-2.0/apps/upload_dis.xpm0000664000076400007640000001714012231073120016154 0ustar rmurphyrmurphy/* XPM */ static const char * upload_dis_xpm[] = { "48 48 182 2", " c None", ". c #8F8F8F", "+ c #979797", "@ c #999999", "# c #9B9B9B", "$ c #707070", "% c #717171", "& c #676767", "* c #606060", "= c #646464", "- c #666666", "; c #6D6D6D", "> c #8C8C8C", ", c #909090", "' c #A9A9A9", ") c #ACACAC", "! c #A8A8A8", "~ c #656565", "{ c #6E6E6E", "] c #888888", "^ c #838383", "/ c #949494", "( c #939393", "_ c #858585", ": c #6B6B6B", "< c #737373", "[ c #B3B3B3", "} c #B2B2B2", "| c #B4B4B4", "1 c #A7A7A7", "2 c #6C6C6C", "3 c #848484", "4 c #A1A1A1", "5 c #5C5C5C", "6 c #626262", "7 c #6F6F6F", "8 c #818181", "9 c #919191", "0 c #ABABAB", "a c #B6B6B6", "b c #BFBFBF", "c c #696969", "d c #989898", "e c #B5B5B5", "f c #7C7C7C", "g c #797979", "h c #777777", "i c #747474", "j c #959595", "k c #8A8A8A", "l c #8B8B8B", "m c #575757", "n c #515151", "o c #5E5E5E", "p c #6A6A6A", "q c #787878", "r c #BABABA", "s c #AEAEAE", "t c #7B7B7B", "u c #808080", "v c #969696", "w c #7F7F7F", "x c #4D4D4D", "y c #4C4C4C", "z c #565656", "A c #545454", "B c #4E4E4E", "C c #555555", "D c #868686", "E c #757575", "F c #A3A3A3", "G c #878787", "H c #898989", "I c #828282", "J c #454545", "K c #464646", "L c #5D5D5D", "M c #525252", "N c #9C9C9C", "O c #A0A0A0", "P c #A5A5A5", "Q c #A6A6A6", "R c #767676", "S c #929292", "T c #AAAAAA", "U c #444444", "V c #414141", "W c #484848", "X c #686868", "Y c #9D9D9D", "Z c #7A7A7A", "` c #9A9A9A", " . c #9E9E9E", ".. c #B1B1B1", "+. c #9F9F9F", "@. c #3E3E3E", "#. c #424242", "$. c #474747", "%. c #636363", "&. c #727272", "*. c #7E7E7E", "=. c #8D8D8D", "-. c #A2A2A2", ";. c #3B3B3B", ">. c #8E8E8E", ",. c #ADADAD", "'. c #595959", "). c #3A3A3A", "!. c #3D3D3D", "~. c #404040", "{. c #616161", "]. c #AFAFAF", "^. c #B0B0B0", "/. c #535353", "(. c #393939", "_. c #3C3C3C", ":. c #3F3F3F", "<. c #434343", "[. c #4B4B4B", "}. c #B8B8B8", "|. c #505050", "1. c #B7B7B7", "2. c #7D7D7D", "3. c #4F4F4F", "4. c #383838", "5. c #B9B9B9", "6. c #5A5A5A", "7. c #BBBBBB", "8. c #585858", "9. c #363636", "0. c #333333", "a. c #323232", "b. c #4A4A4A", "c. c #BCBCBC", "d. c #353535", "e. c #373737", "f. c #A4A4A4", "g. c #313131", "h. c #C0C0C0", "i. c #BEBEBE", "j. c #C5C5C5", "k. c #C8C8C8", "l. c #C9C9C9", "m. c #C7C7C7", "n. c #C3C3C3", "o. c #BDBDBD", "p. c #494949", "q. c #C6C6C6", "r. c #CBCBCB", "s. c #CECECE", "t. c #CFCFCF", "u. c #CDCDCD", "v. c #CACACA", "w. c #5F5F5F", "x. c #C2C2C2", "y. c #D2D2D2", "z. c #C4C4C4", "A. c #C1C1C1", "B. c #D3D3D3", "C. c #343434", "D. c #303030", "E. c #2D2D2D", "F. c #5B5B5B", "G. c #2C2C2C", "H. c #2F2F2F", "I. c #2A2A2A", "J. c #282828", "K. c #292929", "L. c #2B2B2B", "M. c #2E2E2E", "N. c #262626", "O. c #272727", "P. c #222222", "Q. c #141414", "R. c #202020", "S. c #000000", "T. c #131313", "U. c #020202", "V. c #232323", "W. c #212121", "X. c #070707", "Y. c #1B1B1B", " ", " ", " . + @ # $ % & * = - ", " = = ; > , ' ) ! @ - = ~ ~ = { ] ", " = & % ^ / ( _ : < [ } | 1 ; ; { { 2 3 4 . ", " 5 6 7 8 9 4 0 a b c d } } e f g / ^ h i j ' k l ", " m n o p & ~ & q + r 4 c . } s t f u v k 8 w f > d h , ", " x y z 6 A B C D > $ 8 : $ E # F 8 _ G ] H k H j l f w # . I ", " J K x m - L M = N O P Q % R t w 3 ] > . 9 S S 9 S ' v f T d H h ", " U V W B m - % X > / v Y ! v Z 8 G > , / + @ ` ` @ v ) .9 ..+., ^ $ ", " U @.#.$.B z %.&.*.H . j # +.0 ^ G =.( d Y O -.F -.O .` j =.e Q + k Z ", " ;.@.V $.y z 6 7 f D >.9 > N ! ^ =./ ` +.F 1 ' T T ! P 4 # j @ ,. .G q '. ", " ;.).!.~.J y C {.{ t G 9 v E f ( Y / ` O P T ,.].^.^.s ) 1 4 @ ) s / % = './. ", " @.(.)._.:.<.[.C 6 7 w >.l d . 8 ] , d +.P T s ..| | | [ ^.) Q .}...d h : L |. ", " ).(.(.).!.#.[.z 6 i ] 8 ; i t 3 > j N F ! ,...e 1.}.1.a [ ].T F ' a ' Z N 2.M 3. ", " ).).4.(._.<.y m & t = ~ 7 R *.G . + +.P T ].[ 1.5.r r }.e } ) Q Y d D # ) d w 2 ", " V _.;.(.).!.U B 5 7 6.o - 7 R u H 9 @ O Q ) ..e 1.5.7.r 5.a } ,.1 +./ -.7.Q 9 t X '. ", " @.:.!.;.!.:.$.A 8.A A o - { R u k S ` 4 Q ) ..e }.r 7.r }.e } ,.Q ./ | 1.4 >.R 6 A ", " #.<.U <.U K x n U y /.5 = ; E u H S @ O 1 ) ^.| 1.5.r 5.1.| ^.) P Y ( 1 | +.H % o /. ", " $.J $.9.0.a._.A :.<.b.n '.6 : < *.] , d +.P 0 ].[ a 1.1.a [ ].0 Q 4 ` S c.].` _ 2 8.B K ", " <.W J d.a.a.0.b.!.V W 3.m * & % t _ >.v Y F ! ,...| } P ) | ^.) ,.s .( 5.' v *.& C b.U ", " #.b.(.e.0.a.0.:.@.~.K x A 5 = ; h 8 k S @ +.P ' ' +.P .4 1 ,.^.^.,.1 Q f. .G q {.|.J #. ", " <.[.).e.0.g.d.e.(.@.U b.n 8.* X % t _ =./ # O d S G ( F s a c.b h.i.1.].F d d 2 6.[.~.~. ", " ;.y J U <.g.e.5 3._.#.$.x A 5 %.2 E *.D >.( H f f , 4 s }.h.j.k.l.m.n.o.} f.( =.X J !.;. ", " 4.!.[.p.d.a.a.0.W ~.:.U b.|.m o ~ { R w _ 2.< % H # ' | b q.r.s.t.u.v.j.7.].+.>._ w.(.4. ", " 4.!.:.W :.0.g.0.9.(.W L K x M '.w.& { E < E X 2., O s 5.x.l.u.f.h.y.t.v.x.a 1 v 3 *.U (. ", " 4.!.:.:.:.!.g.0.d.(._.:.U p.B A 6.w.- : f = 7 I / F ].7.z.k.+.( + A.B.s.q.7.) # H g R C. ", " 4.!.~.:.(.9.a.0.C.e.).!.#.J b.3.A 6.w.'.= 6 < D j F ].r h.v >.v ` + c.t.k.i.].Y > t $ x ", " 4._.V V _.d.D.g.0.C.4.;.@.<.$.[.3.A m 2 L 6 i _ / -.s [ H D >.j d + 9 [ m.i.]. .> f $ c ", " ;.~.#.~.4.D.E.a.z $.z * U /.K [.3.[.L 6.{.&.^ 9 +.f.t t _ l 9 ( / , k 1 7.,.N H Z { & ", " (.:.<.#.@.4.C.M 6.* c i 3 j { K b.<.z m w.7 w =.S : ; q 8 ] >., 9 . H *./ 1 + D h 2 6 <. ", " 4.!.#.U #.!._.C M 8.* p h G @ >.[.|.3./.F.c q 2.'.o c < f 3 H > =.l _ Z 2 Z . u < c * n ", " ;.V U U ~.#.n 3.M 6.~ % 2.k @ .t [.B C {.~ J y m 6 2 R 2.I D D ^ t $ %.A {.g { ~ L C ", " (.@.U K J z 3.y B A L X i *.H =.{ J b.3.6.{.; g _ . _ : &.h g g Z f.# , 3 h % X * '.B ", " ;.V K K C 3.[.[.3.m {.: i t 2.& #.U W n F.- % 2.G Z o = X c c : # ( H *.i p %.6.M y ", " (.@.U K z n x [.B /.6.{.X { % L #.#.<.p.n 6.= { R p B A 8.'.'.F.k 3 t < p %.F.C n U ", " ).~.K b.A |.B B n m 6.* %.~ B U #.#.<.p.|.8.w.& F.V J p.b.b.x Z E 7 X {.5 m /.3.C. ", " _.#.$.y C M M n /.8.6.F.5 B $.#.#.V U p.3.C 6.3.9.).!.:.:.<.2 X = * 5 8.A n x ", " ).!.U W A m z z A A z m A B 3.<.#.V V J b.B /.$.g.C.9.e.4._.%.* L 6.m A M 3.W ", " d.@.U p.C 6.'.'.8.z A /.|.(.J <.#.V #.J p.x #.G.H.g.a.0.e.F.6.8.C /.M 3.[.I. ", " J.@.U p.M 5 5 F.'.m /.3.J b.U U <.#.#.J W !.K.L.G.E.M.a.C A M M |.3.y U ", " _.<.W n 6.6.F.6.m A 3.!.$.U J U <.<.J ).N.O.K.I.I.M.|.3.|.3.B y W ", " D.~.W A z 8.'.'.m A 3._.J J K J U U K p.[.y x 3.|.x B B x b.K P. ", " Q.9.p.y |.M A A C C y 9.K J K $.K K K W p.b.y y y y b.W U R. ", " S.T.E.#.W y 3.y W W J d.J J K $.W W p.p.p.p.p.W $.K !.T. ", " S.U.T.V.L.0.(.;.).9.K.W.g.U K $.W W W W $.K !.R. ", " X.Y.K.0.d.d.M.V. ", " "}; tqsl-2.0/apps/upload.xpm0000664000076400007640000006721512231073120015325 0ustar rmurphyrmurphy/* XPM */ static const char * upload_xpm[] = { "48 48 1465 2", " c None", ". c #56B6C9", "+ c #62BBCC", "@ c #62C1D1", "# c #66C1D1", "$ c #2F99B2", "% c #2F99B3", "& c #218FAD", "* c #1789A9", "= c #1F8CAA", "- c #228EAB", "; c #2489A5", "> c #1E8FAB", ", c #2A96B0", "' c #4FB6C9", ") c #55B9CB", "! c #75D1DE", "~ c #78D4E0", "{ c #75CEDC", "] c #63BFD0", "^ c #1C94B1", "/ c #1793B1", "( c #1894B2", "_ c #1893B1", ": c #279AB5", "< c #50ACC1", "[ c #1994AF", "} c #16A0B8", "| c #1BB3C8", "1 c #34C1D2", "2 c #4FCBD9", "3 c #56C1D1", "4 c #48AFC3", "5 c #2794B0", "6 c #2F9DB7", "7 c #84D8E3", "8 c #80D8E4", "9 c #84D8E4", "0 c #75CAD9", "a c #229DB8", "b c #219FBA", "c c #229FBA", "d c #239FBA", "e c #219DB8", "f c #42B1C6", "g c #69CBD9", "h c #56B7C9", "i c #0D8DAB", "j c #0BA1BA", "k c #14B4CA", "l c #2DC4D5", "m c #46D0DC", "n c #5FD9E3", "o c #6EDFE8", "p c #81E4EC", "q c #92E6ED", "r c #2096B2", "s c #61BDCF", "t c #82D5E2", "u c #83D4E2", "v c #89D4E1", "w c #37AAC2", "x c #31AAC2", "y c #59BED0", "z c #3FB1C7", "A c #2CA8C2", "B c #29A6BF", "C c #59BFD1", "D c #74D2DF", "E c #4DB3C7", "F c #54AEC3", "G c #167799", "H c #0180A2", "I c #0898B5", "J c #11AEC4", "K c #199CB5", "L c #1C93AE", "M c #2093AE", "N c #33A6BD", "O c #5AC5D5", "P c #86E7EE", "Q c #6AC9D8", "R c #1D99B6", "S c #54B5CB", "T c #85D0E0", "U c #7FCCDD", "V c #34A9C2", "W c #33ADC6", "X c #38B0C8", "Y c #5ABED2", "Z c #47B7CD", "` c #39B2CA", " . c #36B1C9", ".. c #33ADC5", "+. c #4DB9CC", "@. c #5FC1D2", "#. c #34A2BB", "$. c #57B7CA", "%. c #0D688E", "&. c #007398", "*. c #0389AA", "=. c #0B9FB9", "-. c #0B7F9D", ";. c #077296", ">. c #0C7C9E", ",. c #43B7CA", "'. c #4ABDCE", "). c #2B9BB5", "!. c #3FACC3", "~. c #1F9BB7", "{. c #24A2BD", "]. c #2CA5BF", "^. c #64BED3", "/. c #6FC4D7", "(. c #39B1C9", "_. c #3DB5CD", ":. c #41B8CE", "<. c #42B9CF", "[. c #43BAD0", "}. c #44BAD0", "|. c #43B9D0", "1. c #57C1D4", "2. c #49B9CE", "3. c #3CACC3", "4. c #62C3D4", "5. c #53B9CC", "6. c #4AA3BA", "7. c #065C84", "8. c #00648D", "9. c #00769B", "0. c #038DAC", "a. c #0FA5BD", "b. c #138BA7", "c. c #0A779A", "d. c #1D8EAB", "e. c #57D7E2", "f. c #5DD9E4", "g. c #66D8E4", "h. c #6DD3DF", "i. c #27A1BC", "j. c #2BA7C1", "k. c #31ACC5", "l. c #36B0C8", "m. c #3CB4CC", "n. c #47BCD2", "o. c #4BBFD4", "p. c #4DC1D5", "q. c #4EC2D6", "r. c #50C0D4", "s. c #76CEDD", "t. c #59BFD3", "u. c #34ADC5", "v. c #77CFDD", "w. c #5CC2D4", "x. c #4BB2C8", "y. c #3D99B2", "z. c #0A567E", "A. c #005983", "B. c #006790", "C. c #01799C", "D. c #038FAC", "E. c #10A5BC", "F. c #22AAC0", "G. c #2293AE", "H. c #43C6D5", "I. c #4BCFDD", "J. c #4FD1DE", "K. c #5AD4E1", "L. c #6CD9E5", "M. c #59C2D4", "N. c #30ACC5", "O. c #38B2CB", "P. c #40B7CE", "Q. c #46BBD2", "R. c #4CBFD4", "S. c #52C3D7", "T. c #56C6D9", "U. c #59C8DA", "V. c #5AC9DB", "W. c #59C9DB", "X. c #57C9DB", "Y. c #54C6D9", "Z. c #78D1E0", "`. c #64C5D8", " + c #52BBD0", ".+ c #82D4E1", "++ c #65C8D9", "@+ c #51B9CF", "#+ c #44AAC2", "$+ c #368FAA", "%+ c #0D547B", "&+ c #00517C", "*+ c #005A84", "=+ c #00698F", "-+ c #00799C", ";+ c #038DAA", ">+ c #0E9FB8", ",+ c #1FB0C6", "'+ c #2FBACE", ")+ c #3DC5D6", "!+ c #45C9D9", "~+ c #4FCDDC", "{+ c #58CFDF", "]+ c #5ED2E0", "^+ c #72D8E4", "/+ c #3EB1C9", "(+ c #40B7CF", "_+ c #48BCD2", ":+ c #51C0D5", "<+ c #58C5D8", "[+ c #5FC9DB", "}+ c #63CCDD", "|+ c #66CEDE", "1+ c #67CFDF", "2+ c #66CFDF", "3+ c #63CEDE", "4+ c #5FCCDD", "5+ c #52C4D8", "6+ c #48BDD2", "7+ c #87D5E3", "8+ c #71CCDC", "9+ c #5BBED3", "0+ c #4CB1C8", "a+ c #3C9EB8", "b+ c #004C76", "c+ c #00527C", "d+ c #00688E", "e+ c #007799", "f+ c #0589A7", "g+ c #0F9CB6", "h+ c #1DABC2", "i+ c #2DB8CC", "j+ c #3AC0D3", "k+ c #46C6D7", "l+ c #4EC4D5", "m+ c #48BCD0", "n+ c #5ECBDB", "o+ c #6ED5E2", "p+ c #3CB2CA", "q+ c #49BBD2", "r+ c #53C0D5", "s+ c #5CC5D8", "t+ c #64CADB", "u+ c #6ACDDD", "v+ c #6FD0E0", "w+ c #72D2E1", "x+ c #73D3E2", "y+ c #72D4E2", "z+ c #6FD3E2", "A+ c #6AD1E1", "B+ c #64CEDF", "C+ c #5BCBDC", "D+ c #53C4D8", "E+ c #5CC3D6", "F+ c #7BCFDF", "G+ c #67C2D5", "H+ c #4AADC5", "I+ c #3A9CB7", "J+ c #18799A", "K+ c #044B73", "L+ c #004B75", "M+ c #00507A", "N+ c #005981", "O+ c #00658B", "P+ c #017597", "Q+ c #0786A4", "R+ c #1098B3", "S+ c #1DA8BF", "T+ c #2DB4CA", "U+ c #3DBED1", "V+ c #4DC3D6", "W+ c #56C4D6", "X+ c #2BA5BF", "Y+ c #32ACC6", "Z+ c #53BFD3", "`+ c #64C5D7", " @ c #54BED4", ".@ c #5DC5D8", "+@ c #66CADB", "@@ c #6DCEDE", "#@ c #74D1E0", "$@ c #78D4E2", "%@ c #7BD6E4", "&@ c #7CD7E4", "*@ c #7CD7E5", "=@ c #79D6E4", "-@ c #75D5E3", ";@ c #6ED2E1", ">@ c #65CEDE", ",@ c #7ACFDF", "'@ c #7ECFDF", ")@ c #59BACF", "!@ c #299FBA", "~@ c #1D8EAC", "{@ c #147D9E", "]@ c #157092", "^@ c #084D74", "/@ c #004872", "(@ c #004E78", "_@ c #00577F", ":@ c #006287", "<@ c #027294", "[@ c #0984A2", "}@ c #1296B2", "|@ c #21A5BD", "1@ c #34B4CA", "2@ c #4AC0D3", "3@ c #4AB8CD", "4@ c #5BC3D5", "5@ c #50BACF", "6@ c #37B1CB", "7@ c #42B7CF", "8@ c #4EBCD2", "9@ c #5AC2D6", "0@ c #64C8DA", "a@ c #6DCDDD", "b@ c #7AD4E2", "c@ c #7FD7E4", "d@ c #82D9E6", "e@ c #83DAE6", "f@ c #81D9E6", "g@ c #6DD1E0", "h@ c #61CADC", "i@ c #8BD6E5", "j@ c #81D1E1", "k@ c #5FBED2", "l@ c #2FA4BF", "m@ c #2496B2", "n@ c #1883A3", "o@ c #0E7093", "p@ c #024A72", "q@ c #004A73", "r@ c #004C75", "s@ c #00547B", "t@ c #015F84", "u@ c #047092", "v@ c #0C81A0", "w@ c #1593AF", "x@ c #44B8CD", "y@ c #3FADC4", "z@ c #229CB8", "A@ c #28A4C0", "B@ c #30ACC6", "C@ c #3CB4CD", "D@ c #48BAD1", "E@ c #55C0D5", "F@ c #60C5D8", "G@ c #6ACBDC", "H@ c #72CFDF", "I@ c #79D3E1", "J@ c #7FD6E4", "K@ c #84D9E6", "L@ c #87DBE7", "M@ c #88DCE8", "N@ c #87DCE8", "O@ c #85DBE7", "P@ c #73D2E1", "Q@ c #68CEDE", "R@ c #74CDDE", "S@ c #89D4E3", "T@ c #77CADC", "U@ c #34A8C1", "V@ c #62C8D7", "W@ c #3DA6BD", "X@ c #107294", "Y@ c #126B8D", "Z@ c #004C74", "`@ c #004971", " # c #004B73", ".# c #005279", "+# c #025F85", "@# c #076E91", "## c #0E80A0", "$# c #1D97B2", "%# c #36A9C1", "&# c #1E8BAA", "*# c #1A93B1", "=# c #239EBB", "-# c #2AA7C3", ";# c #33AFC9", "># c #40B6CE", ",# c #4DBCD2", "'# c #59C2D6", ")# c #6DCCDD", "!# c #75D1E0", "~# c #7CD5E3", "{# c #82D8E5", "]# c #8ADCE8", "^# c #8BDDE9", "/# c #84DAE6", "(# c #7FD7E5", "_# c #77D3E2", ":# c #6DCFDF", "<# c #60C8DA", "[# c #5BC2D6", "}# c #41B5CC", "|# c #60C6D6", "1# c #71DDE7", "2# c #55CEDC", "3# c #38B2C6", "4# c #249BB4", "5# c #09547A", "6# c #005278", "7# c #005076", "8# c #004B72", "9# c #004D74", "0# c #01547A", "a# c #036086", "b# c #0A7193", "c# c #1485A4", "d# c #299CB6", "e# c #177E9E", "f# c #1587A7", "g# c #1B94B2", "h# c #239FBB", "i# c #2AA8C3", "j# c #36B0CA", "k# c #43B7CF", "l# c #50BDD3", "m# c #5CC3D7", "n# c #66C9DB", "o# c #6FCEDE", "p# c #77D2E1", "q# c #7ED6E4", "r# c #88DCE7", "s# c #8BDDE8", "t# c #8DDDE9", "u# c #8CDDE9", "v# c #86DAE6", "w# c #80D7E5", "x# c #79D4E2", "y# c #6FCFDF", "z# c #63C9DB", "A# c #54C1D5", "B# c #69CADB", "C# c #89E5ED", "D# c #68D9E4", "E# c #4BC8D8", "F# c #2FB2C7", "G# c #1C9AB4", "H# c #177E9B", "I# c #00577D", "J# c #00577E", "K# c #004F77", "L# c #015379", "M# c #02567D", "N# c #066489", "O# c #0F789A", "P# c #157B9B", "Q# c #137495", "R# c #1586A7", "S# c #1B92B1", "T# c #229DBB", "U# c #38B0C9", "V# c #45B7CF", "W# c #51BDD3", "X# c #5DC4D8", "Y# c #67CADB", "Z# c #6FCFDE", "`# c #77D3E1", " $ c #7ED7E4", ".$ c #8DDEE9", "+$ c #89DCE8", "@$ c #85DAE6", "#$ c #80D7E4", "$$ c #78D3E2", "%$ c #63C8DA", "&$ c #54C0D5", "*$ c #84D8E5", "=$ c #83E2EB", "-$ c #62D4E1", ";$ c #48C3D5", ">$ c #2AACC3", ",$ c #1694AF", "'$ c #107998", ")$ c #005E84", "!$ c #006186", "~$ c #006388", "{$ c #006086", "]$ c #036186", "^$ c #056288", "/$ c #0A6C90", "($ c #107092", "_$ c #085B80", ":$ c #0A698E", "<$ c #0E7699", "[$ c #1483A4", "}$ c #1A90AF", "|$ c #219CB9", "1$ c #2AA6C1", "2$ c #38AFC9", "3$ c #44B7CE", "4$ c #51BED3", "5$ c #7DD7E4", "6$ c #8ADDE9", "7$ c #83D9E5", "8$ c #7ED5E3", "9$ c #6DCDDE", "0$ c #62C7D9", "a$ c #53BED4", "b$ c #71CEDD", "c$ c #7FDEE9", "d$ c #60D1DF", "e$ c #42BDD1", "f$ c #25A5BD", "g$ c #138DAA", "h$ c #0C7B9B", "i$ c #096186", "j$ c #00658A", "k$ c #006B8E", "l$ c #00476C", "m$ c #004066", "n$ c #013D64", "o$ c #054E74", "p$ c #0F7699", "q$ c #075377", "r$ c #075980", "s$ c #0A668B", "t$ c #0D7296", "u$ c #127FA1", "v$ c #188CAD", "w$ c #1F98B7", "x$ c #28A4BF", "y$ c #35ADC7", "z$ c #43B5CD", "A$ c #4FBCD2", "B$ c #5AC3D7", "C$ c #64C9DB", "D$ c #75D2E1", "E$ c #85DCE8", "F$ c #87DDE8", "G$ c #86DBE7", "H$ c #83D8E4", "I$ c #7ED4E1", "J$ c #78D0DE", "K$ c #71CDDC", "L$ c #69C9DA", "M$ c #5EC4D7", "N$ c #52BCD2", "O$ c #90DDE8", "P$ c #79DAE6", "Q$ c #5ACBDB", "R$ c #3EB6CC", "S$ c #219DB7", "T$ c #0F83A2", "U$ c #097294", "V$ c #0A6083", "W$ c #035F83", "X$ c #006C90", "Y$ c #00688B", "Z$ c #00436B", "`$ c #003D65", " % c #013B64", ".% c #013D65", "+% c #0D6588", "@% c #065075", "#% c #06577D", "$% c #096288", "%% c #0C6E93", "&% c #107A9E", "*% c #1788A9", "=% c #1C94B3", "-% c #269FBC", ";% c #32A9C4", ">% c #3FB3CB", ",% c #4CBAD1", "'% c #57C1D5", ")% c #61C7D9", "!% c #6ACCDD", "~% c #70D1E0", "{% c #77D5E3", "]% c #7DD8E5", "^% c #82DAE6", "/% c #82D7E3", "(% c #7BC8CF", "_% c #8FC9B2", ":% c #9ECBA1", "<% c #A7CD93", "[% c #A9CC8D", "}% c #A4CB90", "|% c #98C697", "1% c #80BCA5", "2% c #6EB5B8", "3% c #91D9E2", "4% c #72D4E1", "5% c #55C5D7", "6% c #37ADC6", "7% c #1E94B0", "8% c #0E7B9C", "9% c #07698D", "0% c #085C80", "a% c #006084", "b% c #007295", "c% c #004D73", "d% c #00456E", "e% c #003D66", "f% c #003B64", "g% c #013E66", "h% c #075278", "i% c #065076", "j% c #05547B", "k% c #085E84", "l% c #0B6A8F", "m% c #0F7599", "n% c #1482A4", "o% c #1A8FAF", "p% c #229AB8", "q% c #2EA5C0", "r% c #3AAEC8", "s% c #46B6CE", "t% c #5BC4D7", "u% c #6CCEDE", "v% c #74D0DE", "w% c #7CC3B4", "x% c #A4CC7F", "y% c #C2DD5F", "z% c #C5E063", "A% c #C7E16D", "B% c #CBE378", "C% c #CCE37D", "D% c #CAE27F", "E% c #C6E07A", "F% c #C0DC72", "G% c #BFDC71", "H% c #AACC7C", "I% c #7FBEA6", "J% c #4AB2C5", "K% c #32A4BE", "L% c #1A8AA8", "M% c #0C7194", "N% c #056085", "O% c #08587D", "P% c #006286", "Q% c #007396", "R% c #00466E", "S% c #003E66", "T% c #003B63", "U% c #024269", "V% c #03446B", "W% c #034870", "X% c #055178", "Y% c #075A81", "Z% c #0A658B", "`% c #0D7095", " & c #127C9F", ".& c #1788AA", "+& c #1D94B3", "@& c #289FBB", "#& c #34A8C3", "$& c #40B1CA", "%& c #4BB9D0", "&& c #54BFD4", "*& c #5DC5D9", "=& c #65C9DB", "-& c #67C0C9", ";& c #95C560", ">& c #BBDA34", ",& c #BDDC4A", "'& c #C5E067", ")& c #CCE379", "!& c #D1E687", "~& c #D4E890", "{& c #D6E996", "]& c #D6E997", "^& c #D3E894", "/& c #CEE48B", "(& c #C6E07F", "_& c #BAD96D", ":& c #B1D45D", "<& c #99C46D", "[& c #419697", "}& c #0A678C", "|& c #04557C", "1& c #06537B", "2& c #007699", "3& c #00678B", "4& c #006589", "5& c #003A62", "6& c #03456B", "7& c #128DA7", "8& c #0F7090", "9& c #054D74", "0& c #06567E", "a& c #086087", "b& c #0B6B90", "c& c #0F769A", "d& c #1481A4", "e& c #198DAE", "f& c #2298B6", "g& c #2CA1BE", "h& c #37AAC5", "i& c #42B3CB", "j& c #4CBAD0", "k& c #54BED3", "l& c #5EB4B3", "m& c #A4CC2C", "n& c #B3D722", "o& c #BBDA46", "p& c #C3DF64", "q& c #CBE379", "r& c #D2E68B", "s& c #D7EA97", "t& c #DAEC9F", "u& c #DCEDA4", "v& c #DCEDA5", "w& c #DBECA3", "x& c #D7EA9D", "y& c #D1E793", "z& c #C7E183", "A& c #BAD96F", "B& c #ABD057", "C& c #A3CA51", "D& c #498875", "E& c #095B81", "F& c #044E76", "G& c #034B73", "H& c #00557B", "I& c #007497", "J& c #006E93", "K& c #00466B", "L& c #003C64", "M& c #013C64", "N& c #023E65", "O& c #0B6085", "P& c #07537A", "Q& c #065279", "R& c #085B81", "S& c #0C6F95", "T& c #1585A7", "U& c #1B90B0", "V& c #259AB7", "W& c #2FA2BE", "X& c #39ABC5", "Y& c #41B1CA", "Z& c #4FAAAC", "`& c #A2CA1C", " * c #ABD211", ".* c #B5D73B", "+* c #BDDC5A", "@* c #C6E072", "#* c #CEE485", "$* c #D5E995", "%* c #DAECA0", "&* c #DEEEA8", "** c #E0F0AC", "=* c #E1F0AE", "-* c #DFEFAC", ";* c #DCEDA7", ">* c #D8EB9F", ",* c #D0E691", "'* c #C4E07F", ")* c #B5D768", "!* c #A5CD4F", "~* c #9DC743", "{* c #457961", "]* c #04476E", "^* c #03466E", "/* c #00537B", "(* c #005A7F", "_* c #006D91", ":* c #004167", "<* c #02426A", "[* c #0D6184", "}* c #1B81A0", "|* c #085F85", "1* c #0B698F", "2* c #0D7398", "3* c #127DA1", "4* c #1687A9", "5* c #1D91B1", "6* c #269AB7", "7* c #2EA2BD", "8* c #369DB1", "9* c #91C02B", "0* c #A3CE03", "a* c #ACD327", "b* c #B6D74A", "c* c #BFDC64", "d* c #C8E17B", "e* c #D0E68D", "f* c #D7EA9B", "g* c #DDEDA6", "h* c #DFEFAB", "i* c #C0DE6B", "j* c #D5E998", "k* c #E2F0B4", "l* c #E0EFAF", "m* c #DBEDA7", "n* c #D5E99B", "o* c #CBE489", "p* c #BCDC73", "q* c #ACD25B", "r* c #9CC742", "s* c #95C03C", "t* c #2B5D5C", "u* c #07456B", "v* c #004870", "w* c #00597E", "x* c #00537A", "y* c #013A61", "z* c #024169", "A* c #03466F", "B* c #044C74", "C* c #055279", "D* c #075B82", "E* c #09638A", "F* c #0B6C92", "G* c #0E759A", "H* c #127EA2", "I* c #1688A9", "J* c #1D90B0", "K* c #2494B2", "L* c #66A554", "M* c #9BC800", "N* c #A2CD11", "O* c #ACD232", "P* c #B6D751", "Q* c #BFDC6A", "R* c #C8E17E", "S* c #D1E690", "T* c #D8EB9D", "U* c #DBEDA4", "V* c #BADC62", "W* c #B4D94D", "X* c #B5D956", "Y* c #D4E99A", "Z* c #E1F0B6", "`* c #DDEEAE", " = c #D8EBA2", ".= c #CFE690", "+= c #C1DF7A", "@= c #B1D561", "#= c #A0CA49", "$= c #91BF34", "%= c #84AF3D", "&= c #0E425B", "*= c #02476F", "== c #00527B", "-= c #013C65", ";= c #023F67", ">= c #02446C", ",= c #034972", "'= c #044F77", ")= c #075D84", "!= c #09658C", "~= c #0B6D93", "{= c #0E769B", "]= c #1686A8", "^= c #27838B", "/= c #92C008", "(= c #95C400", "_= c #A0CB1B", ":= c #ABD13B", "<= c #B5D754", "[= c #BDDC6B", "}= c #C7E17E", "|= c #D0E68F", "1= c #D3E997", "2= c #AED557", "3= c #AED647", "4= c #B5D954", "5= c #B7DB59", "6= c #B4D956", "7= c #CFE692", "8= c #DEEFB0", "9= c #D9EBA5", "0= c #D0E795", "a= c #C3E07E", "b= c #B3D764", "c= c #A2CC4C", "d= c #92C037", "e= c #87B829", "f= c #4C6A31", "g= c #02466E", "h= c #005179", "i= c #005A82", "j= c #005B82", "k= c #003A60", "l= c #013A62", "m= c #013D66", "n= c #03456D", "o= c #07587F", "p= c #085F86", "q= c #09668D", "r= c #0B6E94", "s= c #0E759B", "t= c #11799D", "u= c #569543", "v= c #87BA00", "w= c #90C103", "x= c #9DC920", "y= c #A9CF3B", "z= c #B3D554", "A= c #BCDB69", "B= c #C5E07C", "C= c #C8E285", "D= c #9CCA49", "E= c #A0CD3F", "F= c #ACD448", "G= c #B3D952", "H= c #B6DB56", "I= c #B5DA54", "J= c #AFD64D", "K= c #C7E284", "L= c #D9EBA4", "M= c #C3E07F", "N= c #B3D765", "O= c #92C138", "P= c #85B729", "Q= c #7EAA28", "R= c #004E76", "S= c #005D85", "T= c #005980", "U= c #004B71", "V= c #003B61", "W= c #01345A", "X= c #013F64", "Y= c #088AA4", "Z= c #086786", "`= c #10829D", " - c #188FA8", ".- c #0A5B7F", "+- c #167091", "@- c #085E85", "#- c #0C698B", "$- c #76AA10", "%- c #7FB400", "&- c #8ABC07", "*- c #98C520", "=- c #A5CD39", "-- c #AFD350", ";- c #B9D965", ">- c #BADA6F", ",- c #87BC3A", "'- c #8DC234", ")- c #9BCB3F", "!- c #A7D146", "~- c #AFD64C", "{- c #B3D84F", "]- c #B4D94F", "^- c #B0D74A", "/- c #A5D144", "(- c #BADB73", "_- c #CEE690", ":- c #C1DE7C", "<- c #B1D662", "[- c #9FCB48", "}- c #90BF35", "|- c #83B627", "1- c #7BB01E", "2- c #005E86", "3- c #005E85", "4- c #00567D", "5- c #004970", "6- c #014167", "7- c #0283A2", "8- c #0495B1", "9- c #08A0B8", "0- c #0FADC3", "a- c #19BCCF", "b- c #2FCAD9", "c- c #4AD3E0", "d- c #2F94AD", "e- c #095E84", "f- c #09648B", "g- c #1D6769", "h- c #73AC00", "i- c #76AE00", "j- c #82B608", "k- c #91C01F", "l- c #9FC935", "m- c #AAD04A", "n- c #A9CF55", "o- c #70AC2A", "p- c #76B427", "q- c #87BE32", "r- c #95C73C", "s- c #A1CE43", "t- c #A9D349", "u- c #AFD64B", "v- c #B1D84B", "w- c #AED649", "x- c #A4D043", "y- c #93C538", "z- c #A4CD5B", "A- c #ACD35B", "B- c #9BC943", "C- c #8DBE31", "D- c #80B425", "E- c #75AB1A", "F- c #4F6C1A", "G- c #02466F", "H- c #006288", "I- c #005D84", "J- c #005378", "K- c #0187AA", "L- c #0183A4", "M- c #058EAB", "N- c #099EB7", "O- c #10AFC5", "P- c #1EBED1", "Q- c #35CADA", "R- c #50D5E2", "S- c #50BCCD", "T- c #0F6387", "U- c #316F47", "V- c #629F00", "W- c #6BA600", "X- c #78AF07", "Y- c #88B91A", "Z- c #97C32E", "`- c #96C139", " ; c #5A991A", ".; c #5EA21B", "+; c #6FAF23", "@; c #7FB92E", "#; c #8DC138", "$; c #99CA3F", "%; c #A1CF44", "&; c #A8D247", "*; c #AAD447", "=; c #A8D245", "-; c #9CCC3E", ";; c #8BC034", ">; c #72B028", ",; c #83B73E", "'; c #A5CE51", "); c #95C53B", "!; c #88BB2C", "~; c #7BB121", "{; c #71A818", "]; c #608919", "^; c #004E77", "/; c #006389", "(; c #005B81", "_; c #006285", ":; c #007DA2", "<; c #017A9E", "[; c #0382A2", "}; c #0791AD", "|; c #0EA4BC", "1; c #18B5CA", "2; c #27C0D3", "3; c #3ACBDA", "4; c #50D4E2", "5; c #5FD2DE", "6; c #589F5B", "7; c #579700", "8; c #609D00", "9; c #6BA505", "0; c #7BB013", "a; c #7CAC1E", "b; c #477E0C", "c; c #4B8A0E", "d; c #569A15", "e; c #64A81D", "f; c #75B227", "g; c #82BB31", "h; c #8EC238", "i; c #96C73D", "j; c #9CCC40", "k; c #9ECD3F", "l; c #99CA3C", "m; c #7BB62A", "n; c #65A720", "o; c #509415", "p; c #679E24", "q; c #8DC032", "r; c #82B726", "s; c #76AD1D", "t; c #6CA516", "u; c #629416", "v; c #014971", "w; c #006188", "x; c #00668C", "y; c #008AAC", "z; c #00799F", "A; c #02779A", "B; c #0584A4", "C; c #0996B2", "D; c #11A8C0", "E; c #1EB5CB", "F; c #2BC0D2", "G; c #3AC8D8", "H; c #43C8D7", "I; c #469650", "J; c #478A00", "K; c #549500", "L; c #5D9B03", "M; c #6DA60E", "N; c #76A81A", "O; c #81B02A", "P; c #8EBB38", "Q; c #99C545", "R; c #A3CD51", "S; c #93C446", "T; c #73B027", "U; c #7EB72E", "V; c #85BD32", "W; c #89BF34", "X; c #89C033", "Y; c #89BF36", "Z; c #B9DA6E", "`; c #AED463", " > c #A2CC54", ".> c #95C345", "+> c #88B936", "@> c #85B929", "#> c #7AB11F", "$> c #70A918", "%> c #65A012", "&> c #588E0E", "*> c #005C83", "=> c #00698D", "-> c #0089AB", ";> c #00799E", ">> c #007197", ",> c #017296", "'> c #037A9C", ")> c #0788A7", "!> c #0C9AB6", "~> c #16A7C0", "{> c #20B2C8", "]> c #29B9CE", "^> c #2FB9CC", "/> c #3D9152", "(> c #408500", "_> c #458900", ":> c #509100", "<> c #5E9A08", "[> c #6CA412", "}> c #7AAF1E", "|> c #88B82B", "1> c #94C238", "2> c #9FCA44", "3> c #8ABC39", "4> c #60A21A", "5> c #68A820", "6> c #6FAD24", "7> c #72AE25", "8> c #70AE24", "9> c #72AF28", "0> c #B2D760", "a> c #AAD155", "b> c #94C439", "c> c #89BC2C", "d> c #7DB421", "e> c #73AC1A", "f> c #67A213", "g> c #5B980D", "h> c #558A0F", "i> c #024870", "j> c #00688D", "k> c #008CAC", "l> c #0080A3", "m> c #00769A", "n> c #007297", "o> c #047699", "p> c #077FA0", "q> c #098DAC", "r> c #0E98B5", "s> c #15A2BC", "t> c #1CA9C1", "u> c #20AAC2", "v> c #318A5F", "w> c #3F8400", "x> c #428600", "y> c #4D8E04", "z> c #5C980B", "A> c #69A213", "B> c #76AC1C", "C> c #81B527", "D> c #8CBD30", "E> c #79AD28", "F> c #4F8E0F", "G> c #559513", "H> c #599A16", "I> c #5C9C17", "J> c #5B9C16", "K> c #5F9D19", "L> c #A1CC49", "M> c #99C840", "N> c #91C235", "O> c #88BC2A", "P> c #7DB520", "Q> c #73AD19", "R> c #68A313", "S> c #5F9C0F", "T> c #59960C", "U> c #4B7B0D", "V> c #004D75", "W> c #005A81", "X> c #0088A8", "Y> c #0080A1", "Z> c #007A9D", "`> c #007A9C", " , c #057D9E", "., c #0985A5", "+, c #0A8BAB", "@, c #0F92B1", "#, c #1297B5", "$, c #1599B6", "%, c #1E7E79", "&, c #448800", "*, c #428601", "=, c #4C8D05", "-, c #58950B", ";, c #649F11", ">, c #6FA718", ",, c #79AF20", "', c #669D1A", "), c #3E7B07", "!, c #448209", "~, c #48870B", "{, c #4A890C", "], c #4F8C0F", "^, c #8FC133", "/, c #8ABD2D", "(, c #82B925", "_, c #7AB31D", ":, c #72AC17", "<, c #69A513", "[, c #629E10", "}, c #5C990E", "|, c #56940A", "1, c #395E0A", "2, c #005178", "3, c #005F85", "4, c #006A8F", "5, c #007798", "6, c #008BAA", "7, c #0086A5", "8, c #0084A4", "9, c #0083A3", "0, c #0383A4", "a, c #0A85A6", "b, c #0B88A9", "c, c #0D89AA", "d, c #0E89AA", "e, c #0C7490", "f, c #41840A", "g, c #3E8400", "h, c #3E8300", "i, c #448602", "j, c #4C8D06", "k, c #5F9B0F", "l, c #568F10", "m, c #316A03", "n, c #357103", "o, c #397604", "p, c #3B7905", "q, c #3C7A05", "r, c #417E08", "s, c #7FB722", "t, c #7BB41D", "u, c #75B019", "v, c #70AB16", "w, c #639F11", "x, c #5D9A0E", "y, c #549209", "z, c #034A71", "A, c #008BA8", "B, c #0091AE", "C, c #008FAD", "D, c #008EAC", "E, c #008AA9", "F, c #0187A7", "G, c #0786A6", "H, c #0A83A5", "I, c #087EA1", "J, c #087294", "K, c #2D712F", "L, c #418600", "M, c #458703", "N, c #4C8D07", "O, c #54930A", "P, c #4A850A", "Q, c #276101", "R, c #2B6602", "S, c #2E6A02", "T, c #306D02", "U, c #316F02", "V, c #377504", "W, c #73AE18", "X, c #6CA714", "Y, c #67A312", "Z, c #5A970D", "`, c #4E8908", " ' c #034467", ".' c #00567C", "+' c #006E92", "@' c #008EAB", "#' c #0099B5", "$' c #0097B3", "%' c #0096B3", "&' c #0092B0", "*' c #008DAC", "=' c #0186A7", "-' c #067EA0", ";' c #097597", ">' c #0F5C64", ",' c #438703", "'' c #438700", ")' c #3D8300", "!' c #3F8301", "~' c #458704", "{' c #4C8C06", "]' c #529109", "^' c #427E07", "/' c #205900", "(' c #235D01", "_' c #266101", ":' c #286401", "<' c #296501", "[' c #2F6B03", "}' c #68A413", "|' c #66A212", "1' c #629F11", "2' c #59970D", "3' c #57940B", "4' c #509007", "5' c #2D4E06", "6' c #02334E", "7' c #006F92", "8' c #0087A5", "9' c #009DB8", "0' c #009CB8", "a' c #009AB6", "b' c #0095B3", "c' c #008FAE", "d' c #0087A7", "e' c #007D9E", "f' c #026989", "g' c #296C2D", "h' c #408401", "i' c #4A8B06", "j' c #3B7704", "k' c #1A5200", "l' c #1D5600", "m' c #1F5900", "n' c #215B00", "o' c #225C01", "p' c #286202", "q' c #5E9B0F", "r' c #58950C", "s' c #56940B", "t' c #519107", "u' c #478206", "v' c #006D90", "w' c #0083A2", "x' c #0097B4", "y' c #0098B5", "z' c #0099B6", "A' c #0098B4", "B' c #0092AF", "C' c #007E9E", "D' c #036378", "E' c #397C12", "F' c #468A00", "G' c #418501", "H' c #448703", "I' c #357203", "J' c #164C00", "K' c #184F00", "L' c #1B5400", "M' c #1C5500", "N' c #225B01", "O' c #57950B", "P' c #56940C", "Q' c #55930A", "R' c #4B8C04", "S' c #02405E", "T' c #005C81", "U' c #006F91", "V' c #0087A8", "W' c #0091B0", "X' c #0094B2", "Y' c #0089A8", "Z' c #00809F", "`' c #09696F", " ) c #3E810A", ".) c #498C00", "+) c #488B00", "@) c #468900", "#) c #488A03", "$) c #4D8D06", "%) c #508E08", "&) c #529009", "*) c #54910A", "=) c #56930B", "-) c #57940C", ";) c #53910A", ">) c #54920B", ",) c #549208", "') c #509005", ")) c #498B02", "!) c #224004", "~) c #011B28", "{) c #014D6B", "]) c #007093", "^) c #007598", "/) c #007DA0", "() c #0084A5", "_) c #0089A9", ":) c #007A99", "<) c #0A5E62", "[) c #3B7E0E", "}) c #478B00", "|) c #4B8D00", "1) c #4C8E00", "2) c #4A8D00", "3) c #4B8C00", "4) c #4C8D03", "5) c #4E8E05", "6) c #508F06", "7) c #519008", "8) c #539108", "9) c #549207", "0) c #539206", "a) c #519104", "b) c #4C8E02", "c) c #478900", "d) c #203D03", "e) c #000101", "f) c #021A25", "g) c #013F59", "h) c #006185", "i) c #007C9E", "j) c #006E91", "k) c #00678A", "l) c #045467", "m) c #2B6B20", "n) c #4E8F00", "o) c #509000", "p) c #519100", "q) c #519200", "r) c #529200", "s) c #539200", "t) c #539300", "u) c #4A8C00", "v) c #3E7802", "w) c #132402", "x) c #000000", "y) c #000204", "z) c #021924", "A) c #023244", "B) c #013D56", "C) c #004866", "D) c #015072", "E) c #005477", "F) c #005275", "G) c #014A6C", "H) c #003852", "I) c #103321", "J) c #316002", "K) c #468800", "L) c #4D8E00", "M) c #070E01", "N) c #1B3402", "O) c #2A5102", "P) c #346403", "Q) c #376A01", "R) c #376902", "S) c #305B02", "T) c #224303", " ", " ", " . + @ # $ % & * = - ", " ; > , ' ) ! ~ { ] ^ / ( ( _ : < ", " [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h ", " i j k l m n o p q r s t u v w x y z A B C D E F ", " G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.#.$. ", " %.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2...3.4.5.6. ", " 7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.<.n.o.p.q.q.p.r.s.t.u.v.w.x.y. ", " z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+ ", " %+&+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+:+<+[+}+|+1+2+3+4+W.5+6+7+8+9+0+a+ ", " b+c+A.d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+ ", " K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@U.,@'@)@!@~@{@]@ ", " ^@/@L+(@_@:@<@[@}@|@1@2@3@4@5@6@7@8@9@0@a@#@b@c@d@e@e@f@*@-@g@h@i@j@k@l@m@n@o@ ", " p@q@q@r@s@t@u@v@w@B x@y@z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@f@%@P@Q@R@S@T@U@V@W@X@Y@ ", " Z@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#0@)#!#~#{#L@]#^#^#M@/#(#_#:#<#[#}#|#1#2#3#4# ", " 5#6#7#8#9#0#a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#K@r#s#t#u#]#v#w#x#y#z#A#B#C#D#E#F#G#H# ", " I#J#s@K#L#M#N#O#P#Q#O#R#S#T#i#U#V#W#X#Y#Z#`# $/#M@^#.$u#+$@$#$$$Z#%$&$*$=$-$;$>$,$'$ ", " )$!$~${$]$^$/$($_$:$<$[$}$|$1$2$3$4$m#+@y#`#5$e@N@6$^#]#L@7$8$p#9$0$a$b$c$d$e$f$g$h$ ", " i$j$k$l$m$n$o$p$q$r$s$t$u$v$w$x$y$z$A$B$C$@@D$%@f@E$F$N@G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$ ", " W$X$Y$Z$`$ %.%+%@%#%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%|%1%2%3%4%5%6%7%8%9%0% ", " a%b%c%d%e%f%g%h%i%j%k%l%m%n%o%p%q%r%s%W#t%t+u%w+v%w%x%y%z%A%B%C%D%E%F%G%H%I%J%K%L%M%N%O% ", " P%Q%9#R%S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&<&[&e#}&|&1& ", " 7#2&3&4&P%5&6&7&8&9&0&a&b&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&r&s&t&u&v&w&x&y&z&A&B&C&D&E&F&G& ", " `@H&I&J&K&L&M&N&O&P&Q&R&Z%S&&%T&U&V&W&X&Y&Z&`& *.*+*@*#*$*%*&***=*-*;*>*,*'*)*!*~*{*]*^* ", " `@/*(*_*(*:*T%g%<*W%[*}*|*1*2*3*4*5*6*7*8*9*0*a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u* ", " v*/*_@w*w*x*y*.%z*A*B*C*D*E*F*G*H*I*J*K*L*M*N*O*P*Q*R*S*T*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=&= ", " *===N+_@c%l$L&-=;=>=,='=0&)=!=~={=H*]=^=/=(=_=:=<=[=}=|=1=2=3=4=5=6=7=8=9=0=a=b=c=d=e=f= ", " g=h=i=j=6#K&k=l=m=;=n=K+X%o=p=q=r=s=t=u=v=w=x=y=z=A=B=C=D=E=F=G=H=I=J=K=L=0=M=N=c=O=P=Q= ", " R=N+S=T=U=V=W=X=Y=Z=`= -.-+-@-q=~=#-$-%-&-*-=---;->-,-'-)-!-~-{-]-^-/-(-_-:-<-[-}-|-1- ", " q@_@2-3-4-5-6-7-8-9-0-a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-p*A-B-C-D-E-F- ", " G-/*S=H-I-x*J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z-`- ;.;+;@;#;$;%;&;*;=;-;;;>;,;';);!;~;{;]; ", " ^;j=/;/;(;_;:;<;[;};|;1;2;3;4;5;6;7;8;9;0;a;b;c;d;e;f;g;h;i;j;k;l;'-m;n;o;p;q;r;s;t;u; ", " v;4-w;x;3&y;z;&.A;B;C;D;E;F;G;H;I;J;K;L;M;N;O;P;Q;R;S;T;U;V;W;X;Y;Z;`; >.>+>@>#>$>%>&> ", " K#*>x;=>->;>>>,>'>)>!>~>{>]>^>/>(>_>:><>[>}>|>1>2>3>4>5>6>7>8>9>0>a>[-b>c>d>e>f>g>h> ", " i>4-H-j>k>l>m>n>o>p>q>r>s>t>u>v>w>(>x>y>z>A>B>C>D>E>F>G>H>I>J>K>L>M>N>O>P>Q>R>S>T>U> ", " V>W>x;b%X>Y>Z>`> ,.,+,@,#,$,%,&,w>w>*,=,-,;,>,,,',),!,~,{,{,],^,/,(,_,:,<,[,},|,1, ", " 2,3,4,5,6,7,8,9,0,a,b,c,d,e,f,(>g,h,i,j,|,k,f>l,m,n,o,p,q,r,s,t,u,v,<,w,x,T>y, ", " z,s@H-X$A,B,C,D,E,F,G,H,I,J,K,L,(>h,h,M,N,O,},P,Q,R,S,T,U,V,W,v,X,Y,[,x,Z,|,`, ", " '.'/;+'@'#'$'%'&'*'='-';'>','''(>)'!'~'{']'^'/'('_':'<'['}'|'1'S>},2'3'4'5' ", " 6'.'~$7'8'9'0'a'b'c'd'e'f'g'&,&,x>w>h'M,i'j'k'l'm'n'o'p'q'x,g>2'r's't'u' ", " 6#!$v'w'x'y'z'A'B'E,C'D'E'_>F'&,L,G'H'I'J'K'k'L'M'N'O's'P's'Q't'R' ", " S'T'U'V'k>W'b'X'c'Y'Z'`' )J;.)+)@)&,#)$)%)&)*)=)-);)>)Q',)')))!) ", " ~){)])^)/)()X>_)6,6,:)<)[)})|)1)|)2)3)4)5)6)7)8)9)0)a)b)c)d) ", " e)f)g)h)_*^)i)5,j)v'k)l)m)J;|)n)o)p)q)r)s)t)r)p)n)u)v)w) ", " x)y)z)A)B)C)D)E)F)G)H)I)J)K)|)n)o)p)p)o)L)u)v)d) ", " M)N)O)P)Q)R)S)T) ", " "}; tqsl-2.0/apps/tqslwiz.h0000664000076400007640000000626712231073120015201 0ustar rmurphyrmurphy/*************************************************************************** tqslwiz.h - description ------------------- begin : Tue Nov 5 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslwiz_h #define __tqslwiz_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "extwizard.h" #include "wx/radiobox.h" #include "certtree.h" #ifndef ADIF_BOOLEAN #define ADIF_BOOLEAN // Hack! #endif #include "tqsllib.h" #include #include #define TQSL_ID_LOW 6000 class TQSLWizPage; class TQSLWizard : public ExtWizard { public: TQSLWizard(tQSL_Location locp, wxWindow *parent, wxHtmlHelpController *help = 0, const wxString& title = wxEmptyString, bool expired = false); // TQSLWizard(tQSL_Location locp, wxWindow* parent, int id = -1, const wxString& title = wxEmptyString, // const wxBitmap& bitmap = wxNullBitmap, const wxPoint& pos = wxDefaultPosition); TQSLWizPage *GetPage(bool final = false); TQSLWizPage *GetCurrentTQSLPage() { return (TQSLWizPage *)GetCurrentPage(); } void SetLocationName(wxString& s) { sl_name = s; } void SetDefaultCallsign(wxString& c) {sl_call = c; }; wxString GetLocationName() { return sl_name; } wxString GetDefaultCallsign() {return sl_call; }; TQSLWizPage *GetFinalPage() { return (_pages.size() > 0) ? _pages[0] : 0; } bool page_changing; bool expired; private: void OnPageChanged(wxWizardEvent&); wxString sl_name; wxString sl_call; tQSL_Location loc; int _curpage; std::map _pages; TQSLWizPage *final; DECLARE_EVENT_TABLE() }; class TQSLWizPage : public ExtWizard_Page { public: TQSLWizPage(TQSLWizard *parent, tQSL_Location locp) : ExtWizard_Page(parent) { loc = locp; } virtual TQSLWizard *GetParent() const { return (TQSLWizard *)wxWindow::GetParent(); } tQSL_Location loc; }; class TQSLWizCertPage : public TQSLWizPage { public: TQSLWizCertPage(TQSLWizard *parent, tQSL_Location locp); ~TQSLWizCertPage(); virtual bool TransferDataFromWindow(); void OnComboBoxEvent(wxCommandEvent&); void OnCheckBoxEvent(wxCommandEvent&); int loc_page; void UpdateFields(int noupdate_field = -1); virtual const char *validate(); virtual TQSLWizPage *GetPrev() const; virtual TQSLWizPage *GetNext() const; void OnSize(wxSizeEvent&); const char *valMsg; private: std::vector controls; wxCheckBox *okEmptyCB; DECLARE_EVENT_TABLE() }; class TQSLWizFinalPage : public TQSLWizPage { public: TQSLWizFinalPage(TQSLWizard *parent, tQSL_Location locp, TQSLWizPage *i_prev); TQSLWizPage *GetPrev() const { return prev; } TQSLWizPage *GetNext() const { return 0; } TQSLWizPage *prev; virtual bool TransferDataFromWindow(); void OnListbox(wxCommandEvent &); virtual const char *validate(); private: wxListBox *namelist; wxTextCtrl *newname; wxBoxSizer *sizer; std::vector item_data; DECLARE_EVENT_TABLE() }; #endif // __tqslwiz_h tqsl-2.0/apps/tqslwiz.cpp0000664000076400007640000004267412231073120015536 0ustar rmurphyrmurphy/*************************************************************************** tqslwiz.cpp - description ------------------- begin : Tue Nov 5 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: tqslwiz.cpp,v 1.6 2013/03/01 13:12:57 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "tqslwiz.h" #include "wxutil.h" #include "tqsltrace.h" #include using namespace std; #define TQSL_LOCATION_FIELD_UPPER 1 #define TQSL_LOCATION_FIELD_MUSTSEL 2 #define TQSL_LOCATION_FIELD_SELNXT 4 BEGIN_EVENT_TABLE(TQSLWizard, wxWizard) EVT_WIZARD_PAGE_CHANGED(-1, TQSLWizard::OnPageChanged) END_EVENT_TABLE() BEGIN_EVENT_TABLE(TQSLWizCertPage, TQSLWizPage) EVT_COMBOBOX(-1, TQSLWizCertPage::OnComboBoxEvent) EVT_CHECKBOX(-1, TQSLWizCertPage::OnCheckBoxEvent) EVT_SIZE(TQSLWizCertPage::OnSize) END_EVENT_TABLE() void TQSLWizard::OnPageChanged(wxWizardEvent& ev) { tqslTrace("TQSLWizard::OnPageChanged"); ((TQSLWizPage *)GetCurrentPage())->SetFocus(); ExtWizard::OnPageChanged(ev); } TQSLWizard::TQSLWizard(tQSL_Location locp, wxWindow *parent, wxHtmlHelpController *help, const wxString& title, bool expired) : ExtWizard(parent, help, title), loc(locp), _curpage(-1) { tqslTrace("TQSLWizard::TQSLWizard", "locp=0x%lx, parent=0x%lx, title=%s, expired=%d", (void *)locp, (void *)parent, _S(title), expired); char buf[256]; if (!tqsl_getStationLocationCaptureName(locp, buf, sizeof buf)) { wxString s(buf, wxConvLocal); SetLocationName(s); } tqsl_setStationLocationCertFlags(locp, expired ? TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED : TQSL_SELECT_CERT_WITHKEYS); tqsl_setStationLocationCapturePage(locp, 1); } TQSLWizPage * TQSLWizard::GetPage(bool final) { tqslTrace("TQSLWizard::GetPage", "final=%d", final); int page_num; page_changing = false; if (final) page_num = 0; else if (tqsl_getStationLocationCapturePage(loc, &page_num)) return 0; if (_pages[page_num]) { if (page_num == 0) ((TQSLWizFinalPage *)_pages[0])->prev = GetCurrentTQSLPage(); return _pages[page_num]; } if (page_num == 0) _pages[page_num] = new TQSLWizFinalPage(this, loc, GetCurrentTQSLPage()); else _pages[page_num] = new TQSLWizCertPage(this, loc); _curpage = page_num; if (page_num == 0) ((TQSLWizFinalPage *)_pages[0])->prev = GetCurrentTQSLPage(); return _pages[page_num]; } void TQSLWizCertPage::OnSize(wxSizeEvent& ev) { TQSLWizPage::OnSize(ev); //fix this UpdateFields(); } TQSLWizPage * TQSLWizCertPage::GetPrev() const { tqslTrace("TQSLWizCertPage::GetPrev"); int rval; if (tqsl_hasPrevStationLocationCapture(loc, &rval) || !rval) { GetParent()->page_changing = false; return 0; } if ((TQSLWizard *)GetParent()->page_changing) { tqsl_prevStationLocationCapture(loc); return GetParent()->GetPage(); } return GetParent()->GetPage(); } TQSLWizPage * TQSLWizCertPage::GetNext() const { tqslTrace("TQSLWizCertPage::GetNext"); TQSLWizPage *newp; bool final = false; if (GetParent()->page_changing) { int rval; if (!tqsl_hasNextStationLocationCapture(loc, &rval) && rval) { tqsl_nextStationLocationCapture(loc); } else final = true; } newp = GetParent()->GetPage(final); return newp; } void TQSLWizCertPage::UpdateFields(int noupdate_field) { tqslTrace("TQSLWizCertPage::UpdateFields", "noupdate_field=%d", noupdate_field); wxSize text_size = getTextSize(this); if (noupdate_field >= 0) tqsl_updateStationLocationCapture(loc); if (noupdate_field <= 0) { int flags; tqsl_getLocationFieldFlags(loc, 0, &flags); if (flags == TQSL_LOCATION_FIELD_SELNXT) { int index; bool fwdok = false; tqsl_getLocationFieldIndex(loc, 0, &index); if (index > 0) fwdok = true; if (okEmptyCB && okEmptyCB->IsChecked()) fwdok = true; wxWindow *but = GetParent()->FindWindow(wxID_FORWARD); if (but) { but->Enable(fwdok); } if (okEmptyCB) { if (index > 0) okEmptyCB->Enable(false); else okEmptyCB->Enable(true); } } } for (int i = noupdate_field+1; i < (int)controls.size(); i++) { int changed; int in_type; tqsl_getLocationFieldChanged(loc, i, &changed); tqsl_getLocationFieldInputType(loc, i, &in_type); if (noupdate_field >= 0 && !changed && in_type != TQSL_LOCATION_FIELD_BADZONE) continue; if (in_type == TQSL_LOCATION_FIELD_DDLIST || in_type == TQSL_LOCATION_FIELD_LIST) { // Update this list int text_width = 0; char gabbi_name[40]; tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name); int selected; bool defaulted = false; tqsl_getLocationFieldIndex(loc, i, &selected); int new_sel = 0; wxString old_sel = ((wxComboBox *)controls[i])->GetStringSelection(); if (old_sel.IsEmpty() && strcmp(gabbi_name, "CALL") == 0) { old_sel = ((TQSLWizard*)GetParent())->GetDefaultCallsign(); if (!old_sel.IsEmpty()) defaulted = true; // Set from default } ((wxComboBox *)controls[i])->Clear(); int nitems; tqsl_getNumLocationFieldListItems(loc, i, &nitems); for (int j = 0; j < nitems && j < 2000; j++) { char item[80]; tqsl_getLocationFieldListItem(loc, i, j, item, sizeof(item)); /* For Alaska counties, it's pseudo-county name * followed by a '|' then the real county name. */ char *p = strchr(item, '|'); if (p) *p = '\0'; wxString item_text(item, wxConvLocal); ((wxComboBox *)controls[i])->Append(item_text); if (item_text == old_sel) new_sel = j; wxCoord w, h; ((wxComboBox *)controls[i])->GetTextExtent(item_text, &w, &h); if (w > text_width) text_width = w; } if (text_width > 0) { int w, h; ((wxComboBox *)controls[i])->GetSize(&w, &h); ((wxComboBox *)controls[i])->SetSize(text_width + text_size.GetWidth()*4, h); } if (noupdate_field < 0 && !defaulted) new_sel = selected; ((wxComboBox *)controls[i])->SetSelection(new_sel); tqsl_setLocationFieldIndex(loc, i, new_sel); if (noupdate_field >= 0) tqsl_updateStationLocationCapture(loc); ((wxComboBox *)controls[i])->Enable(nitems > 1); } else if (in_type == TQSL_LOCATION_FIELD_TEXT) { int len; tqsl_getLocationFieldDataLength(loc, i, &len); int w, h; ((wxTextCtrl *)controls[i])->GetSize(&w, &h); ((wxTextCtrl *)controls[i])->SetSize((len+1)*text_size.GetWidth(), h); if (noupdate_field < 0) { char buf[256]; tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf); ((wxTextCtrl *)controls[i])->SetValue(wxString(buf, wxConvLocal)); } } else if (in_type == TQSL_LOCATION_FIELD_BADZONE) { int len; tqsl_getLocationFieldDataLength(loc, i, &len); int w, h; ((wxStaticText *)controls[i])->GetSize(&w, &h); ((wxStaticText *)controls[i])->SetSize((len+1)*text_size.GetWidth(), h); char buf[256]; tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf); ((wxStaticText *)controls[i])->SetLabel(wxString(buf, wxConvLocal)); if (strlen(buf) == 0) { this->GetParent()->FindWindow(wxID_FORWARD)->Enable(true); if (valMsg) ((wxStaticText *)controls[i])->SetLabel(wxString(valMsg, wxConvLocal)); } else { this->GetParent()->FindWindow(wxID_FORWARD)->Enable(false); } } } } void TQSLWizCertPage::OnComboBoxEvent(wxCommandEvent& event) { tqslTrace("TQSLWizCertPage::OnComboBoxEvent"); int control_idx = event.GetId() - TQSL_ID_LOW; if (control_idx < 0 || control_idx >= (int)controls.size()) return; int in_type; tqsl_getLocationFieldInputType(loc, control_idx, &in_type); switch (in_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: tqsl_setLocationFieldIndex(loc, control_idx, event.GetInt()); UpdateFields(control_idx); break; } } void TQSLWizCertPage::OnCheckBoxEvent(wxCommandEvent& event) { UpdateFields(-1); } TQSLWizCertPage::TQSLWizCertPage(TQSLWizard *parent, tQSL_Location locp) : TQSLWizPage(parent, locp) { tqslTrace("TQSLWizCertPage::TQSLWizCertPage", "parent=0x%lx, locp=0x%lx", (void *)parent, (void *)locp); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); int control_width = getTextSize(this).GetWidth() * 20; valMsg = NULL; tqsl_getStationLocationCapturePage(loc, &loc_page); wxScreenDC sdc; int label_w = 0; int numf; tqsl_getNumLocationField(loc, &numf); for (int i = 0; i < numf; i++) { wxCoord w, h; char label[256]; tqsl_getLocationFieldDataLabel(loc, i, label, sizeof label); sdc.GetTextExtent(wxString(label, wxConvLocal), &w, &h); if (w > label_w) label_w = w; } wxCoord max_label_w, max_label_h; // Measure width of longest expected label string sdc.GetTextExtent(wxT("Longest label expected"), &max_label_w, &max_label_h); bool addCheckbox = false; wxString cbLabel; for (int i = 0; i < numf; i++) { char label[256]; int in_type, flags; wxBoxSizer *hsizer; tqsl_getLocationFieldDataLabel(loc, i, label, sizeof label); tqsl_getLocationFieldInputType(loc, i, &in_type); if (in_type != TQSL_LOCATION_FIELD_BADZONE) { hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxString(label, wxConvLocal), wxDefaultPosition, wxSize(label_w, -1), wxALIGN_RIGHT/*|wxST_NO_AUTORESIZE*/), 0, wxTOP, 5); } wxWindow *control_p = 0; char gabbi_name[256]; tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name); tqsl_getLocationFieldFlags(loc, i, &flags); switch(in_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: control_p = new wxComboBox(this, TQSL_ID_LOW+i, wxT(""), wxDefaultPosition, wxSize(control_width, -1), 0, 0, wxCB_DROPDOWN|wxCB_READONLY); if (flags & TQSL_LOCATION_FIELD_SELNXT) { addCheckbox = true; cbLabel = wxString(label, wxConvLocal); } break; case TQSL_LOCATION_FIELD_TEXT: control_p = new wxTextCtrl(this, TQSL_ID_LOW+i, wxT(""), wxDefaultPosition, wxSize(control_width, -1)); break; case TQSL_LOCATION_FIELD_BADZONE: wxCoord w, h; int tsize; tqsl_getLocationFieldDataLength(loc, i, &tsize); tsize /= 2; sdc.GetTextExtent(wxString("X", wxConvLocal), &w, &h); control_p = new wxStaticText(this, -1, wxT(""), wxDefaultPosition, wxSize(w*tsize, -1), wxALIGN_LEFT|wxST_NO_AUTORESIZE); break; } controls.push_back(control_p); if (in_type != TQSL_LOCATION_FIELD_BADZONE) { hsizer->Add(control_p, 0, wxLEFT|wxTOP, 5); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT, 10); } else { sizer->Add(control_p, 0, wxEXPAND | wxLEFT| wxRIGHT, 10); } } if (addCheckbox) { wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); okEmptyCB = new wxCheckBox(this, TQSL_ID_LOW+numf, wxT("Allow 'None' for ") + cbLabel, wxDefaultPosition, wxDefaultSize); hsizer->Add(new wxStaticText(this, -1, wxT(""), wxDefaultPosition, wxSize(label_w, -1), wxALIGN_RIGHT|wxST_NO_AUTORESIZE), 0, wxTOP, 5); hsizer->Add(okEmptyCB, 0, wxLEFT|wxTOP, 5); sizer->Add(hsizer, 0, wxLEFT|wxRight, 10); } else okEmptyCB = 0; UpdateFields(); AdjustPage(sizer, wxT("stnloc1.htm")); } TQSLWizCertPage::~TQSLWizCertPage() { } const char * TQSLWizCertPage::validate() { tqslTrace("TQSLWizCertPage::validate"); static char errtxt[128]; wxString error; error = wxT(""); tqsl_setStationLocationCapturePage(loc, loc_page); for (int i = 0; i < (int)controls.size(); i++) { char gabbi_name[40]; tqsl_getLocationFieldDataGABBI(loc, i, gabbi_name, sizeof gabbi_name); if (strcmp(gabbi_name, "GRIDSQUARE") == 0) { wxString gridVal = ((wxTextCtrl *)controls[i])->GetValue(); if (gridVal.size() == 0) { return 0; } wxString editedGrids = wxT(""); wxStringTokenizer grids(gridVal, wxT(",")); // Comma-separated list of squares while (grids.HasMoreTokens()) { wxString grid = grids.GetNextToken().Trim().Trim(false); // Truncate to six character field grid = grid.Left(6); if (grid[0] <= 'z' && grid[1] >= 'a') grid[0] = grid[0] - 'a' + 'A'; // Upper case first two if (grid.size() > 1 && (grid[1] <= 'z' && grid[1] >= 'a')) grid[1] = grid[1] - 'a' + 'A'; if (grid[0] < 'A' || grid[0] > 'R') { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square Field"), grid.c_str()); } if (grid.size() > 1 && (grid[1] < 'A' || grid[1] > 'R')) { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square Field"), grid.c_str()); } if (grid.size() > 2 && (grid[2] < '0' || grid[2] > '9')) { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square"), grid.c_str()); } if (grid.size() < 4) { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square"), grid.c_str()); } if (grid[3] < '0' || grid[3] > '9') { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square"), grid.c_str()); } if (grid.size() > 4 && (grid[4] <= 'Z' && grid[4] >= 'A')) grid[4] = grid[4] - 'A' + 'a'; // Lower case subsquare if (grid.size() > 5 && (grid[5] <= 'Z' && grid[5] >= 'A')) grid[5] = grid[5] - 'A' + 'a'; if (grid.size() > 4 && (grid[4] < 'a' || grid[4] > 'x')) { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Subsquare"), grid.c_str()); } if (grid.size() > 5 && (grid[5] < 'a' || grid[5] > 'x')) { if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Subsquare"), grid.c_str()); } if (grid.size() != 6 && grid.size() != 4) { // Not long enough yet or too long. if (error.IsEmpty()) error = wxString::Format(wxT("%s: Invalid Grid Square"), grid.c_str()); } if (!editedGrids.IsEmpty()) editedGrids += wxT(","); editedGrids += grid; ((wxTextCtrl *)controls[i])->SetValue(editedGrids); tqsl_setLocationFieldCharData(loc, i, ((wxTextCtrl *)controls[i])->GetValue().mb_str()); } if (error.IsEmpty()) return 0; strncpy(errtxt, error.mb_str(), sizeof errtxt); return errtxt; } } return 0; } bool TQSLWizCertPage::TransferDataFromWindow() { tqslTrace("TQSLWizCertPage::TransferDataFromWindow"); valMsg = validate(); if (!valMsg) GetParent()->page_changing = true; else GetParent()->page_changing = false; tqsl_setStationLocationCapturePage(loc, loc_page); for (int i = 0; i < (int)controls.size(); i++) { int in_type; tqsl_getLocationFieldInputType(loc, i, &in_type); switch(in_type) { case TQSL_LOCATION_FIELD_DDLIST: case TQSL_LOCATION_FIELD_LIST: break; case TQSL_LOCATION_FIELD_TEXT: tqsl_setLocationFieldCharData(loc, i, ((wxTextCtrl *)controls[i])->GetValue().mb_str()); break; #if 0 case TQSL_LOCATION_FIELD_BADZONE: if (vmsg) tqsl_setLocationFieldCharData(loc, i, vmsg); break; #endif } } return true; } BEGIN_EVENT_TABLE(TQSLWizFinalPage, TQSLWizPage) EVT_LISTBOX(TQSL_ID_LOW, TQSLWizFinalPage::OnListbox) EVT_LISTBOX_DCLICK(TQSL_ID_LOW, TQSLWizFinalPage::OnListbox) EVT_TEXT(TQSL_ID_LOW+1, TQSLWizFinalPage::check_valid) END_EVENT_TABLE() void TQSLWizFinalPage::OnListbox(wxCommandEvent &) { tqslTrace("TQSLWizFinalPage::OnListbox"); if (namelist->GetSelection() >= 0) { const char *cp = (const char *)(namelist->GetClientData(namelist->GetSelection())); if (cp) newname->SetValue(wxString(cp, wxConvLocal)); } } TQSLWizFinalPage::TQSLWizFinalPage(TQSLWizard *parent, tQSL_Location locp, TQSLWizPage *i_prev) : TQSLWizPage(parent, locp), prev(i_prev) { tqslTrace("TQSLWizFinalPage::TQSLWizFinalPage", "parent=0x%lx, locp=0x%lx, i_prev=0x%lx", (void *) parent, (void *)locp, (void *) i_prev); wxSize text_size = getTextSize(this); int control_width = text_size.GetWidth()*30; int y = text_size.GetHeight(); sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("Station Data input complete")); sizer->Add(st, 0, wxALIGN_CENTER|wxTOP, 10); // Title st = new wxStaticText(this, -1, wxT("Select or enter name of this station location")); sizer->Add(st, 0, wxALIGN_CENTER|wxBOTTOM, 10); // List of existing location names namelist = new wxListBox(this, TQSL_ID_LOW, wxDefaultPosition, wxSize(control_width, text_size.GetHeight()*10), 0, 0, wxLB_SINGLE|wxLB_HSCROLL|wxLB_NEEDED_SB); sizer->Add(namelist, 0, wxEXPAND); int n; tqsl_getNumStationLocations(locp, &n); for (int i = 0; i < n; i++) { char buf[256]; tqsl_getStationLocationName(loc, i, buf, sizeof buf); item_data.push_back(wxString(buf, wxConvLocal)); char cbuf[256]; tqsl_getStationLocationCallSign(loc, i, cbuf, sizeof cbuf); wxString s(buf, wxConvLocal); s += (wxString(wxT(" (")) + wxString(cbuf, wxConvLocal) + wxString(wxT(")"))); const void *v = item_data.back().mb_str(); namelist->Append(s, (void *)v); } if (namelist->GetCount() > 0) namelist->SetSelection(0, FALSE); // New name st = new wxStaticText(this, -1, wxT("Station Location Name")); sizer->Add(st, 0, wxALIGN_LEFT|wxTOP, 10); newname = new wxTextCtrl(this, TQSL_ID_LOW+1, wxT(""), wxPoint(0, y), wxSize(control_width, -1)); sizer->Add(newname, 0, wxEXPAND); newname->SetValue(parent->GetLocationName()); AdjustPage(sizer, wxT("stnloc2.htm")); } bool TQSLWizFinalPage::TransferDataFromWindow() { tqslTrace("TQSLWizFinalPage::TransferDataFromWindow"); if (validate()) // Must be a "back" return true; wxString s = newname->GetValue(); ((TQSLWizard *)GetParent())->SetLocationName(s); return true; } const char * TQSLWizFinalPage::validate() { tqslTrace("TQSLWizFinalPage::validate"); wxString val = newname->GetValue(); const char *errmsg = 0; val.Trim().Trim(false); if (val == wxT("")) errmsg = "Station name must be provided"; return errmsg; } tqsl-2.0/apps/tqslversion.ver0000664000076400007640000000000412231073120016401 0ustar rmurphyrmurphy2.0 tqsl-2.0/apps/tqslvalidator.h0000664000076400007640000000430012231073120016337 0ustar rmurphyrmurphy/*************************************************************************** tqslvalidator.h - description ------------------- begin : Sun Dec 8 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #ifndef TQSLVALIDATOR_H #define TQSLVALIDATOR_H #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "tqsllib.h" #include "wx/grid.h" #include /** Classes work with wxWindows wxTextCtrl to validate TQSL Date/Time entries. * *@author Jon Bloom */ class TQSLValidator : public wxValidator { public: TQSLValidator(void *objp); TQSLValidator(const TQSLValidator& val) { Copy(val); } virtual ~TQSLValidator() {} virtual bool Copy(const TQSLValidator&); virtual bool Validate(wxWindow*); virtual bool TransferToWindow(); virtual bool TransferFromWindow(); virtual wxString ToString() = 0; virtual void FromString(const wxString&) = 0; virtual bool IsValid(const wxString&) = 0; protected: wxString _type; void *_objp; }; class TQSLDateValidator : public TQSLValidator { public: TQSLDateValidator(tQSL_Date *date) : TQSLValidator(date) { _type = wxT("Date"); } TQSLDateValidator(const TQSLDateValidator& val) : TQSLValidator(val) {} virtual ~TQSLDateValidator() {} virtual wxObject *Clone() const { return new TQSLDateValidator(*this); } virtual wxString ToString(); virtual void FromString(const wxString&); virtual bool IsValid(const wxString&); }; class TQSLTimeValidator : public TQSLValidator { public: TQSLTimeValidator(tQSL_Time *time) : TQSLValidator(time) { _type = wxT("Time"); } TQSLTimeValidator(const TQSLTimeValidator& val) : TQSLValidator(val) {} virtual ~TQSLTimeValidator() {} virtual wxObject *Clone() const { return new TQSLTimeValidator(*this); } virtual wxString ToString(); virtual void FromString(const wxString&); virtual bool IsValid(const wxString&); }; #endif // TQSLVALIDATOR_H tqsl-2.0/apps/tqslvalidator.cpp0000664000076400007640000000653612231073120016707 0ustar rmurphyrmurphy/*************************************************************************** tqslvalidator.cpp - description ------------------- begin : Sun Dec 8 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "tqslvalidator.h" #include "tqsltrace.h" TQSLValidator::TQSLValidator(void *objp) { _objp = objp; } bool TQSLValidator::Copy(const TQSLValidator& val) { tqslTrace("TQSLValidator::Copy"); wxValidator::Copy(val); _objp = val._objp; _type = val._type; return TRUE; } bool TQSLValidator::TransferFromWindow() { tqslTrace("TQSLValidator::TransferFromWindow"); if (!m_validatorWindow) return FALSE; if (!m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl))) return FALSE; if (_objp == 0) return FALSE; wxTextCtrl *ctl = (wxTextCtrl *) m_validatorWindow; wxString str = ctl->GetValue(); FromString(str); return TRUE; } bool TQSLValidator::TransferToWindow() { tqslTrace("TQSLValidator::TransferToWindow"); if (!m_validatorWindow) return FALSE; if (!m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl))) return FALSE; if (_objp == 0) return FALSE; wxString str = this->ToString(); wxTextCtrl *ctl = (wxTextCtrl *) m_validatorWindow; ctl->SetValue(str); return TRUE; } bool TQSLValidator::Validate(wxWindow* parent) { tqslTrace("TQSLValidator::Validate", "parent=%lx", (void *)parent); if (!m_validatorWindow) return FALSE; if (!m_validatorWindow->IsKindOf(CLASSINFO(wxTextCtrl))) return FALSE; if (_objp == 0) return FALSE; wxTextCtrl *ctl = (wxTextCtrl *) m_validatorWindow; wxString str = ctl->GetValue(); if (!IsValid(str)) { m_validatorWindow->SetFocus(); wxString buf; buf.Printf(wxT("Invalid %s: \"%s\""), (const char *)_type.mb_str(), (const char *)str.mb_str()); wxMessageBox(buf, wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, parent); return FALSE; } return TRUE; } void TQSLDateValidator::FromString(const wxString& str) { if (_objp != 0) tqsl_initDate((tQSL_Date *)_objp, str.mb_str()); } wxString TQSLDateValidator::ToString() { if (_objp == 0) return wxT(""); tQSL_Date *_datep = (tQSL_Date *)_objp; if (!tqsl_isDateValid(_datep)) return wxT(""); char buf[20]; tqsl_convertDateToText(_datep, buf, sizeof buf); return wxString(buf, wxConvLocal); } bool TQSLDateValidator::IsValid(const wxString& str) { tqslTrace("TQSLDateValidator::IsValid", "str=%s", _S(str)); tQSL_Date d; return (!tqsl_initDate(&d, str.mb_str()) && tqsl_isDateValid(&d)); } void TQSLTimeValidator::FromString(const wxString& str) { tqslTrace("TQSLTimeValidator::FromString", "str=%s", _S( str)); if (_objp != 0) tqsl_initTime((tQSL_Time *)_objp, str.mb_str()); } wxString TQSLTimeValidator::ToString() { if (_objp == 0) return wxT(""); tQSL_Time *_timep = (tQSL_Time *)_objp; if (!tqsl_isTimeValid(_timep)) return wxT(""); char buf[20]; tqsl_convertTimeToText(_timep, buf, sizeof buf); return wxString(buf, wxConvLocal); } bool TQSLTimeValidator::IsValid(const wxString& str) { tqslTrace("TQSLTimeValidator::IsValid", "str=%s", _S(str)); tQSL_Time t; return (!tqsl_initTime(&t, str.mb_str()) && tqsl_isTimeValid(&t)); } tqsl-2.0/apps/tqsltrace.h0000664000076400007640000000037312231073120015456 0ustar rmurphyrmurphy#ifndef __tqslllog_h #define __tqslllog_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif extern FILE *diagFile; void tqslTrace(const char *name, const char *format = NULL, ...); #define _S(x) ((const char *) x.mb_str()) #endif // __tqslllog_h tqsl-2.0/apps/tqslsign.cpp0000664000076400007640000003177012231073120015660 0ustar rmurphyrmurphy/*************************************************************************** tqsl.cpp - description ------------------- begin : Mon Nov 4 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: tqsl.cpp,v 1.12 2010/03/11 19:14:21 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include using namespace std; #include #include #include #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include #include #include "wxutil.h" #include #include #include #ifdef _WIN32 #include #endif #include #include "tqslwiz.h" #include "tqslerrno.h" #include "tqslexcept.h" #include "tqslpaths.h" #include "stationdial.h" #include "tqslconvert.h" #include "dxcc.h" #include "tqsl_prefs.h" #undef ALLOW_UNCOMPRESSED #include "tqslbuild.h" enum { tm_f_import = 7000, tm_f_import_compress, tm_f_compress, tm_f_uncompress, tm_f_preferences, tm_f_new, tm_f_edit, tm_f_exit, tm_s_add, tm_s_edit, tm_h_contents, tm_h_about, }; enum { TQSL_ACTION_ASK = 0, TQSL_ACTION_ABORT = 1, TQSL_ACTION_NEW = 2, TQSL_ACTION_ALL = 3, TQSL_ACTION_UNSPEC = 4 }; #define TQSL_CD_MSG TQSL_ID_LOW #define TQSL_CD_CANBUT TQSL_ID_LOW+1 static wxString ErrorTitle(wxT("TQSL Error")); /////////// Application ////////////// class QSLApp : public wxAppConsole { public: QSLApp(); virtual ~QSLApp(); bool OnInit(); int OnRun(); bool ConvertLogFile(tQSL_Location loc, wxString& infile, wxString& outfile, bool compress = false, bool suppressdate = false, int action = TQSL_ACTION_UNSPEC, const char *password = NULL); private: tQSL_Location loc; char *password; bool suppressdate; int action; wxString infile; wxString outfile; }; IMPLEMENT_APP_CONSOLE(QSLApp) #define TQSL_DR_START TQSL_ID_LOW #define TQSL_DR_END TQSL_ID_LOW+1 #define TQSL_DR_OK TQSL_ID_LOW+2 #define TQSL_DR_CAN TQSL_ID_LOW+3 #define TQSL_DR_MSG TQSL_ID_LOW+4 static void init_modes() { tqsl_clearADIFModes(); wxConfig *config = (wxConfig *)wxConfig::Get(); long cookie; wxString key, value; config->SetPath(wxT("/modeMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); tqsl_setADIFMode(key.mb_str(), value.mb_str()); stat = config->GetNextEntry(key, cookie); } config->SetPath(wxT("/")); } static void init_contests() { tqsl_clearCabrilloMap(); wxConfig *config = (wxConfig *)wxConfig::Get(); long cookie; wxString key, value; config->SetPath(wxT("/cabrilloMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); int contest_type = strtol(value.mb_str(), NULL, 10); int callsign_field = strtol(value.AfterFirst(';').mb_str(), NULL, 10); tqsl_setCabrilloMapEntry(key.mb_str(), callsign_field, contest_type); stat = config->GetNextEntry(key, cookie); } config->SetPath(wxT("/")); } static void check_tqsl_error(int rval) { if (rval == 0) return; const char *msg = tqsl_getErrorString(); throw TQSLException(msg); } static tQSL_Cert *certlist = 0; static int ncerts; static void free_certlist() { if (certlist) { for (int i = 0; i < ncerts; i++) tqsl_freeCertificate(certlist[i]); certlist = 0; } } static void get_certlist(string callsign, int dxcc) { free_certlist(); tqsl_selectCertificates(&certlist, &ncerts, (callsign == "") ? 0 : callsign.c_str(), dxcc, 0, 0, 0); } class QSLApp; bool QSLApp::ConvertLogFile(tQSL_Location loc, wxString& infile, wxString& outfile, bool compressed, bool suppressdate, int action, const char *password) { static const char *iam = "TQSL V" VERSION; const char *cp; tQSL_Converter conv = 0; char callsign[40]; int dxcc; wxString name, ext; bool allow_dupes = false; gzFile gout = 0; ofstream out; wxConfig *config = (wxConfig *)wxConfig::Get(); if (action == TQSL_ACTION_ALL) allow_dupes = true; check_tqsl_error(tqsl_getLocationCallSign(loc, callsign, sizeof callsign)); check_tqsl_error(tqsl_getLocationDXCCEntity(loc, &dxcc)); get_certlist(callsign, dxcc); if (ncerts == 0) { cerr << "There are no valid certificates for callsign " << callsign << ". Signing aborted" << endl; return false; } cout << wxString::Format(wxT("Signing using CALL=%hs, DXCC=%d"), callsign, dxcc) << endl; init_modes(); init_contests(); if (compressed) gout = gzopen(outfile.mb_str(), "wb9"); else out.open(outfile.mb_str(), ios::out|ios::trunc|ios::binary); if ((compressed && !gout) || (!compressed && !out)) { cerr << "Unable to open " << outfile << endl; return false; } int n = 0; int lineno = 0; int out_of_range = 0; int duplicates = 0; int processed = 0; bool cancelled = false; try { if (tqsl_beginCabrilloConverter(&conv, infile.mb_str(), certlist, ncerts, loc)) { if (tQSL_Error != TQSL_CABRILLO_ERROR || tQSL_Cabrillo_Error != TQSL_CABRILLO_NO_START_RECORD) check_tqsl_error(1); // A bad error lineno = 0; check_tqsl_error(tqsl_beginADIFConverter(&conv, infile.mb_str(), certlist, ncerts, loc)); } bool range = true; config->Read(wxT("DateRange"), &range); bool allow = false; config->Read(wxT("BadCalls"), &allow); tqsl_setConverterAllowBadCall(conv, allow); tqsl_setConverterAllowDuplicates(conv, allow_dupes); wxSplitPath(infile, 0, &name, &ext); if (ext != wxT("")) name += wxT(".") + ext; // Only display windows if notin batch mode -- KD6PAG bool ignore_err = false; int major = 0, minor = 0, config_major = 0, config_minor = 0; tqsl_getVersion(&major, &minor); tqsl_getConfigVersion(&config_major, &config_minor); wxString ident = wxString::Format(wxT("%hs Lib: V%d.%d Config: V%d.%d AllowDupes: %hs"), iam, major, minor, config_major, config_minor, allow_dupes ? "true" : "false"); wxString gabbi_ident = wxString::Format(wxT("%s"), (int)ident.length(), ident.c_str()); gabbi_ident += wxT("\n"); if (compressed) gzwrite(gout, (const char *)gabbi_ident.mb_str(), gabbi_ident.length()); else out << gabbi_ident << endl; do { while ((cp = tqsl_getConverterGABBI(conv)) != 0) { // Only count QSO records if (strstr(cp, "tCONTACT")) { ++n; ++processed; } if (compressed) { gzwrite(gout, const_cast(cp), strlen(cp)); gzputs(gout, "\n"); } else { out << cp << endl; } } if (tQSL_Error == TQSL_SIGNINIT_ERROR) { tQSL_Cert cert; int rval; check_tqsl_error(tqsl_getConverterCert(conv, &cert)); do { if ((rval = tqsl_beginSigning(cert, (char *)password, 0, cert)) == 0) break; if (tQSL_Error == TQSL_PASSWORD_ERROR) { cerr << "Password error" << endl; if (password) free((void *)password); password = NULL; } } while (tQSL_Error == TQSL_PASSWORD_ERROR); check_tqsl_error(rval); continue; } if (tQSL_Error == TQSL_DATE_OUT_OF_RANGE) { processed++; out_of_range++; continue; } if (tQSL_Error == TQSL_DUPLICATE_QSO) { processed++; duplicates++; continue; } bool has_error = (tQSL_Error != TQSL_NO_ERROR); if (has_error) { try { check_tqsl_error(1); } catch (TQSLException& x) { tqsl_getConverterLine(conv, &lineno); wxString msg = wxString(x.what(), wxConvLocal); if (lineno) msg += wxString::Format(wxT(" on line %d"), lineno); const char *bad_text = tqsl_getConverterRecordText(conv); if (bad_text) msg += wxString(wxT("\n")) + wxString(bad_text, wxConvLocal); if (!ignore_err) cerr << msg << endl; // Only ask if not in batch mode or ignoring errors - KD6PAG switch (action) { case TQSL_ACTION_ABORT: cancelled = true; ignore_err = true; goto abortSigning; case TQSL_ACTION_NEW: case TQSL_ACTION_ALL: ignore_err = true; break; case TQSL_ACTION_ASK: case TQSL_ACTION_UNSPEC: break; // error message already displayed } } } tqsl_getErrorString(); // Clear error if (has_error && ignore_err) continue; break; } while (1); abortSigning: if (cancelled) cerr << "Signing cancelled" << endl; if (compressed) gzclose(gout); else out.close(); if (tQSL_Error != TQSL_NO_ERROR) { check_tqsl_error(1); } if (cancelled) tqsl_converterRollBack(conv); else tqsl_converterCommit(conv); tqsl_endConverter(&conv); } catch (TQSLException& x) { if (compressed) gzclose(gout); else out.close(); string msg = x.what(); tqsl_getConverterLine(conv, &lineno); tqsl_converterRollBack(conv); tqsl_endConverter(&conv); if (lineno) msg += wxString::Format(wxT(" on line %d"), lineno).mb_str(); unlink(outfile.mb_str()); cerr << "Signing aborted due to errors" << endl; throw TQSLException(msg.c_str()); } if (out_of_range > 0) cerr << wxString::Format(wxT("%s: %d QSO records were outside the selected date range"), infile.c_str(), out_of_range) << endl; if (duplicates > 0) { if (cancelled) { return cancelled; } cerr << wxString::Format(wxT("%s: %d QSO records were duplicates"), infile.c_str(), duplicates) << endl; } if (n == 0) cerr << "No records output" << endl; else cout << wxString::Format(wxT("%s: wrote %d records to %s"), infile.c_str(), n, outfile.c_str()) << endl; if (n > 0) cout << outfile << " is ready to be emailed or uploaded" << endl; else unlink(outfile.mb_str()); return 0; } QSLApp::QSLApp() : wxAppConsole() { wxConfigBase::Set(new wxConfig(wxT("tqslapp"))); DocPaths docpaths(wxT("tqslapp")); } QSLApp::~QSLApp() { wxConfigBase *c = wxConfigBase::Set(0); if (c) delete c; } bool QSLApp::OnInit() { suppressdate = false; password = NULL; loc = NULL; action = TQSL_ACTION_NEW; wxCmdLineParser parser; static const wxCmdLineEntryDesc cmdLineDesc[] = { { wxCMD_LINE_OPTION, wxT("a"), wxT("action"), wxT("Specify dialog action - abort, all, compliant or ask") }, { wxCMD_LINE_SWITCH, wxT("d"), wxT("nodate"), wxT("Suppress date range dialog") }, { wxCMD_LINE_OPTION, wxT("l"), wxT("location"), wxT("Selects Station Location") }, { wxCMD_LINE_OPTION, wxT("o"), wxT("output"), wxT("Output file name (defaults to input name minus extension plus .tq8") }, { wxCMD_LINE_SWITCH, wxT("u"), wxT("upload"), wxT("Upload after signing instead of saving") }, { wxCMD_LINE_OPTION, wxT("p"), wxT("password"), wxT("Password for the signing key") }, { wxCMD_LINE_SWITCH, wxT("v"), wxT("version"), wxT("Display the version information and exit") }, { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("Display command line help"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, { wxCMD_LINE_PARAM, NULL, NULL, wxT("Input ADIF or Cabrillo log file to sign"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE } }; parser.SetCmdLine(argc, argv); parser.SetDesc(cmdLineDesc); if (parser.Parse(true)!=0) return false; // exit if help or syntax error // print version and exit if (parser.Found(wxT("v"))) { cout << "TQSL Version" VERSION " " BUILD << endl; return false; } wxString locname; if (parser.Found(wxT("l"), &locname)) { if (loc) tqsl_endStationLocationCapture(&loc); if (tqsl_getStationLocation(&loc, locname.mb_str())) { cerr << tqsl_getErrorString() << endl; return false; } } wxString pwd; if (parser.Found(wxT("p"), &pwd)) password = strdup(pwd.mb_str()); if (parser.Found(wxT("d"))) suppressdate = true; parser.Found(wxT("o"), &outfile); wxString act; if (parser.Found(wxT("a"), &act)) { if (!act.CmpNoCase(wxT("abort"))) action = TQSL_ACTION_ABORT; else if (!act.CmpNoCase(wxT("compliant"))) action = TQSL_ACTION_NEW; else if (!act.CmpNoCase(wxT("all"))) action = TQSL_ACTION_ALL; else if (!act.CmpNoCase(wxT("ask"))) action = TQSL_ACTION_ASK; else { char tmp[100]; strncpy(tmp, (const char *)act.mb_str(wxConvUTF8), sizeof tmp); tmp[sizeof tmp -1] = '\0'; cerr << "The action parameter " << tmp << " is not recognized" << endl; exit(1); } } if (parser.GetParamCount()>0) { infile = parser.GetParam(0); if (wxIsEmpty(infile)) { // Nothing to sign cerr << "No logfile to sign!" << endl; return false; } } else { cerr << "No input file specified - nothing to sign, exiting." << endl; } return true; } int QSLApp::OnRun() { if (loc == 0) return 1; wxString path, name, ext; wxSplitPath(infile, &path, &name, &ext); if (outfile.IsEmpty()) { if (path != wxT("")) path += wxT("/"); path += name + wxT(".tq8"); outfile = path; } try { if (ConvertLogFile(loc, infile, outfile, true, suppressdate, action, password)) return 0; } catch (TQSLException& x) { wxString s; if (infile) s = infile + wxT(": "); s += wxString(x.what(), wxConvLocal); cerr << s << endl; return 1; } return 0; } tqsl-2.0/apps/tqslpaths.h0000664000076400007640000000544412231073120015503 0ustar rmurphyrmurphy/*************************************************************************** tqslpaths.h - description ------------------- begin : Mon Dec 9 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: tqslpaths.h,v 1.7 2013/03/01 13:09:28 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #ifdef __APPLE__ #include #endif #include #if defined(__WIN32__) #include #endif class DocPaths : public wxPathList { public: DocPaths(wxString subdir) : wxPathList() { #ifdef _WIN32 Add(wxGetHomeDir() + wxT("\\help\\") + subdir); #else Add(wxGetHomeDir() + wxT("/help/") + subdir); #endif #if defined(_WIN32) HKEY hkey; if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\TrustedQSL", 0, KEY_READ, &hkey) == ERROR_SUCCESS) { DWORD dtype; char path[256]; DWORD bsize = sizeof path; if (RegQueryValueEx(hkey, "HelpDir", 0, &dtype, (LPBYTE)path, &bsize) == ERROR_SUCCESS) { Add(wxString(path) + "\\" + subdir); } } Add(wxT("help\\") + subdir); #elif defined(__APPLE__) CFBundleRef tqslBundle = CFBundleGetMainBundle(); CFURLRef bundleURL = CFBundleCopyBundleURL(tqslBundle); CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(tqslBundle); if (bundleURL && resourcesURL) { CFStringRef bundleString = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle); CFStringRef resString = CFURLCopyFileSystemPath(resourcesURL, kCFURLPOSIXPathStyle); CFRelease(bundleURL); CFRelease(resourcesURL); CFIndex lenB = CFStringGetMaximumSizeForEncoding(CFStringGetLength(bundleString), kCFStringEncodingUTF8); CFIndex lenR = CFStringGetMaximumSizeForEncoding(CFStringGetLength(resString), kCFStringEncodingUTF8); char *npath = (char *) malloc(lenB + lenR + 10); if (npath) { CFStringGetCString(bundleString, npath, lenB + 1, kCFStringEncodingASCII); CFRelease(bundleString); // if last char is not a /, append one if ((strlen(npath) > 0) && (npath[strlen(npath)-1] != '/')) { strcat(npath,"/"); } CFStringGetCString(resString, npath + strlen(npath), lenR + 1, kCFStringEncodingUTF8); if ((strlen(npath) > 0) && (npath[strlen(npath)-1] != '/')) { strcat(npath,"/"); } Add(wxString(npath, wxConvLocal) + wxT("Help/")); Add(wxT("/Applications/") + subdir + wxT(".app/Contents/Resources/Help/")); free (npath); } } #else Add(wxT(CONFDIR) wxT("help/") + subdir); Add(subdir); #endif } }; tqsl-2.0/apps/tqslicons.icns0000664000076400007640000142373412231073120016213 0ustar rmurphyrmurphyicns'TOC His32s8mkil32 l8mkit32nt8mk@ic08yic09/is32B8=7 gf]pPíSdQѷ/ n R;xb}kå~0G+=5īzD} r׳ P| 0̹a0 9εl7fTuY4QAQo/7 l7f"8 ~3$|; FCR0=361DtKD( 9jW o 6i7J)1A<2ovz0m [V( 3d1^3., )~/ yu/r1f45. ,*Z7ulsV}=7szek!3jqmlRGk cl`podxY*Y[mapweQ <$,hdp{l 3)mLnaXj[*U @C%  ,lG*ta=*&h{Vp&"_pTc& YkMf& nGe) HV,s8mk&KAE:2eQ*pP'Gf$Q}E@38I5C B$B.DS  O  *O W<N ~`il32   " *FVO5ŹNy(,{mPQ̾է&.\^VťZ)_M +RF_++|].ʹI9=!tn"˰@="smsͪ'-~^T³ľZ}{P .T֨Ҫ{$iR ԫƊlwz{Aͯўл71af r~ƯV,Q+{ҢfjjÃǢD8ϕঊ59g\f>۶WY$ ŔB¬Pྠȶ/4Rٻ=!0R<ӽڝ~MBԺܞ43PTE!Bз؜'*: ˲|؉<  ǩq؋ 7  uŤrԍ1twю 3 wqʋ5cƍH]xfÊ,L=<<:H-3p ! vrtHn'F&NN&QICyW-G6"<k~ˏJxU6Ij {t~~k$ bL.nYytihc\zE h3#jfhxjlnd\y5cbaiiypzfaY]oqDuefdbjwdqrtUiMC_iqZ`^kncx|dM^~ \X\sxb\ejkls}PidRL+8Sogen[T}ng.N _g_`xf`{vqF (J^qF_w^Zho}vP n'izq7UyrXT`Y`fq8q&T[LUj-5M?H5}Q5jBG' w}# }o|zgiPujxu]?kw-tbstIf(/p]huJV%kZgtFQe hQ\qEI|d$\N\l@N~O ^JZe;OT  ZJRa9L~W VQ_R} ,9T[YZY[W_I7& 6jؘϧQ힨G#xƾ  5X~ ~fE:\尰˿ɾБIzѢӰ  #[~t/9Υbpƴ׳#aD;ϜθЈſܩdٿڻ̬ո%Et?sկߺÍxҺѷ) feG42:Ss3@۪˳^ͻ]P[XDȩ  sc0:AԤ;k͑Ûmgiu`zՋq۫㼯н}ǩlvΡs˝ĝ2uY@.ڤZvԵʽܘz巈kqƚy帮0v`@1۹_ތzŋɊΩͬpݒlٓެ),viIA_ݍvcތ崶濏ͺxrŚx؏ PݼE@/vk?wc݊SwwŶ{ٖvʃsĽC!1vf>ƞkbc{ንラͲŶr|yooˮ΄3v\?l|hy܏̡֨uuY϶~<uR@iohy勡؅եxzXm ~I zJ<}kgdktiͳаŃpг[$mRJ%nhhdҢgt{ħͺͧǾnRټaFc$@r_mbӞŮݬmzڵPn"t;IcV}fwf㣊ȬάٲsƽJzwTL7ſ̿xU|]ͫԺͻԽmy{JK0wL{Uzb歅پrڰؿxu|PX)ON@y|Oya߬}~Ҷ{VDE~WEҀP{_ݯyrɡlwzV{yA@C qzIҀ]丂ӻѿӬpis]豣' diFɩ_ЅGفYڶr̽΅_qa 8n@CԊcuѯӈLx\l˿ͭ܋ns;m@RᥤƎjqևHY`Үք)?O'g D~ΕkOhڼӐRTtɶܡxǴ y{lUe{ oIbƗ^PaҸԕIavŹڂѦޱ] PXIEꨔR}Ϣ^Ql׷ݒLX˔j㾳µ]Y ]J~G{ɮy}ЖNWʽӷ̧կ¤ð4FsvIMIHmߟLkVө޶ֱᩡۼ}ܛAaum hO_4ޠQYôƜz⻼{} 7aM/kQfݢHV̭ɼ̱so _WQgKMhuީMUпݪ|պȾϡ%$49ze wh]`tzvx+wХPܩUӳe̾̽[ dp3 y₎?ZQVgzyƬ֫Pnhջy`@b% ihUdޟi»ĵǰU|oݷSvRhlj?i^ޱ䶅gȻ̹կSnrϷž۬$ V ﺯ@ZңץveʞԳT|oվķʠ 6 Ø@p࠼׼[F˽Ͱ^jˣnԽŴќ`tbPl?פ|~J/~ɬdaĤfǮŠɍnUy$(s˒?xTT˾ºsq\||dWA5zBА<̾zlRx»yf2AI5yi,lscx\CoJ3җ;ʺhUpghpf"_ct{=QfijX^B Yͺýڛ8qXWƜ#:>:+;q2@&6X. jɔ滴±zٰOW+ e͛¼IJ٫R V/bɛƩ¼|תVVT+ g˥鷻ĹwڰUS R+ jȓ輮yϩVp Q- mē벴}{ͩXs P- kƵЩ|fk<O- fqz~ϠxfcN- j‰߳Ψw`dN- cy౤xt{wϠwjlM+j஭vpr{՟sapM-eܼ|uquv՜ocrM-b⥼wlttv՞nbutN-^{|۶yovrԞykwvO+|ܮ|tywuМuk|uQ*;vݭ{}xmktæΛseuR) wwްy|txtΙti~uS(tyz||֬}w|z|w°˜rhuS'twyܥ~~yyΚqm uT&gu}ܗz}|yyɚnn uT% kkxड़{yyx˚mmvT$huܝwtytvþ濗oltU# ppḨwtoyyuli |V"fsᬦx|xuxuݼfj X ! ms᫹pw{ztxĐjm W   gѭnmr{vuظhd pBZYYZX^vuwsh軙llowxrདྷgp pțjoryvmչkv  5n }Ǐgdmvtsds8reulfoqqcrI mkiimfnl_t!j inbcmelݼas K]NG941-)$#'.28FPU lNZ`ejh׾Zs G^YdX{ιXq {?ZRjjPv ~g+`_ţe5p }yc]a#   SP8J`<  Nu Rl2 0qr6qցvŢoyC$J{67ATzr}  6kz~yT݌J $yôœ:^ۓJyӲ~ϫ9˴hɳdr髥z}α ;p}rIzʛ~ķ?rouavʺy@} Ioķ»dA5CA*cA~XfîǿpxPOUxs'W¶˿?ưy}cg˾|y>HF.@VԿA!|qebYǽk  G9Jh¹Ѧ }Hs¸mraZͲ F9Cڜ (puTjkYWș DFc̩j*zsX[ïl_R HIëi-ji]SWǷ¶˯gzlW^,Ek]O|_p{iVÙ ɡ8 ,ђBcYöixmXvelwpSƖš/8wmeWuβ\|t\ΛAXM~mVvȫšq`zlh՞r>GbǾnWȧܡfy[wv]Ģm@.̂@vhYé|]řp|]}[xƛ@1zzDtn\ϰqrm}{ay{Wϔ!uѽ?Dn٧DvqVLov~͖ȫv{a~^[ϑ S~ĻH ?i\rܪHrr`հ̜=avϘ[md{k[sϬF =PEݲIeovȮХzY|lgtU pЮ?둚P_ԴOds~ʵδϴ\nboDnʫ| @퍑JY޶L^oɽj`te{lD˻μҮo?팄OPԸNUvYώO{h{\wtqEҼźؔ&C}ȺSOϻSKxLjQX[nyYtpuţ>ηa@}qιWISIq©đȠVkyu>~ūlAY{}bP_NÊmǨ[p}t;r~@u]=¿dFowvƯUhg>wEw`=cK͓eğXy‘ʺadxjBtֹ FCU_7}\Iifar}ºspw}iIrѥFEzd9w`Ef`Xfzplsm|VfvhFyɽzC S^4pdCɦgoƶ\Xv`JrÌ)FpHjyk0ub@W˪sɯɴoOp^GDƓlH_or4t_D˱P½ζv_x`fG~oSYxt1pyAEoͿ̲ǽnlu+ Evx}P9Qpy|:n~;}ȷYhɿǿvȭaq Id}Ct~>Mj3pفGͰZeͳdėhs\MFt{{3eVzt+?Sm6sވ?vƹ΅Phyģoq]Jaqcvk0k|0# $B]7f>yƲƻ{Ƣci5Ixqkkc7T[0:wĊ7Pؒ>½r‹aq k{vfm?*4hÊ;qؑC}}\_w3Jlf?/ ZŠ3i͇@im{mǹVq h(:5go8e˛?]ó̶& h!?3=La_L)6m9c?ôKscı½] }>#KO[|b Wo9TЛPyÿyO hR)UO~ʍň Pu>_ØUȯóU  g?URƘˋYv;TȗTļ&O Jk GtػE!\}@`ĐS {@>HAGQyRza &fq(?[_E-'fNGLykkqV -yj?ŸrZp@=e\Tp~B_}`Gq>A &w:5p]T>hr[Q)1eYT[rqJgmqvr~]CE 3";2oj]øũO@izvSYTcT HL\v]%6OPQ>HD  Uȝ'8 IdƭS?hv}~y{?#;=;,<`&!9}r3(4YE  m暘>5T˺M3ccoopqiBƥ <&+f I┦m Bǚ_+NVW`O:Ѥ 1WP%EH$ FјõġWwX "200Ɯ  I䍲·:"w`BŸ>8Fɗ  lؗׯyYVRQN^,  m旮׽TUL:  n┩ԹK5  o܋ûڨA  oے۷S   nْװl" mяٴ~}c'' l؍ګt& ( jЇۻtʌc- kՐۿȊ4U-Xʉ۰zȖ3/ b̑ۺ|aVcɣ:1 nɁض{r7̫9|+ nɆڭv}.42x . kϋز|{}w Y0w. l|٦~yz4 . jˍֵ}yws  l & luӦ|zzzuȉ- m~Ԩzmyv~qe) j~Ο|ivw}n˵A( lÀ֜|qfrxgü* nǍ~ѯwuyrrfŵu . j}բqqynsis8b2YΧyqmon_ûp4q+ kvy͟ywrimbz¿p-|+ h|}z{~̨xtxlqiqǽu2 + c|v~ѭppsjqavxǼp9xY+ hw~|z~ϛvjpjtagĽk7V + ks|y~|uvͧqnqku^uǿh9s - oqt|~s{јkemmp_wm=t -lbpv|sx~|ͪofolqa|¿fJV?- hUojrzr}Ҕp`lmlhaJL- jfnjlswx{Úpikihb~±aEQ- fZ}vwjywwėjhfin_}ú`LT+kqnoqnr{tœ`aeml^YEY)fmz~rryw}ğfeddpZɿYH_ +an}owgqo|sЊ`]gbkZyYFd-_]vknqb}npwƟ|jhe`fU}_Ih+sncjplmpnϗvfdiih[|_Hm*=[nlnsyoyzĘxbheY]ZIJ^Hr ) x^ntnjrrɕubc_k`W|~YKt"( w_rbkcvgȿe_dbdZƬ~WKz!' x]lobkʍfigal\WQ!& jZqepk{|cifcb\ë}UQ!% oQuptfύ}~dahhb\sɻRQ!$ kYoxvƅ~addg\Y|Ƣ~UO # rW~nƝy`f`bbYoǽzPL!"hXxΑ|`dedaX|spNK" o`͎wsZb][|zvPM" kɸfsY^^b`XvzOL" mџztlX[Z_aT{LQ" tά|}X_db_P}O\" mzixTV[_^Wy}wLZ! id^WX^XTpµvJY! piSW\X\QqxoD["lj_QU\XRj~oGZ! p4IQV[Nvj|l@[! .NGTCou`h>Y"]/L=PMnj7]!FFIiNX!ejk}_JFI $   TQ=La=   Nt R}j2  3oo6 taQdb{YM`E$Lz79FW}kdKQ`6lVZu|]dRUgmUcVikK %|ke\kmV}:`hgmsr~~{ybW\mzyWvsI{ÛXc\\Zr|nmv~k:e^usunzvstdeklfQBeveqՋwdWbgoo[Z``ddq~r:cYiy|sqxkxzIWrf\&Owڳi\dpm|_^cT_ekvkw~?vbNfs{~l]vyL_`\t?Lqesz~tryf]f]_aSRw}>{vbYmn|zzxmbxl{gRmg{m%HnzqsxwmS@&!04Ecwz?{_\_kpuwonszgorr]Txm{o3Ey|uO`fH/>Ims*Npx@ @gbxvynqs~wh|xu{ROs:@xR@fvfuQI,>e?f]fntv|qw~~vv}~rPTzlkz;G~NiAIH#,>d~A!sSopxzv{~}xWFumKj;6k  H(4Hrl* )S^fjl}{|xYGo`Q:<{ G),`v(o{H2LVfer|{wt~oUD|ms4: E6Ayuvj*]O\4C`qurt|zq|mYFt^o88z H6e~xsj-iT9bh/?ccv}nuye|aCsRaJ<yU}}g`,2Fuv86[s{y~r]UTgtmZ:oL]L= W|{m9,Ӎ(Y=?aq{{_=HOA3MgxZ@wPUV5 yUzq /:jJc?=c~xxcCv{kkXXhg;yXbT9p uXrA ]*[_@9k~{wkItvqyeH[|cAtY]QDÝ \g~su>L(Bu>:v{t^ixarU}p\=qR|koouz|jxsN<\gHvWvq=yX[b>a zal@3RSf#O@?o|qK|LFpkz`neTeUpAwSUg:U !Vir?GN[et!QD:x2MNUeiz}MiYvD|WC|i;f TTK?MDRpr#MuA=r&@xsOf6eOytEw^K{YApwe{t~wH=S/0Xz&@~BH{Y|g}{uzj?aLmrDocTi]4a say}? oje*?b-@tGR\kyZTxz`pyeqO`ut:WQTz*T}a@XMS`euvn7+\{04_\UIzf}xs]u]evt5MZV-UynA\\VTW_fmemg|?/g|=7etVDwceyY{\_tl9S]Uv&Qy@p_O]`lkdhbsqso8'Z{B-pr{`A{LMvgVvtyzf}|j8LeHh*NܙEyTSX]i`Ylv{ue{~@)QpB2dhdBt5Scarnhur|AIYLr/M~ێFD:]Xbgoyvrmoihw?$Vj91]ykCA>dKhk[O}iWMWMX^Ha}1IyFEOdbbtwknqrgoju?$So>.[cm=}{z@7AO|qvWLIMFUX8JXI[-Qz|Ea0ZZbjqrqmcintew4!Np|A+_cw?z}xipjHW}d;>WEdr,N^-F|M?)GT]koqjjnplon}HPh>)_wt5wuuj`cfkLyu~L4RBko*cgDyblx=)>I\gnp[hghnoq~NUa?,nn.^un_q[~y`sOAYAff;oGxY]_ywE2=ZajfgngmvpvtsNNlV*kn&Hp`mdUy^_oVlHP_Mp]-E pNaR_i1oi#:QdaksmrWxtpyZ#NlZ$Wr8Dqvk`ZeIf\_xz?Kkm IfqRUY`a)RuZ[&8Laisored}nzvq\Ox]/]s}5Ctn|}@i{`c~zkCNur\MGbOTV[Z!Fq?WK,M@OJ H^# ,rn{shGYmZ!Gmn|x^CsoTucHdzortnxw+s Lh%   INernpl!Fr{k"\r__\o@[~vzziyso^' Q<%.6FH6'MSxnvs]zl#DZk`!gk/MCW}nuvpszgpp`| >9K`nppoY\k#6Zmj.rUr}mk{xqvv|mmsyNhI?;]dmvv]5Re_kotqajvf'Ao{h0|zrgrz|yyqu{pu}U g @C=jmbw}q_ae`2n~nkqoupeosumv|vrus[ tv}1?3btg~wniy]/Yvwvtuxwwjjzf(7_dvS4d|j[bsgulvzz{votv{Om`  (~MU{@nqpYftvv}v_9C2K`roq}musvsnsub..epoT.YtbpJGmq{vnhnqsPA  .vPs? ^mksinpnE7dwhP'(Kaztsvkkdemh`bA=ZNaM-FXXj8,\^fibjcgK/C '|Zz=#jxjijh>4cus0'Ieprcf_^^aWMc?< ^S ?:QfF0ILLQMY>2E 4ku;!Gqe84Z~z~q-*LUY`_`ec][`4PLWS34EN7%789%6E  Vvwv :(7lvwu2*HPceVUUS[%"=>;,;_ *uo+%LF  pjjfuq17 9o|zyu,HGPPNSL( <~(*~g KcswS 4 .hjl}vxl?;?>F9#ƥ 2XO%EH% Hmw~ArxdbYPN!!  K^~x~0uu^W=)8/?ʗ  mgkoy{z RD:6QO^,  nhz~|x@ 88<  ogzux}n9 7  q\uvz}x~ul+   peqfo~ztv{afs9 # pcxwox{w}r}]rtnxH & o]{loqutyxwoWknjwaJMH& o[nnvnvqwvp|Y^fdc`LNjS ) nWuqnttu}z{y[bicq_>O~[\E - l^pcuowguyyvr[^fbf_GZ]tRmwxT   \Xfphq rp}s~pT^jc\^VRyYfsw+ eeu_dptguvz}qYUdbXQ6/B|idov qQblidttqlsmVX]LRvrp`n+ pUpaejojol~|hRY\Z[VF\&qq`wx . mW]hgfi_us}fggXSVS_QLVk=`i. nNoj[eljiivg_WRUUZTGKy  . oYl^fae^rszqlc\SROYNI\d l & pHho]aceicvwqeYOXRRNFKrb. qUm_`bdUejy~zwoTHRPTIF[x}C ( mN]ald^[f_jykpTDOPUJJTe,) nPd][\cad^iuu}nUKCNSEDUj* p^cV\b`XefnepwtROTMOHC[gzbP , kOkV^i[[`dos|{lqMKPIMHBP}|dQ|_+ZVZX`ZdWedvo}oxoRLNIKGPUr^A1P+iJLJXKJMVQhjnhh^<:>FL@@Z~~~`@.T)eJWWMYLQRWbcya_bA>==N;FS\{|b@1X)_FWHTELISRhm}fqk^=9@=RHJNSKV`]~qdjQ?A?9A:A^`lz`:-j) |:RPJFMQkj~oP_\>?;EA9CCax]=0l!( y7S=HBRjEhhhb_A;A>E:@_hbw\;3p!' z7HHCOb_mbYdZBDC=L>?CD98Ozq{l\=8 # t6_O{eZS=?A?B6DRHunY97!"j8[ombaT<@?@C9;;q~uiQ58#! r?pemQM9B?>?;=A9@?^~xfX67" oqUQH3<::B6AXYd}gY4="v}Y\WY69==@2CHWzb[7E# @UFT59:>A49Hkq~nU3C" |:[\;:88>5?KJs~rT1C" q@m5;94B.A;RoP.D" nIC4:>95B5Vm}kR.D" r359@185UfpN)D" ;/:,7=';Ga -9NM #05O S@*4OIc:{"5LcQ7Ki9:HG> {D @[D 'aAN%QBQ7&BevN"NS^O WL+N=SQd]VS MF D kL[ T@  0[Y2 UN3hSI UNa~iQR U 5缠]SS 40MYK (QiK\8pWߣuNRN j;rd?G+2f 8Ocru 3 )+Cd" x:R52#>/  6)Hm 6ps1;˛zlpIf9ק\Cw] FJpd  If  mE f   !`"ІZ 5S0 1 .,#,x, ,7,G,R,vT(^5S'^ O,Z  K7A(  /G,N  J,Q fHzF&,T  P?l`-,rS#`V%,W  :LPXW",ʴS[$PS-]W@HQ-XVL@O-M[G 8M,`xǎZNZ21J&; Bcǽ~cROQ=/I-L *3;:8642110/.../0000259>?V+@   } hp~jn^ic08yPNG  IHDR\rf$iCCPICC Profile8UoT>oR? XGůUS[IJ*$:7鶪O{7@Hkk?<kktq݋m6nƶد-mR;`zv x#=\% oYRڱ#&?>ҹЪn_;j;$}*}+(}'}/LtY"$].9⦅%{_a݊]hk5'SN{<_ t jM{-4%TńtY۟R6#v\喊x:'HO3^&0::m,L%3:qVE t]~Iv6Wٯ) |ʸ2]G4(6w‹$"AEv m[D;Vh[}چN|3HS:KtxU'D;77;_"e?Yqxl+@IDATx`ՙ6۫tջd]4ۀ171$$RIc$d͆MvAv7$wc:ƀMmIVJytӱ-{طh9gμX1܈ /ł?1FQuBQy7'5 I~*@~4܌*cM&10["< y$qSF>v`^ܯ\'|W@$1Se^s'v83Wh22R"0s'.7/-\Vϝ{AfGG_K$5Ř(vBuhp1 'Nde.ŢQ 2}`SЧB4S瞊ϑ!##9Yl,ٰdy*wޚ DjCgL㯐||$Oh81? 3=a2NF!Ru:]YU00;7}|oWJ١~UF:;\Hk{/ιwݲm{k3K=˗㏷\.PȢ!dpJfY#R0[,"'9!X6^5|\C>1r@SW{]CmUUN׫u4)-I+[#!a{~l L6K/ηWA =۩jGT pLL~|+%p|$a)eoB o^pAͷXkFp8^Ò |*9h 0]%\!V1D =Ҳ2}]vӬsfQ,R&AEeO{C9u yF5FN- p:dt#4hhچd{GH?-qWk-%޻fZjDA gimd2f!0$A`*/GT~o c( xZFj$/zk~^fzL٬SNv: 6DfzX[GbwvkΛɺFⰉ,OD,S_@/+ΥxpP^onY .r;K,*}iki "&%nR%k_sM,Yd*T&a䖏 sAIvOYo(xK-Yz/4i.۳x *dBO[; LvYhd)HM7+Fӫ o\^tÝgE ] "`Y#P0S' I-$SGk Q"\>/'92C:"mz!K>ˍ,8ϊS {-sCɢ0:LQ[dmH"tF;: )Vdaу0ة ?{o>I0XzZtLBQLu͢(MO.L6^6oݡOT.z|XnPa)7Px(f[Dn_-m=_,rYK/|u}v۝pȬ5[yٲ+FpF L9򱰇_T/8''[oq ,(~cٹ9%ˮ#;a64ٯF#~L'J $X7cxx2tn>YRT@. F&nǒQJh! 5=MsorK5}{[I;u9o#S. $2b(cB,_AIL)ؘ2m0c 4MDC~I?^C~P(ơy&#&tsF抰dP(5/Us* zz[&r$JOsaSt ^n[dz\zs>sF6(/#fͭrAX+*)m]|̺5?Nefv| GӈB=Q߶Θ7c%>3_Cx@вTHo ch4 |Ւ8RVZz-4}w҇^o@O[nzMDMZ,gM1CICЄGӮu zI*.@`@ ńk{ZH:,i,E]b0Y#ة 062D|glN.V"<[ Ů>#*@e5 H"mL F>I]ߖڽ`Toz)7b,2>39$l|3M<)V\jvZkku- 3bU(''kq& 0}&wpC;)SCc €ƣâ D)*Ե&,YүEPmQ2<[(+AF59 ZG_\?u;_{%lü 1Ы0I';ooܫg}vߤR\N.N4-Tt~A8A^uJx2YgTR(8(BQ~a4a&BЖ@Tp(,6p+inrZ-uDf/qX8ힽkU@F0Ȁz`G1 =.B,2te4Fp^)zFt\"/}$|hZBau%Ձa<CCv }n_u͵>9TFd Xn0_NF>9G=[kݒeۺȄeFu'AFt4,]q#bn@Mu C"F fĽ@@ZZxba'?֪tL γRoo"+vzio=){%ϙ>0 Iii (%0Q4 TbIɸBQPS~w.)z')e!IfF0xd_Kbr̅$|\ +ǂ9b]zUmDё!@(Xd'OFܟf#Mϻ0/_Pv`j2e8V#VƠj,i(1Wz*Ab mDPZV@an ii !'U J ^{O颮K47uF]h7 22֡gdy朡??/t̘1]Î;zߺ䞻󈉆n߳)UJlEi 8)Հ5@7@5qR%!lfE&Bo0$±NSK9Nn!%ɢYdt@BE)!b M`,{}9*GhqϿq-kjj,p&bqhv.o#ψ,_T?K(_/Iqܞi㢰Rv3C tG^x|FH"$,K⃹|WEh8]\7[UYu¾U4P N*If&DXT!r9PdnGB=5=//GdfA6e!? T5$lܬjtIvZB?DA*))J$`ܜڻ Ra^9f8, B7UTNlM9Y:}rH$aDZ[B6Q={+_x"œ£FԌt C `4ivN` o_tta~YTSo_@ V|'MP4 dH! ?lCP Lp"aH &.Tz%F Kx "!ۭϘ6R D_lټ(w`prc2b c5i/&] -%AA&%y(}Ii uB;ϣ6Ç~)qfd.|1z.% ;ѮyY/hOsDcfc<@Mk??pq䑺C{{={ gs8Y]bNRkk7|qI8&-OMM4cTQo''Qz*.)4ma5DwW//ʱ}V0&Է!0Ly9!J0q ! Ezⱅ_vu wg9m`B G^PCUE4-=OtH>%8N;**̓kI> DF85n*RV*#="V9Udfv%GG4.Ytӧ7~$_l` |ڏN`xF~F|%˓ FWB91 =S8IXץ^""~Oc0}/[q9/u<#o"Mzf1Vn>)$ %q4]z"a"x 摇~Tc|@HGW}8\.81t@5>pCpDz-t8q2 1 0irL ApX )M -]2ewQ z5[նtS{G/ބ]B̂AĞY|"/'G;S 􋎚zM#O󲜐8rEv~LvV>%'g[#K@ءVr|r_hH)'IFp.GY@3GËDL# TYj:Ըu6A I'L\a3Hߡ=`qN,b? q6ds_3hQy r> ױaOjoxΟX|"^*<I/ٛK[ I}[lޘcPjrk^9kjs׽2P |RU 2!Dg.I=],ڲN~  נGAm袆.ax_T9jP |}a!2IBDףϘ9u˦w(>1prD` 6##$>Mxža,9ƿ/!80' E,i?qf>4,z0QHw wE$8Y c  :m B.MYّ87X8q|> |@OfwHW}a/7'Ec7IPW)[y`gnn)q+bDQ Ĺ& @JOj[[ KK A)+@uvQKG@g,/? .zYT[L*9 3`#9oXv9:Bi&|  X!nb 穣\E8 !AtӖz>x .>0`\E[{XoiRWgHʅ@r?A'̏{SC9S{篍eCr|װYB*}C10IΌI $v.=?zV:Tkf]_E諷vo.]  !@ cOIB)ǀOI|^9Iq9Fڣz %ca7L.uM++pkˮYܮ&z~~/ؠIwCL`DX̸)(0G^V 7.Cr6I ?:0Bj@Y7O^ ľ/n";.IDd7 fKM/..*+ɤ6ŭdgI2;ۨϋ,PBŽ y,Hy.KL \ 5Lظi Ƃ0(=煔 '${^@:z:GҦ{ްjoaGLpw/B  8U(ظj8)Hש:g6Fb~k[7adFDF >]}ӬMpc\' H#?/*E==S߫ר_V!}Qeߩ*By$ ׆(RⶎXg xkvygrA_F!{ `$?D E8&_|p1⋧gf:.APs憾78,B|f6+s^pLY z.ήz CVV1o iBe*PD涎a=DBf#.#ph*7}$~THnv!B0DS ߃ }H["@lkjxd4a4T<\_ nHۻ$20RBH;` @0pa|Ow4߸g ށ%BRȟo:p2bW~hȏq{IEuHq)q%~9c0 >Y>>zrr`NhjEAg.JX-yD'0c7@lR7hsei#)H~m=׶5]nڇ-BF iXL01Weن#r`8.< (99i@$yOAA:TdH pc (Q'ϥM[`LT^/ p>Y&r@?:f1!h.B&B%CoM:d#UnLA \+3D#ŸA|kTEgGXCz[S75&rMyxT;ܭ^۞-7oÏ=r%K_'?Ǟ@BŠZ : EfX Xܟ%'HBJT/)6f}D'ANc9B] DC`$GD]|=Ɲ0wq>0oВi`\ǖv '0~8yiC>30dH^_AN4J)PX,#wHg~cr&75&u2mX K.%h w#>Хb8hτge.`;*.GT0q/D춎>jm <4# ␄#9o `!H9p_:{uM3vN 'EB_+'RաTz ܳ,z23 !uĨ땶 'g;TAPkq~{A:Tfxõw6WSo7w"Az1f'ǎq<(,*+xuKhKL~\ŻKΟ24jMNJ[YN`t"%#,Y*$a`0P_D^ؽ79ueEݿp{֮]sl0d>'RLRU @N I#? O9?r Vhڟ;q}xUՎCLB t9/*$vLN+s+/_8 sQp6 z#w7e'?g2%p/K.Y[C-lهKjd(d!?[9̕.'1\ukúa[ ]wA^+yBe_?= 2q0`yg=\%TIKBϞHW Aa* Do4d2#Vz2GXF056RT?U/vƞmp,_q-=H)#W.Wνl{h*MuLMjӟn_pwe=ht=& G}pmfeJ?T.7.nX0P%gN*56iοH0BkB?sz`յx4?%Ǒl\&W \DS{;ύȴ[\&6FlU|&M}ŧt '``|? QTqsK] l-fX9Wz>ƎFԪ.N'nhd]gn?tV S: tv@wB-pH7Ǎ(:\0_::iqRR@! V}F(o|ht3ܳ&0Ac\nn{s0@W7= D#7< _J3,p {+X55a⭷Ïk!NE+i=0fq0dv}/م@kiB42n+V?@D9 'z)gΜ gf[Ԅl1] ҡ4͞aI'+#G&PZ)>&t#V/1 ˼K_`=JPOو#[.'C5"CE À^ 2'y\oGƽM#@1bc3}C}8.*M-D+F1B}pŬ2p|I E *8o)o U "omlGnwii/:4 SD(-ź7Kffa Ul 4hb1 Qr u8q,>^@vh q$qJ/L_ FLD8^' lp>m`/4hpAzAp6d407JH]Z$f,0axvcr/0;ux)í-^c/ \r˭w=ӫ?cݻUPX\))HcRbyae!?*8%{nO~zS=9h@ A&O,qЂbȢtCBbwanA$qHB㎭Da82}k> )$$4:Q [KH?B(B~4XlDz)kS2C=xU"8|_ۆaA49F F3pnp{G0Y(X4G Lݣ/`MGK{gk1'dggvtY0mmwF78R nx.4]-4;YfTs||!v8`8+w!agb8}(3 bÜ>\X1 Vںc?HvC06o[ai}Gc8`=PD7mYL|;"ɚ_~}|`=]XQR1D0AG`&.nUfPr,0?#/Xn|GdzL;@v@< "*- :%;BA02'"GRqM^x3mݶÆq{L>7cgQ}籛L깳Q16ޜB/#>5^mIj!2dzؿCx0Q8q'I>2S7AIRJ(z K)#DH&&UФ;,%L/_||ueZwW'ȃA@~cɔ 5kcȞ.9`i8ןa}Eso@4#@Gʂt ݈  TZ ['܁2D!d]a1I i_DަK?l18:AxTʅa ufx9ꙙY1~[zo|O[`p4BDeDOA OmxH0p^i`qg)"`e"1oѢ{׏~-&" "p̣\yD vFQ,m WN5+j闟yoR*4I>6&_n#Ǻ$0#42(`[fyۚ2ߍ٠=b}x*R;Nэ=0a)I#: Y.ęРN-31<3krW_yՎƚyk^|$0}}:*@DLD%%Bۏ]q6䷣^ưkv HO8!dBM6U[8"N54wu ! аVd}›06ꄍvl?j *92e觺H+1*'P' {V!n /C&ʠOA8nj2ehhMTO~1'KOH0uy;6\AH$`zG/\?_x)sɤn `dkT&FlTAns!y /5r<VCLQ>:ԩN؟/%'anh'L?yy/Zlc#I{#0U~?i4;n+WSfns!)Nq'pMH jOX^/w7lQI񝑚x9)SB/PRX% Gr"ʍ+Ȇ܀LQp0r}0&?c(yYpa8Ba!zT:[0I9(ŗ͢6j7I\8&76nO+_YOPcJ.dsmٸ}䩑̠˘@6>Yr`SA0/\aUpBdx4BҎu/Ԥ(btaZL$9_;5C(ґ kuz&QSݑPfF=8=s$*gkc2$!K0Z+cy=M{ Da9qy&`a44G(\)DȌ*HRDF;p,4k43qC7oٺEwx̂gmCj% J/#4C(C e"aY`OYg wyP- " "m~XQV4ulc:AA XpKI;wAn!*`p4$z|4JKa:ڵ0"3EP1zd'Xۭ"G/i+3Ynf5??Ly/ .^O?9QQ ڎEw..S C}h#: pmD8)oe sU8UC)G'1 oHZ%,ou1GcuXdveОҩ5` /?Ȩ7&xq˨FZįЕ+ B(cq7u"wЫԂL|6$GiKC;޶g/hnk"e9@GG03sg' lҥ&\;ǀ,λ!s@_Bǻp|K ,0I#9Bˡ Y`ucIH9'HɠJ.I;θa([arҏFpS[sG  .SQiPvI?m@ГK~.G(xG_5?9^b7"oKHL$0ru8VtbSZ[A3xhʮ]{W>|Hnu2|s_ ?"<ɱ=aFdVxn|Ψ4? ~r8daO ?1x,lcjS8;l JÍ̓y(#x,6ذ: ~#<@Uuv( ;wPcK+tTE <!9 F */9Z`a}uؒb+ ;08,!A81>lKz `$#QCmA.]F.'hli]`B0'{rjK̶ DtAH &eѼSi?r VH6 P4j=־ $(|g!u.t=]g_z˓lm}4t`N$%!HSG"= Όj~.GumݖIT9R8ۇ@)u3'Pb đs*2G Бv ƫ_+hGZb?nR|~O1cBn/􎱆C|2;OW5yШ n gSk$Ԍ>.#DHM2f5;TN>ȢmHf17A\ )-\G4r CHnvU1,'4q +p1YuX֧fa[ڐjp4"z!a ѢgS=J7uv6 ?Jo&sdQ~d/,S!ze{@c]k_荵kמ I' ?& !p.kj.{QVΠ]ji r8S0*J8Xʨ!;egweWC3m)Q&$N[ĕqQi<ObwVyߘ6|{Ӵu&!pL8К{>$:b)#M%tYc:nAL\> \K^X'oiHcFwZ0P VAB|lCR|dÕ|c\Q]@ $P(H?$U,pPP?;KmjAIQ>5s*Vu3\Q}A.mqy~pAƦ%$zQc(RI$X/[v95tt;Ao\Ory '7ǬU/\93 <$⋜qp0 F.ڸsoK]>GP% hpbă$G@Hpڽog"nG43n/E삄VRЍ1!'/@:8nSOMq.7ހ9o#WOm1&H<)R|ոwi]B e4UWPb qZ9&=* ,o(03 :kB +*땢xR?.Whhƺ0D~g8}jF0 !4Yْehk82ϋ~9#y@V8hq>c瀝}f.2Pk.C{!.p!L>vjAjoۄg:5\v?D+^^#zro]x_gM2%+^o ABFX(D`Xћ}&CEtʭC"1{ L8рWAAe妣l{&?!U=I?a P)G,& ZHAN1cX^R~_#/x%ޡ@nzϡmT ϧNcJs0 5^a:{.n©LFk +eiP}`ш13o< .ݲcW"#!o) M1Y(3ĂQ'RQ Iwa5 L2QՆ%v:4*.?1 x!`@Ogc`d3GyY,Lv,B-; J d@\l{[DQ@PQ~dyrO$ET@0[I3gc+V?\8qu/RbS"Fg":* ֳ8wO@42zX~,YtẔ @b) ~?/~]?x4W%39}Gʉ=zyNwDEq!d=ytNL$uA{VC89.b?|'G{/5`dO+XC !𚎬6"CPXloAiA8{Oq0TѰnя~ri]]v$TѤ;-rЩL":|!0:p(ށ DyN$ǔKF$cQH%wuj2W:|5tB2襪5ԅƁX=iVD.Bl^a!e$)2*QLQ۱ iɅ0ɃBc+iP'iuر#P0cxN|>#%!XEm 0 sSOv95ƍUZ)w:JB^' 3OXPF%@ʙS@!lB@Ll\t)\#m:<٥hbTY'{sn̥zzFU{!MT]=Ulv ݔWP,u[S 1c8@IDAT ri#'_6$H4a[Q|88eCț8[&g9Kr޼fLg_lӌ&_iiF[ KFO `P\.]݋&χ9')@g"%E%.~zaafkmt YzEaKv}! ' ?ԕ! ±&LDi9V!8<#2tjV!7|eӦMy^hELb9SOM0e {?vb,!W/(D& .i p"urthon̆/\{#8U!j^h8H?nþ9˟xT'#@j],f\p1f@#v&^ @Zo'HͥԀ$꠪Z2&vtvDMVu9g-f5{hUFN,Z, GL,Lz$*C='U7`U`<{(s I>/> m&D\EPؕE;yW!ݰE!! Lާ0'C^D1}*m|! Dp{49Af{;irՂ2p_g++ߧQZMPVْ '#C=_mJ)^ R8Rk'p]IW; jjbt|_xV >j|1T0!KfMJ4ɭ\>839-D*vZS8pؿLcyGgwWd2 DI( t32̞hz~kɢb4>dh, Pon14ql7ө{ >π s~&r vIxG]{T}C{1^f81ȥ{R0„ʩrp);}Rhse#4*k>#`<]qRuW\-;i.H ?,A#HA=Ɍ<& p u@!h| 8Ϲru!8 ;p94 Kh͈x.gf B_\x?.>Bݭ?޲7,=Ҁ0bc?ƍ;h jC+PseF0{6ls+R}u(-p ~, /+S?b*TC@"`q qBC&kM;o^vQ|Iw;\0 OI$8u:DfN5XsuҊd'!?@YM,y(;S]H ?fb[h,֨MtR_hy`M@j_n|򸬉Tcc`E;ͻpW_y䥛yjYY^Rhw7#GT`oгQc۪Gwx%y?^䏀LL'DsOX[8u16=)SW^;_)~`S( ކXOQmӎCTPH%#=}n5gR )_0rS"H ;@rb떦)`G nw|!d~ܹ!2@֋s'fN7G.B{9/ &QTw*--SuMF4І H=õe"s)>{l% M>!:ZWM<0$t8oZ21cPw3Z @nlڴq7uKফѸiH 8}g:省e:3;ǥ5673g V^l ]8((FE"OI@`d<$҄•Ǖ{XD?.= J-p V$'*GR`mddqq^~ R[Zz=RD麫L(A^*o؅݆0GQZdRsiǾt` JOWU˖)bb@]^YZł饅9b+P̘|uVVw`eF4xaégA]RXɕ y$E~Tp WaF0"QYItvv,ؙs_loo/ug!>}|7l>9Gz1b!oI9@eFS"=S -l撇Q&qT$X !ܛwiD>"rC^h!;ƍ5BL6Pc=;R4e=RRoK=34:bviM/Uz`kHɻb{57 p?ա"=MkGO f3ʊ@4{~]uE(BGꃍ$.8Ι1ֽv+PeT=fpM46oL5x}kT {CAayg?(Ju;e|H$jo#sTEoe={u}q gC &Um7ğ 1k\c@N( ^ ,=qmȅV82*lH *[iz hlτOp0`@+ -o$1PJy_b6ujq7ėvKK>!t 08[N14 "w}f,*4ԅwB|HM]wozuS]4Л ?O(`~d,a @I!TۅEC:!n3P\'ҍ~ŝH=H-nmA0D`oϜ20ZQ}2"s.v#yÛ0oaXwtҬ sBw ]*ƁDXz1zZDǽiѪ;f.1}z^Q]]uSNZxVs"$& @NrɥO?|~Π5a7dٱyB nq!S68ǔ%&ի_~6\oG)d#_p'ș 10#Y@#au8.!]..K&6 zp`8u+2Ѐ "n;H_"Ll6kvB``p7M ,j?UNT{zi؟uޤʙ`w)AHmdPTAT6a"e8Z/d#,BWM"n=.uwo 0W;9KfUj"DyL3ϙDnDA(f 9F^gFu#[FCr<O`@֖V: müsP}~M}"A.lBu{V:ْ4w%m3'lv2]sn,,,X+c:JF[ q>z|j˚&L.3WfАt}ADD Evaظiׯ7`dEy3֝>g?$jTev>I9Po0IsȟG G9yX?*of KhQkE]2'V@T(1O{v" ݤ*Q;ꢶ߂+Jơ}70gGc+t!!ц%!p<1"D5qwCQls&VƵ+OBYN4qh{0*U9眃Zʶd9a!.gvaf0`pdY:suF$-ڥuws sTA3L;vWu3nAjZ~'$$>lvy3Wb&tb"kq["md.@ljjG_' m~aB=nV̭ S* ^Ac3X#Xxn {UנV0MnnFsIVH&Snz,pY"5=_Yk}qXq$6o& GJoǜ:TQwgK4}dߴ37oYaL]9LIs  qn7wmjϷf@I4yiy:iNXgY7plsbp :-I6}sَm{9jTD= `z:hNoѺK_f,:ո BR~M>n 9 %SD J~Ki7QMh_.C`1cZ1[]9+awB"ZA5 0U 13gQ'\]s-_KC" 06N mǻV;.ܨcMDh/庍 +0:E`=6uW{ _Qn|TzfIE![4vZ;-W2Lì1j/7'tF`R{r|MAp2C&:oK(sYL2^,XXa%wT9}_Z\AKwэKa Xtx7zز(J9 (B t Z~^;USQ,{g'A o*P?!;<$9xB*Q{/w>xD$8:j9k~\IC h?@3U)"8(0k,@ k~1O {kTyQُ݂|S<)g'ac& MiilL"ҶN`dJa6b%&$-Ox랫ljf򥫠D#-Xc $_SSHM炉xBd#ҍ 'PpLsW"- 22ziXSϽaCT#0a Q\ʱJX@ x~$>,Z(xH07uymo98]܍+ yiǿܗ6 '0wlt{ݗw}ή[҇#5;q?A 6k"%ݛ8ȸFocǎ[UޞL ouGXI]hb=D:#8%= =Z?ǽӞ*!+vK*vW}JY = nj~A~ji@ s#Ё :br޵X~&]7S?{;i33y)<%$ Bq2c=?@8{L6ZMk-tm=}_&Af< ŠP*NO`zؤtsH)-#0ߵBE֬L`X1> Hك +P0raFuSIaml3 ЩeڕW21PRt5G:iaLk3/e("OT,(PflڶҴ?Ag*0嶷P ?JX^v÷߷=|0ffhdpJx2IU4Xz6DFDO%YN$xHxK|8?3T OZ~?&&z?tF~M!,&|&:vUPcR1Ǔi'_=4[K|}9¨;hw+7vïP(E*M 5@qAa#HC, ]xRB#`O8*׭YSM>q(J5)tJZGl31we4DGGN5A5QqQa"C1 zQm" J3RN"5)mFaAXQ[b̋S &$j`j77[?nټeXV* Ƭ,Yt4'!;zQYi KNJrGƦ@`ӡpXa&/Eƅx:g5MB3|o?(#NXN @|z'@ɷXxzAS;?[{+p\؀xh #}cf\b횠95Ds qnwY>>nL8_Ї~ΦuF&X=Q0Iq_OM $UKp]v)`v`UC7.#iDjm\vFv|ei,-'mRL|E=&!V@1>L|Y 8Ęu#˨M@TO" 9Qdk1ǎUci%Nk6Yf;nΚ3V/ǪEC-a$ b4!8u73}@EG6jN>pO"6胎݉8pܤNbR'CH%S zB0)s):uko}? "3_N @>0?IhQ+4⎾+h& q+j˵X PY.2?CNC ѵ_~5퀉g{MM x`xp;86 W(w g@Տ8~V}wXa 4sx|S'֌Yź{FBgPx0B}N\: ЁZe n k3 O>J H1{gȿ7@Z,Ƹ·a8!G=_끗^ziԍZ[_ 1. ƙx?̘%VPk>'5y[N95?9U.f@.k~XpowYVQ4K}pN{ZyEy_%]t]?uxx??m?fwcƝA]Tz0 niܹYɦUu4! PQjIr6wZ}t2-@lM6F z>n|L e&XCGL@~'F'Y'+kS~a@lU 4n ]86F.8Te rXW9rY jǟa3k{RSSsYRAͤ4k$*wR&ݰ #ͩCǹY'99!( wCa.Q|3+͘XQ&.ǥB9rԸWV^vI0e{fL;UCmg•~\мhDd5tOՑ[y? ລEuBpAM0[$$vI0 +?SԒ[x Z+YC fr|*F#L9xAC!FZqQd@a+ N@4lcyM^R&//^JZP5!w!Lp9bI5#NeeƭzӤ+OԠ: rk<4Aej) u-V@9 kw" {30=(@\(>`Z@cg)}~}-{Mkm4L1܁㦥m x 6^D%Z%6ef-O:vfe:S_}Y ՟sj@}̲o意L|֓fmBs.(` c'!*V>e'6^B8 eRܯ͈r={)eUZEdp|ORR?b}m>/8vrJJhWH#'mAee9kSz;G.>bjVXLiy >=P_F˗.MHNc%݉v+/i2p&(`g]1iq);76D#Y ѲbR 89AW/i hB7Hq%uK[? ~rge# ιf˺XaXګ鑌_85]Ȥd.ST -ʜz0J%}Wx#ib<4D W_=SX!9~z5U]Q@&4OkKZY?Ђ33Gw7Sts^^:ﻻëo+G9pȀSN`;ꃦWIYͅ.]{Xl9O۷VfGg+}- 2F+FX,LD%`!Dń)MN-A_4rK@OY]a6HJ~iT V(|ݬ1Cl1qX( %5;DZZ[o34˦d6HL@p C[Ȭ[YL!% 9%4u0A(>`ELT^薭kM!0+V/6T9B&SX>^4p{X9=$b~kH\~ኛ6޶&""q[qJ# $/&$ۺHڤ;+o`}g7kٸ`ٍq6z< I*۠S'\u _{]qNw/A0[W 7(']lq]/G`=K6 ̟y0ȇR} lظe|뉪xuh!J-iH?1LqچDM -VUŬ/.e>k6mZu0@C ld !67,4˪[RdO @7M\NJo@+uΉauI6?ˊ{(Qjr:)(+11_} &ӄax/VbC;@,{$UuRf=WTR"|:(w$'_hN,,3hBDA\,XF$ҧq27tor#dtW@ FLp Y..4٬|bXq6${lknk7 9/>Ѐ}ܝ F>7:Ĺ+M 8W ,|/؀@^um| >)W%B/_;tX27"T )oE7 i?+q8&@7Z텷sN/5P;L OBDrԜ"VfZq~h9 X@n?Ճs_PM^ASTDN}D_;؀!TsOG_U@M1_]O).Mf'l D! -6BS_n;;-~`8^A2Q,x5kڍI-r~KqYk္6, 7!ANhn9v>.J,P+@1;Zaq 5*YѻMPЩ!9&H\ؾRJ`qĞ"3?q~ԉrWJCcx0&"WTh;@:d_~1"jkI ۃTfO1uM,&JJ(5I#_Iop93XhV.$9ozxx|g:?c=(+9ҊWmQ<0^1-e}a!ܴzH*ȧ&uOas8'4"ziލ < oȤG 1X53MW A g#H#} l)FXz`usk!wmfכMzjU">_bv0XRFCX{qj:sa@.\{,#>B rܡvhDY:vL:GAoĿqJ{QT攍DjtM7D ؁!zi '8مA"g0JC(JH?1" Ɯ/_Z䵧~`x ON ~ )SWuz5 $ T rq,7`0ν8%p>I6qs6+\Иs.`?/o˘ަsAly&'A+At]<B@ƊVV,@XRA,Raau&mL%9vҬ4:0Ţ:x SfXrFG ]3%;[½7LY:14w,gpBn}#5\(Yc#]]_!{O}nnL0_cANvKHY?1 I[Nң. ?de٩C'gSJ-zD`.Bʀ<Y HAR!@IDAT9H@QV'H=HL[s4b9+ œ=yS`x @$0&3Z|wm7PX X鶓/ nAl@ EQ#2޽?Ї `^+uT)Tj<0 k'ԮʂLLeQ!Tm]#@Nj%L@CR ))~ '"¤‹+n*hX+ H"#p &xJdznGgK=3N &,3~2↤MN5'A8\NM=|cX^fƥ}GibJJwRXpz\Pm l\]3 h? l\z_XWm$%|;bnDBgTn<ʋM̲y{/ZY4B?wAOs$Uz''yo6H~UeK?Pu&p<@ &j?J3&U9GhYbJV!>hc@ԝ>]k<KV>u~Q;_J>`i|SJm$> o2<ɜm2zm61eR\K 2κ9uMM*6H7!ٗdz6 pKhb#ND1+.Rx'O =>aa4) ;+%6Ea筂PC҉"( z:M4 B9fCgz$73qCL$yW9M7߼_<݄XP Ghcoya ԈN(~(a%<fH>s{S0nC^z?N5!>f#Ωlb0+V,׾'vmMV{76>RN<@JH>wk*.A1c-A(%RւA-ƕOGب`@X|$M;@tbQ .6w 4(w?*_K04MH=j/.purVEry!SfۭН5 xtZ-]Rls VQM@WZ2/hQ@~ .+3t%xS͍W۶n0n]u2ΑgVQIX0H7ܰ̔`OV#.Zܦ|PgY5,Y|κ37{`I'ĖIL;/FΝ0 B.T|NYlZNyHLxW>(Aa 1m߸H( a4mmK+ Zn,֮i4ZhfP2cYHHHԝEn|E)QhJswN# ҇njs΂{O%I sh6d> Q#Vnjpd3d @i huځ\IL&?,1~&F8ЊJ28T))~Vp,D&1JMř=z ,M1"V[0wۖ\H .>Zh31ERb/T4J&B5F2b%# 8GYņ3v}vM7M~eBW"|;aVvi>yUmd!1rB0sN, VRwsQ50٨w()n>'Z] 9sV5jS)&ޤ{-e+\Z='݇Ϫ|LW_WJ&+ADiHٸ+1=MLv?ArD!֘5%0V`.VF`R.>b%*"1 %J^)ǡk3ˬbBV ò*9tmNFU# A4IM h]qV]Z (9jnڰ 1'faI.Tz?L YLIR)Lx`,񦳵ZU1-W|e$-6nқhi6P 0y}owVlm"s=O W`\vk0?m_[q3\.\*pٓH@@YI V C E( Iw>e eV]y-r|#&@Hz+n\;ȿ>zݮƴomjur!EުՌZO,LX=_ u< %n̖5 E1Qceޞk0k֭BR~Jj9 0GK*K 2^7SB9gho+uDכYHA,kR72  vt>|i/0/+5@TPJyP u$>i}IssG~X%PƋ[R4F!R/ #ڡ)wz2`Rc!#I!Y]# PSs0(Xō72>׽FZ[t e8'ONON|E+? HPFS;U؃qd^v{ϳ?V %W$RL9RC*(J;w҅̃I/y|\SrHA?Kc_5#TpfЮWT ?L9(*_;>{[TXFDj ?PLY[&TFIcZQgG1!*j̗yzLm Qyr'ؖeH ;jN=C=agv>j 46˗K bv؅H'*W9 p/YPّa<]&atG?$ory`!8? b{Up!gJZlO EHr-, ,ćjH&Q$o%Lu.,jʀA; ,f <~L*/aD|Vt$ ;JO <翖 />0CxR,S.H=ɸ;ɻ d.mK8厳V g>/oÕ6]=>%9F=?$;|K3}t62nJm8o/&1~@d\v 05d?VߐVQNfSf$X838/?\4h>q.ݘ.m4yEetqmI5)f'iLrY "h'(5R\~Lq_9B3t8HC*: #>cGb6&+fkۯ.4$zF0b ɠSI!+eIU] {aL~1f$QvA ^3C޷b(*O"+j-|w\G #D#9#u^/dte5|i[P݌I,X`OF"_bʕ#Ǫֈb&VlҬa2 -a޾~gph|f]? W\>^(Q/7q?I!}'.LޫRsN2RQL5]jݗ ?/]3,Pzk+8Լy|.>>/ y~LM{^~\zCO'O7LUĄz):$lEG0û)1ͦns<F${? M 8E" a*'R `+hYlC鱠DQ$B\Y_^11>`a%?v,i?^,NLhq-gB`pɇh ,-/`P0S1RR58N3Q@DIE^gB %0T7BYȞP;1qw$䑐UX8(zCH$Ȉ'4 x#jť&ӌ+C(MA OIٝRPvFG96ykEcz{ו;oäHO>>tD5_Cϵɬ8 BRr'Klź8p(:H[:{ >~6,5@DY^=ȪiQ3 C0 'C"k@hUd="b`^Iw_}.0^چ连ɕV:8H\4=;=lcXNt) +BN̉|8qz BZt݇ޙ&+3DZεK?pckήvҏϰ`"Q`qe|OKjp|LgͲy]O|}j!(EuYYKAsS*vQ0&:ƚa 8~ qڠ[&Lee$BGQPku> Az_H`\iZ9Ӏ0x6(@ Ō5 >5TdHw9W2:[gpt*8Kݷ;MM \3(hGLgݑ;b8)gXY謐Z1wU1Ca\jٮشT4ĔS[P%Y$}| l+D}2kzL)pMg΋0qP*Z"G]iW%/  TZVZ.ifGoٴ6zo]hp#Fe7)N oXs0?z&k? )E@HcdޫY]>U @^~!p㥓ub-RRk@0ɬƌMe>u]0u$>DO6$wT|2 AV|&bqco.D5UQ*EMB-[Z;vL4IjDj,7ߴcЉOHHK9J444':}]8`U?#xS2J= Zpzj{Vo%(qoW',LvEaH2-WNw{=+7>ǟ ͍O۵T\}e:qLsuYSHYYbv}on!"J *)wt='aK {1HniuBp Flzz.AK&U I:]^*Ѽٯ%e솯Q 9owMgV߳>cf5y`o26`isM>#IyɟBieUpd,AᝩفT9{@%fc4^SnTU1h'^!+so*4J_ٰ!8:B({"IV#Vf d++:2$PYT[N :@j'GIZ`,?;Xn}cd8B5304"@O&" h c_9fN]-*7ҋw(hEkzQD'E7]!LF^f{fSW_CSjDGo@V}a #! 6 'L&2[3Bӏ`ҲKi ~?ncbDACNն&|r (eoӨh'*IJGLR4HAc ?$,Bq 㞧'AUu#xZG/ʫ(5 TՃ\cْz Po"G Hy2 q ŅJ9yKRV(d uiٴyGb6oޒ= cp %VƂ%iK.n;Qhu/^AxkEHXIxyܸ^Q*8uh&G O%~r植_g~o~f{O/*i?FC%:/MՁǹ{]Ύtfl3O~'cΟ B#01( Uu``wljfϘB J8LCM }m[L^^~yb}X4Rc}6F@/\?!,( o#.B3{OpЌ\2HZ X@ۏ7TΟxFRn8Ty%)dEA`uC`_Srtw+4wܹ [ou]1&oUkBꉈBIE >'aV! C)@F@Uj98<^=<"Dmj x7e G$L͔w .*Zx Xyd ~;(23ZAtty^`+vBbLj*M*'3If FsV=))*$Ҿm@_O:XkĜu,ᆢH A([l.-ho!NJr|;}w3d1ճoԴw3hUי1RW[67u4N|'iСz(jj^8hz&LDmkD5tv4 ¼'u@Ց*3YFyv&q7&>h5"Ɠ\$,npD95L.˨K PNj03SnVd|m3ܧSE @ȷwҕȴmhg\"@!DL:>On\m; |KilX_~0FEVE<ڝuێG@l\”\ ߴ״¬ݽլEN bؙD6B[`r<-=%bсC5(Xtr=nd75:0yԙxݯY]NKμkN"A7>*:[n1[X 扖H{./ ?7E]tzuڈ/ kNɊ{RH$M"ըk'lqe៿ {*߷n |i톇 )j|6?AJU]g&XGQu4f"Y)@QF6Y(idcS 9FR? JqLlL"ZMULA:p b= N]c(&!0&MSX)ХBHEC;ːڛ&>6w=c|dyF[Weq.NwfR;ax ?V[6X)1xVon~A4W|A(X 6R&AqɊ|a^,jg?-"DsV^5+aZ^QE RZ |줾^;5()/0K3n^;:|NXa毐zi Mz'lQ + .%qt0~hB@ha߹̰Ga qf ]fj L ;l R'Lazq]Y'Ny20&q >eD`(Z$Q #A[Fi9ql V iHr)(>P&Fpe69XYNU.JQҹb=NZfI"`(탧I&tpiy9UQ/|h׮]?illB#>\ (Ͻrv)qZߺbhq"Ú0=.z)YwV ~jZ&YEdUzDGY9wq^"_d?.\~6 a\ofVVO[III6}1.U $$S\z-(1&yqiMs&/,$^zsm_U ~uWTBɶc!ط眙쓾j,&@`bĝHD?!ЌtR:ꜭi5_(RZEͽ؎QQ^W F]ڊW0Rq?*0x326B +GP`6iKP!mj=utjEHM(PSRNA5B$PQ-%Z" s >Y,2' TJa jAZ%R |6C Md&g?? ڊfhUaSB_B saT 'Z67Q +a_׭u.iwÎE1 F;NX5 /8$`BS>xǖd7547l?ϟrǽU 2SNz~Vj3ă^3nj&hZBbð.^ro̽? %= xl2]~Un~q鐃fadRSbFqotfbJ٧aWP\x{ght%0 /K)&:1cwj)ԧPd-mrlܠ39JKƓSc|a-KPI%Öm7 2T>gn%TF2ֹIG' 1zQ[>ƱБ x?=t .U 扝!0eY:od@Ze_ǰs< SCM纅S ߇"Cjk^Y"ņ\ 5)Z`L70u5X^d8݄ۿU2Юtʚ`ܱ G&i+Qi`iV,Sg^֣@0re*k3N|"kND(ֲb-t,[R`}ohw󓚚)mcשwQ\tysoȔ^0I!4M-:^ Zy} C>LV͞{>㔤DbSȵ =3sfsש0C3dC+Qڟ缨m~G?{oggYY}Ͼ(" $BA[_KQjmTu_m""@’=$>g~wLaKX GYk] Hki_oΣ s^};qژUpiv;4Μ>\ajpA*5IɿYg}tr\7g yx6iy4ldRW)B8JRN 0sƘ]vyf1o9vQ $\ ~1Ї Df`=Q*vIǺjHRmNo<"Wo|8lo3 ș72eH^:JBd*A:e VyPS EE\LnKUB8(nBw $UI>~&*$˥EΣIYrݺkVRt+%yLXE@  aGC^*&~RfVn%ː708&@`XNb|iIw;Z!G\eA >xMJ@q"侽{G>|U;gtl7PNu[ ~ݬײ0Bb`CXNFݥ`ٍ`}_8nhY&kY@^r\E~,|>B`94&5LYDn ni)&٦z4w FsvZ ap 8VQ(W)jJ+762~ YC/= Bw ;_Ny\ jʬjJ͎yfsQVj1$ sdž 'P J'2ק!(&G@ 2BkiTULzvt7ٝ_k+W@5.8qimOH?ԏ} ;i؄7^83݋VPYhmfqeVu7I_Ys=[4'@!zJ7R'{R΀Z;zJ۶mۼ3fg6&J ŸDs9"t3tӔk#m/5g4iqʚOY!6|O-ZQlF L;f|:n6>bpkѾ/8 'E;kҹX[ndl6quLPI kvz1,Z(,=(=a}a?jБ?e.SL· ns l>;w1!AaZ yZ"Om; \{i9h9TP N"C^By`+GЛ,0/iioW/eVX3A}-^oUpzR/}s#xLz\ ԤO ~ڊ=Sls Ius$4-Jynw>\1GcQLnR |7;>6悤CKOIY}fZwϜ:L]aS,+B -61V-̿3^`_q#NW(v Yqp$dҲ+F uYY .EPz{M й_ { #t h'?Fe2U|mmvZjɀ(u!x`ɼۿc>J0O<ʮmEAfXp9c(X(GLH?Ah$~ h&OQmĹ$}pa R%G@mԔUzT^{ޗ륳gz 0?kkMI6vִ5@|sТ ur論o |N*eo^4",|||Ӑ4P)%ۃL;STU'?E-$)%yCNrEJ*0eC*!>BCO#`C,%a@IDAT\5欳T6AYQTM%w՘& rQieab\y|BM7!Q^Qh,G!05xC'jAPHޠJ?4Ј,s? t uM5dCOcHTՖ1OzQvL7=rZ:(:dLrP(68gYv$DQIE}#L]@D4tiHǓQAO^HG (%kCG<ݴZs*UVdu)OvnnzS.xW,ښ{/_>& H6`/z?'R[o-v ~q}WӢ=L346S̓8SX?RLJI\){f;1㸪(m,?0QJ$^t`\{55+V fd]׵ySo$;۞pҧ!_c1@M3մR}"zDC沋2W<XqNYs|f6d܋>܉_s8JM wgJ EW  HO@|,Bu,CsZ!A@BbSXr"L,OaydEyx/&?0V؀7s_`c\d^Bx,-(܂P򯲄29xUKcĘUJq(le%r;IU\P X*$5c3j43.- IRMyjg[o}1Dh*V `꺧>3(yɄ9gx>>Jݎ;FاD@'''wUWzϖLx5~3[{\)( 2' 5L6q~- %-4,ILf]X3ө7Z8Taz r!@ndgs*u2WFfT>^ &,| ?X0KOC_>꙯T'2M"@Qix"?'\*r`f[c/ )ј. }>7լ[$ >ǚp9r`B6v hהbO G>䲫lHpժҠ6[C(`bJ=(uA2֙d#1sQQh>1r$`cIś[|}{<#cg^}偾=7&.4iu͆}^<nI#p,{8 EWM@\0|hne E6+."rŊ]O}G">" Z>NWtB*٩>\Skln2f#fe:W,]{_0XƒIv5-L9kv؆ qh -X>RX)Koo4bh@X4N,/]m{"B2TTXac2IT*4hʶEAco'> fcm\ӯ\F5644[:5*И m12󣴞|9Ѓ%;/d:Ӆ %֫sUXԖ !n_T(/F|\uu!ESrkЙk@-R~j"K>4~\x2EFgdx}YjhLV.#]]TwE{zǶ8vCɍHf g|^v}BN\7_Μ|} %csIQڣYt+X\W/_a{kܮ=M`H*YaNvCQLޱU6s ŋȾCM.vGee4#_XRJ zʇaR 5Š @"B56Llnϩ'R4YdǠ @ Z"MGWL*Ȭ&X.<k9,d :qɅ &̋xc#\R4uPUw3>Uc9KZ 827s՚|# cG "3S&Ic_C:  )<0IDU3ą ~ā(ڬUd6 H SaWgO>y$%x3 !P*ʽMo㜕:x-._5'6ؗ֯R@^<$@=(|<7=gE\}ʕqn_G<#{N3eUȚ6yϬ5.Ţ>o9?Ƣ# BU BA&<!:x!ل\FDHf˖@U\L.0Qȼ*_쿊9~4TǟmA%/ȴD43SWSPك[!+M~^z0ぃM!=!#(ץ=ʟs\3ϣ<<ohБ&]VKKn%b\DNrsa!e-Aʴf`\0 E ,h3Ӛ!=y ܏p*`*Hk0 8]#\scƞo @(;pkq{fn+:sjSN{jc~JgSTbypUs|%KY0_`h؜[T<괬ĂE{J٦\oU)A D]-\Rfߞhw>.m oxl 1/%,Y|l|HngORbP\78EO{];ej>@?؂c>/ƿK  #LzKK.=CtV1s@>6@`MBG_]TuyCX|i}n> Xj"eY/} +^\RF8 )[$U@T>T䃇#@f^foaOhk#_"O|A%#>O $<Jq,?D j f'ʀЅDLV: ;GϽ}_G>ޞyɥc8vR\x#4ylh͗=U ޠViձpKJ o$=o܏GmXcw|1PRz(6xҌù/F{vr +aPG]bRx@c' )z"y a!D-YUq(AD(<uɘNigv~q  R*Кgu:dctl?G"]xp88-((3Fݱi`==i'ٿw<bX&Zog%2&Ж=n*:sRN xfVٯA]O0ȦT|u-H\}ݞ=Onq~B]vj=$GAp!.V*e7޹0RM}C,UoZhn=XuQ UxX;c ׃'ء (MFx6l 8F"\nab/qlՂ!(;PTp SgP_[cg)ك pUi& ,4 .GQ^ig~386!l s D֡dqi.,<;)0- ڒ[ G[-|}{Qc(Z>7"Pc)QΤ_:ת|Ɓ@eYe@"%ш 'F:,d^(vH[by]rwnOȥZ_vF/:CHQH0x5|MeP_^_K >o|+xE,8M>_%cӟ /=d7-..q#L'sfRO٫~%;H =sV&Iv:ׁ3KdWtJx40aUq<8 u2ln:`xu} h̘\<ˌ{/aBx7>bYZ6IFvCFi)&/@JO1$%\RJ2H*γ x(/)r!!BQ%y(|+@T3b(|n!o< :F)24x`CkPs{HjCMN"S#*ɣ"P6 ?MK2s )(mkt37 7[ٲݢZg«lVZyt|LdHN<2-+|YJD:YeE&b>ɹ\V}'DkʂGc\ 'uw#M\3󔈔믬c%foPBPz"se'}4NPEI;=%K΂s( .5X I 1NƠ 1p*їɇ"f*#/X8TʛTl"4iIj[˹BBs6N)8$ ;ݣG{T̗/yO˿|`H"9^]6^ In  H+~xA8"2u31q?:`⋷7Y袭OAM~!p鼛3 9Hcܸ&Nԇ+ w4 Կw{#fak.Y 6AP_/>q:,2BAZgq": TP0wp3{ҳ~.4'Pݿ qhTw,DL&9 V_IFyK-mѦAgd4 ;As׽7]&ݪmgn+0),6$`]*$x0 !9' Aae*+Ԡ_??k]'F-/\f/c@;Κ^t,"O;CT5; p.d}YwXZb cq#cJ2#d̕eǬ4 P#ߏ53U'‹5ݖ3fh=sgңĮx%@pB^~?ʌ[弼%6[{)e=Qi[tкd_ 7;w4!ҎPkcpt1E@Nw(#s} P\sf3~Qi4!)RLJe>ߑWC>J{$!JFktxO2ER$^vӛ^si,%tK VpwT;iT4R%`ܙB,<f-0qM#PUΈ٧nu̹O .rN+EUp=B s]E5@kjI42ef.F5K$Ɏϝ_gݱ&(XH ʐm2`5oa#yQc]"1G<Մ20C>%JýJgh)q֮쎓TH<><:`qo R.Tq?qH皽GphA] _2y#~,~3fh4' W}/ !P(?SsNx* fexm] (y=Rӗ(5'dH`F|C)Go[ pΕ]?;n\^xٿ% sf?|u.|zE ѩ&[';Vm=,4U)ȚAPҴ q76] a޴΋ SQ 7 #jvSnOpSIbfM HWcYyk)+۷Ǻ?;>4h<۟ۇl@2pݦ$VݙMOQ' `yS'opa!0%+Ȅ>rAr5[,&1#vq?Z/^I4 & Fm}ֶ~O0~*}ۦg޴ T4(fs$#֕ ԠC~9XN}n'dGIL0bXP= = Gh*܁[޼e۵˖.} l+og+ߟW}W*%0 $u<w{Mߏ\t;N%}L&|jjPIGx{e[[X'2ڪs, me6|6z dE5G@!A3MMo$!4VD/$_Yu$Swg wQ==U tI75aږ[aJD\:7ц"O(\LIRƓ#9+.]xӃgN|skB Og`Q# Xq^亿9~56L[@~%Ϯ7Wm $hPϬ'7hQk&Y<…VG骴~}'e_e54IӰkםi.y}y~QkʩZ,PN)U#%88%Xws`m_M.=敫Xol<ػp߲ Qbs=Οwwٵw^`ҍ~oWIVdSبSotãJBad]0 ;<;I&KqIs"0ƜVdk m꙾vuu\wݵ׮G)*iyQ o89KYߚ55UC瞯]tE_+sv<~Z ~_` Pl V7`wl#$.ߦ01fĥLcAvP8ϫiL~Q޽=&JsWRZ7#]g^icdWDs/`qzY>L&2M'Ԡ2L{0R EUu==h8ŗ蒫R˗~@fprtwwaG2Ds5bOWTXDHB;yT>$I ǜ|▞K1X~`7QSYHtpssr30u;:g; /2 Rd*-*k>zԃ{ D~?S91ۺx7p74m6톦ē vh }6]~Y5ZL HNf+A(rg>殟Kk|_̫g<1e >45ad_y啞իWl\x_C q籧wμ|\>J[yJ[I^eR?"͏Ed ]yv$<桏} 6wP PSd%ԞkDi9G磗'ǡ}ML#TN7!ǃ4<| B K%@/*Q *#^5s-*ß Ϡ؊#IKǝus/VXq7M3"r1J3;~|Τthf8wqǻϝ9w#ZzСC+s[7} |ߟ{\斫;KKË7I/_pi)/hcuS~]p|V #ի^Ƈf͜I|sVd.o.z&"4 e[gFiIT 7Ӵ~;ѐDy1/>e8 DWky ;.TEߺxǰbѴ؅,zO0YCgc xr=~Ɇ|5|E )d'FA,KBc?3/+9+? ҔA%he ݔG5~y{n1ߟ\poS۶_?m5c>8Pyz/wV\~UXGwٵM†$KV;ar;{j1%>̠t4k^S=zBXChBKKA]:":~R2&X%2 <9f6Dds"|b^y,J\df4[m-{ h2g/KK,(_(! qL ~Xm_>Db[]SD&R=zȝP+RW\vgyV\qM7c¯gwL9we}8"oeDR%#44F*/xH:v; UWsO1egh1f1zcX*KPAKYl<1x_pP0h=i哶=1d܄MѤ[Є]X'er@o/^L} :bQ~aN.!E$32W_Aw1r  `NVi4no u d$oK29ƛoUnS|<yA^9@/ׇc/hb&L?e./bނ YOyq) 녜g nksC\/zُW`Ki"Ndܥ  c,.ƮyUo% ώU^g^&xM9uz'pIqƃsGcN4f{!7|7M-mӏŋ,%47E%`h?92L?6_}qiհ wPR?{/: ǚ t@Mue_,F cgrG=ڒjԐRVrH*~QL#10xy^3 !0ᤨ7o`MEkzB0zD1f4=`vibOZm(U|t‰;qwhw_ҳ3f|nħ,\X< G>_::+([Cw|I }83>m~;Rn&xjYʕ~kWxa`_VVv:={X#R% w:f+CjUg 11JJ!,J/ViԘ#Qn4iY(Y}^s1I aȑunkiI齫Fu\y٥>EV<@=E(E1?Oмh|?{'F157y7?oK_=N垦Q班Z#|'YSJdľaH@jCJf[ PF`Ia(it!қ~l'>yJx5/=J\{ Ω7Gz3#0 Cgwز+X @Jr\ !Q/%-0 /ڼi($ʶ"Eae>[ NAM W^4с?};žhK9]Fe0u]OAe (Dؘ?X,RԱKvڄZlEaOғwd.=8+7CG:^J|wmm9'C%.C>UvKKlt;tɾ$ڬqp O3] ֬?y#=RJPajpQ5fpłOM;]-@ōPJjIYIilS& '͇Wx3hw/4]o"*[Й /TJڋ2pHp^?:{nظG4oͤ:$l>v?B\EO!m B9 ?b>X\~1Q Eư@rXۉG/* be< 5E.=njl1͌CC2JyVH̨\O_wɅ׳x) G);bG_98Nt}G\߲?"Xkg0av\滋`R}< #tK ̕a{{L?LD㡊m$4r*#ãfF=b-c* q kLFVZxoMg@_|{)3Ox{tL32_lYtu4̪ۣpK0++YL:Fۡ f .(o:]s4Zc5D@K R71%C,"$ah۷cҳ:*T^J2֠P(AZf'_hA*YKwvY}{uU OdJI8lXs`{ӭO'tgΞFǜNޭz};(A:Կ>k&ɸp2ef$l_|.# ZQnxdkl89 `4zs!9:Z!kgt%Z&K@t&O<>^]i^|uuFC~MV߻tit͚w57ܺ?䤅EШ3V=naH ǮlhDe|J09φ6Zlpmm_ӂ( Yj&޳]iΠ |n&ȈZ /,{N!44{Ƅ"^Xz5&)D| 2ygˬwmJ,eK]{{ksn\~G$ Ξ3TkIJ]=qޫT'V2@>PECcU5 9$>%ԽgO~Bڀ1,onI<>zP)ou&J!paN@Cf8sf"1h`u(1 j;}({"~x|)<5\7kLl7[uF ĺ}-/Q'ܵ)៲-_wo/#`]]㈺fb:.I,\w2N#A1SNhn dAgV)M7!b|SP >ჟ_Y sH=ˏXA'ȰKRI(Àe2M!|.8kmH94Uw?tFЇAZe`єf+#,€F|-VPUFCȁ9NXgqwnJ_hހo^q{(Dbմa6i nPAjxvL:YCm>[A.QH.QtY\TW1T(crgmTF*`f'ʁZx r`U7u;B f 9n^ )Qǭ0y_ۿO WWrB\fx>;5,NQ`E?>LgWI#a H=\w.=sÚZzrYQXic@1 4 51!E8x^G&M2e_Wmܒ wsyffЬ*afߡ16W9% Q^I,q}C3sC$, : g3^7no{O/|YȮߑ,K !X_n뇱1.-$^SVO>E%C. 4a;'ǟNnFlSDCkܔ $ O%Et2~'rHЅūlP~X"Ip쮖F1x<1+njk+̂զ!HU,4\SJ$#z; |, f*)AT錃|x,0.{z8<^ok0S܂|{a[]8#k 8!(ˀjƻ@tXY;58:[yqZaO1ؽ z}6=Lu}o Y<$s1k" ;YT(t؄ ouIKLee1HĐ+6J;W)9*TF3[5Yh>i&t9a* IԑϖT+oB|}(*o1!-FĴ3 enةUK.>?=죟ڹH81b 72ʉ>-Q,VeEX~.Z`_4L0=]r΅ҋ? eZǪ #b1H4*L>! E!Ø / ł h>hJ}J(C9MQ,uǀ9D. w[v s%gns(;:nc,fd 2xΪȤ=S]{y];!qQb&+~̛tޖ `C^4^}~ڰeu2|%^9VWۙu1o[k's>{f=#AU,QP>Lvriu`I2IJ_ n (ofv@Y|&*B|{$hƂK52\_a2߾#TcLsg3HW2JKEEk7:s#c]nW{3hÇ'e@Z<Vޫ|pEHqy᫊Dlox)cnFD^i뾍`N~;88 3kH:.4c+fd9^hWini3 #<H= $`z42H Z@N.91--v-$`xA{z,D(e&L/|ʆ \8lf^s%?fN f3 *2b4-橇0զjBtaٶ=f% |]?]ihx;ߔU9re@IDATu(׹ ٴ#JfBI42}ž޶JLup`y[G˾o#I7++H8C!唕ElM7PcuN?| 3`;8ƒ 94tuɲ¯v^P"Ø5Tm6xrx9Nf.^|21Hԩ(HI0B4yEH|y&yx0Kl2P& hٲa 2inf}V9s)K>Ϸ~vXcsWVCfn%9f'h1͠.gso$wd  @薜^x()o@mMM~|W۶# {{Л+Qg,dtBp ,6Xt FwSL?ck6ʃc&eX$S]Ue H {YX]{YYa1qDI>;SnIq!C^@Fdm_#tx@ lp٦z"ԀA@RB2a.Ig7>ܔLc5sgOpu~NTtǶl~ 4}aMY&mqw{Jש $HpM&$`VA U7ۥ7UcLxzbv\ҋOxh'pG>Y?3(Y)!80O1`_0e݈[)8l2b" r HoK%)"e6nAG ~Q (4jZZڰ]b̬dOCZ2>C%< OB-3501=&I;a3 )Ѹo7Օ ܀ji`,ʌaǰi޽)aִF?̨1q7o>Ь +?o^{W!dp`;;6)Woc)qJ =q2SŴ@SvRx\3 p~u,}6 ;?|؆/d /?36kC_rTb9e?X"_ ǃ>{ou5s:ڝp13j,BNe9;y;α%ݲw#K(t,4轱W]N5i͟6sx_B[64am ų4sሙ 1}ozW ʈ߽'D^@pYb[PmZBq#,|f@;ٔgF';ɐ"Te.GYM nKkC"9z~r'~& LyYSZV6m$i{JJ^) n+wn/{}Pof PiVM Sk~PA$,IIyqT ~,R [Y=O-ffMG۝(=g"lŲOA>=`1g-XkaēUPK/\ ltS]4\B,n#MG&$`wMEaZOP~Yt)%h4( fzE! Y 1A'F 4'Ϙ f6<wwآkt>ū~]nG|Ng̒ZKx.z=>;sL^g11@,pPz ٧0b$nE#tjHfskɺ,JySw!d#vN׃ jNx&88 ߟʀ@7ݱ l3"\p<35xpzGYAKlJ\pys2ӯVnyƢ&ݖl[D~b@3 ykM0  efsha=$ Md‰  qXzpH7HD,|x A#L̉Z%<i61r8'֮m!T9 p >iG9(*lw6MԑK pf餗K=j>,(4S,0ϼҦ3SŰw<;>~xvۯY)W!94=N_S~~g4tRoy퇷K/>CVE4#7"dY1GbGL/5G2\g، d# dL[W K5ot=9 춪d֋!TȂa6HV2noA1jGx&HIjc2hҽzMM9E>֞+4U~JM@f qPxy dn j>vu8陙/oχ> C\L?_>mR牝0EMvkrOi'wez.LIvʢ&|? ԗre~[/a>%#夳:# ׎?N- U>w|O6l\M#oML=h[3C9,G/G$1-qJK\?7v9~'}A < Awd[!eΓn"eS@mɥ̘7 7#X.Tdnʳ%a 7F鲲kt1a>qߺy~,]v'3~6Y^{=%$IǫlV@q66;j~}<4C~A~^{|TZ[jwVA:P nSBZ!'X-WOԩd&ci=S'dIPAuێ d+Ws2в9 }X~7hi:JB/oq,v|[o٦``G4^km-lal& wn1S)7[>ۉVI0Ex1\Ȏr~|mqL|,o@/$H{n8qJH@aXא]a/ w]X쮁ܮQ?2}ix8>^̦mW;[Dovx/M<%'c,@Xm|u7,ou6>z293rĕF|7{c]4׮lri%=煟n嗒_r`(wCUK͇IG &4 aEUW~^^ 8{BK-<辘v|v Zw}1ӈWqn8"pA% ׹ uy&RZ_>8Gmi!?eـ qgDfC/ތ;8Nɛ9<:)vǧĎ ? pݚ;>r-'Ls^IlKOI< `,KUQ^F-#hEx>/z[~gM6+ =An^ٷRB* p BA{Ȗ'FM̓6M6`%M_C/P;88AyE<?GLEBQKw-J=풬xEɴTPð"S8g%ޝ|ҩ6'O#DK;n؜t9H"t>87^ GnS @x6$w8;!J?R' _]к;y[v<VWuJ!'J}Z/S@ě;{illmg 7(ɴlS_WglB628dY,@(V}C;/u!?^pBX<(1B!=P0(4l| H"_Q\u( IE#g `&T"ECDs!Sw!n;J&wL?# YcU~6BZv3}q4 ⑪ۏTsL)0X&Q˕ؿߜUD: ܆'!{-:黽eՕWEX΍qM+ȨG4sbҕ S;lޥUtm$؎kb\bIb'{1&0UHH!PY]iNoη; $Yf.\͝=;=!9c~|R[\X#IՃ5 ^H.Ȧ A@14$ OT&a; O1mR»}(}c#潤dH!p:TL)'C ʵ/ .Px+d7 i;H&àX^Pq:iCAJ+X,0w%VA8^N'נl(S~aY ܺ˜eB¬E ytAT>Oi\껞0~3^VMNg_5.O\]e]}0L%:'@ho5QOa#tWYXq e%(-@#%>Smܼ=K@ : 5d$B}nDӜ "@'EwbH, S1C6]*Qb#X 6S|+e$:FFA-x51ls]2xY-C~QAV&&*cA83<ȑ7'oޑ06B!=BaYN;ɸiZKI_ɞ(@+;H tI#^jƭGk++`V) ~LwqF~=9iQfAѠ_4N1Ar|yPUUvh!lcl O^)ʢCEuC)oĜx]:&7p~}_` j (:u}#?ǶU14^`3SC`c- ZIS{ZvЈ*L>jʟSf^P˾IY('3i"O7$o_4a$ʵV?F<yLOܧy?Nx7 =t+oԑ} N%2{G #X'#kYFb+h؃ӦdJ I+x_0.6;,js1#*דEX6 ڵG z~&>|"LX} M[1߁K84/$!AH"ݡ.`FrdmWHE Ƨ xx|^byHyr"Pe=(, yD4=#0$ǑYFcM"铝9=RO/z%yIc-E_963wTH_?u?$ӟLr@Pvy&o:oc5-_jd M@1 |Hz.0f"(t%n@$v @meD^z2ڏ dV>{ ~01Xn5w76 wп` &FEw~Rl$Ĺ?QœN@${$o'eQh@{<{̚+:0&j?Z8C"m߭ҝGp]c>qFG-\U?KU_~, *x>ؑ# qC$)W[=մ5j'%}#-΋VMxyXYN/zBO/rGM%crz*h >"i/ThDsͩz "I$/;??Xz\4=>d7n)miiKPrQvӵP_w=9t4,f$?xR3*tMQ]͔675@{ (-.AR0@,>/'#܃؉%J?X}C"j|DtM,oW9E<81DTd_9 n 0JTS@Fkg>?+zd[bJNo6/H斚LnZ{#/HH'5c/wZӟ?)5` $' Fog1ZڽC64=ҭvDGV";:V##cWJIpЏY, ,J`tMH 5{zxoy_^rHYyLkڠ)b2a'HE=¤OYjզ E{ɗvVWӶ+#[p `I 馇jOhDRд ܉_Z0g"gXq#$ .^D>< > A82. /"*F9yUVusUV:;O}ڕ0p4V0b2\P,Ƥ$ShnL(Yҁ^*oL\^l} $̉ ͩ& o6"@l/- ,C@UH_!W7RY<#Ȕ};| 0Gɲ|r5^~f1{Μo|wǶXmUϐd͢UV ;F~ k0# =WKC/O/H 𓊼BA Dku 8*:I;sP0SpD]|a|( _3 !נIć jf}TvUAҾ&ψxs?u=2ԁT6@J.RƢ$3IME}K2*S5E!OP̄U]%!' ǔv1dJ!"vQ1}k $ĆpIr?C+D$J!2[[ ޷1[r\y|s|ZA /޶^=l\P%:v_y%. @G\K 2`BI>% B.YZw"[>XJ.O+ >eCtӟ{n&^Oy>i^w^}s~7Lw]}ut˟;iR]Lb^}xئ S\ں}/S,wڬ:2ccnn8 լSɫwCm߼".qpq3Lo+?o?N"c8A1n6°]b0IU(8lo  4![!Ƅp7{jrcC S?e맿wh5Z@KR'z'q4ʍ, LpSVf_f$%ˬ7{>LimٞB̫Alu<ss<9Ui\3f΍>x}}\{0_TD@Дbo Z(fTAM4 =AIЬZ\0)1Wej F>?$%#Hpp3R ý %xB7NoAIEp=̡a5.eD%Z{j2Hݾ 'q0Q%jfԮj}ЕRQKԙ~+./6I$AnN啖m'FE>2Ĕ,-IOse1rϙ{p^OLLh0h}׻~u_ԗ$F`$wcėYeUN$/|a}} AD6qZXlWSjsD'.\jSo4Iԝ{)J@wVjlӢ/KX"E4[ =Rub^arm(sd>~+Θ>CP`,Bh?:@jcSڷUUX bh+f]}m,`7@2mrv_NObtCz5zO:ԗeɒeH+t$B`i!-ep% E6'i; {4t](A  ?Oߧiv;* cttN2786/$tdB9tF44Bㅒ!}T XH|Ih>EH4+z0G] UYYÂU/,NտТvAVXV`4k6Hnp? 1~Ub5#cL~ixW_[u==ۯiOfLHQ hזnR>+NJXudžɡ7KNާz ?ufU[7]MB+0ԃxC<7/_mz{DJjTv+_^1`C`b.䒚vow$ #hU L*3?Ḑ9H~}虅$/jrQ-P {Ԏ] vZI<#7܋p]E_Єt=X~,7 ~|~ogsםA[%R][xc rxGHK'A3ϓѷ@<(A%hZFP:6Ss*լp yu"[$Bt`7+#t4N!f4HVPYU3?np̂IHg0. k#⯨EԨq%1oP4uBn՟>~"R?h8ӼK6=NsS8k.d_q?SPk4'7yK/W]i2x]E`X*Hn{'4YDDQnkS' 5 )|Kc|nIo ?YP#U|}CZlo IRun$hLʨvfUy Y/Voe<#?_09Z R׷w8t̸>[nuZeW_,5FFf6e?1iY Yj鯺z?|PXMYˈqo#'u+6?>6;ڎC ٦DWcSň\YQ x*5n.ʊr]@"BUE2—TԪ=-TҢ6`n /(}f {r] T!ҹ'B* ¬yڤH* Wvvh|Q#^Q;~ٹ?6eN Pu{nVL]^·;o<-*-ptE=Bl`K_]໰CW1AwH%U$Ir9a (5K1kzu7\fC!`a O In? /JɂeG;5_QA۠߮K 4 {'eA!BMdZot#ݪh3 œW\߷'n`eeb4)qw.9PZYӧ;3j?=/f?/_}Ͽփ {"ya@I>4R+-uWf[OK[,ZiС/9RiMJϦMQA-Z0W2g By`_X*Bn#_=eAFaP\/DR+iG2c ꡴ }/ @Ǵ4goV~)@1(>I`ڄMZLp28PЧT9_+nj _) l^w߶h9tO^?iϘ~|]e?ͯ-{#.ݙJ?aQGxc X@)G|p36flzarlFԡܘٽ}B RTu%Spw4/Fgbg;# tFߝtY4^### ^A-)Dœ{̍_ø(n y9Ck;o^_g 'ѥ RL?s?3¯~kyk?FˊsD,R7/+`ftITI= А(Gl=`e  <]4`\"ΖKZ} 5T6=9QxSº)ҜA j#J$#I8| zITVT-8R,$0ZCCjC5#v{մlؼt]l` :c3-?! 8?Vi_oYǟ|w`hvacp02[0ӂZ0ha4~B ,\~'v?sLU٧B }hyV8jZ$N6ڑ?#yCj9Sgr!r^yʗ d՞nyo=nGpxmB["g1H+8z+5!80oůwbDL2AHUUp۶;\^ b2u׾Frϐ $R8$G E3oZڒa7FMLy `(Lja@TjkoT8Cj߁ø$Ԟ̽= jwLsUw,ٶgo 81My?4ȿLc6y&OmL,{ǯW{lhvEc(R!M[#uҳOxA5KMruN:^yIw i蒇5oUVX @ z)?ڡA~{Y]ґ=J,BaA)/'&Ol/Ɵ ܣKU*'q esL8O+q`P3\D(pW_R)|+ˊavF0ޘ^=Cߵuz/Ug3e娍[va1ɻf }0و R#3`?fPp'*=7zT3.Wl[q⮫^ܼ栙wiZYO4LG77'8ǚ&,m-|s^fZk>c˲p |DvVQ kRjM,R'JoE% 8/yy`Q4hIDATZ4V(í|,|mDWW pP&saR* iVU(i%Dd/,Ȃ*OrXE}k@P~a3)p\~;yߴI ?fޓ N{Wyo  /`,Y TFK+hj*s%Jv%o/|qGod# X2r"̧v%FF*7Q@̈D%Ú8!Tx˟_C0٤$gä*+ٯLN8~+_`e%T:6EA8ą!7`v^z2#CRt:Ƴ8r{ps7ǒW#Gn +={8ZҥxWT9wjk΅t#/>+EMNts;vnT_"7i1C?ؽE8~mxa l5m4Y/,!81U>LNexچջAYHQR1B<+*)ԩIx!s'GwŒSV?vc]470#hПt=ﯿKֽ~dFsnOq$21_TjԘÙXo9^wrjrvO>v{3y*~o&uYv@__ԞuЎ"t)"@Lӑ!RoFr upoauŋ1 XQaKYqs_҃QUN.ʁ%`G)i;)B2m"yI["WFKj@Iv2XQ;,³@0sEI <5OTCd r<= fQ `7~_ݏ?ѧ!%o |z{ذDŽeP td )E2uggqB I0}ΜyU{7-wwIx)bDpEbm^QQG@%K.u7+Aj#h."vPvE465ac!ٿCw͜_ >2n!DQC9o/B԰ ̃=8H{n/\YHpcvѱxpz4 [429y%?8#ے3zc1~3EB]uicZ7#zcoxzU?R==Ak2'k2{]eW,GG1BQUBq>uUx~\'ֿSv[$kAb Hӥ2H`=(+;UhpTd.PaxG(rSk \z`C5Nn(?hQZs8|3=5?2.!gFQΙ @NL5p, !|+tehKl(BȈ@:x(<el#a|iINJW]ɿ۬nu%.9Wo}rQ_>̀ AH:̀K.%jh92xKԛtz p \;zIܒiWչ|vdЄ<ljqAń `*ʊhxhT9XG_Pq;ImܼXO0z??62f{--@?5b.u/02 So w'dGͤVYͳfթ\`ﯤgpX ۮdJ )3ڪZݵS͞5؀Z` 6nF&y[ʧO5 n4 8P3KGXDO-2hk7 F!\dZ]9J h@"ǂ'Qv4)S{^A'0={>qCkd gp5?QbҚstIg<;2]%1x…7hQF%TIE8@L2j[T>D 5t2 4Ep aN4# hEB0G9p{U3.%/_rkZR ?Ɍ p֯韬&/s &_VR'?Q/ &7lt9@'`j)W s.h9 a.@UU{)u%~9DXjvc7_Z:;u}Uiz; Ay g_3ט7۩|l_<$7Hh_*٩žKm* >:0DgΨpwyB@Fv_;|M,0dLئ䋩7/(Oё 8 kN( $U|*.Gp>v)!AFBWxCKV "Y"g='؁UQ b:JR<$8J.dtjWBI; xC G)EPk٢v{t r|UǻW=K{xKUٿB?y40a|_ԁ\"G^=LJ/J4詻WR*K *9V,ګY'`٥f̛uT^|S w^.!Xt0Z[n[ ~\UqK@O V. FK~& ]6H3zqxT ~ـxC) 6z(Jl7{잘?n_\m q $]y|+9y/ل] p]wͽhkm'aͥ)`Gf+&x tN[hoW_z&i6U3mrP3릪tJT?JAϋlRQtۑT/}N]J ,-zP0SJ1u)U}Q,ͧJU\L$' 'Y/}IQF8j域G#jhX TĚ֑Q[hed'J1Rs ڎ!T\[ ,o^~ǒ&F@f?+'pދ䋝K(9y6kv۰RCi II:L_R"aQo]&` }HD00ʳAV`EP:6i0b vKx5P rDv!ĵԁ{U40K ؠCp+Ɋ! XBAE)̂jjn5yrFόG(o'ו @ZAnӟ/Zp΃=]ma5&'myUlnR~{I-W%e3?M O-Z8]>B4Q=v`{(J` S0L+a5Oav<@:CtZtRFF4R뛔Ax _v3;>_-Ko\3#ɽ򯫭rK>;8͘ !v{yc"(,TInAIyj 6_z)"MWYEQ 0O>#*\cW.m؆)G ē4$@ }`E0J|a.[PcwIGm$nPD t^#ڏIsOEL(MYeV_qgnX"d=}N9srS=, MOݞZlIas]*{3L>79߷DG#؈^ڭdTGlU7F﫛ZCj;0 MʅٟG+0Q&B0"'Nv:dPfϝ_q䑗BօH*3{w$!|l1{lh#_vȌ~Oti @>ϊpr^Ogb'6q.?gy#h(`FBD rO[Z;%^@@v]7L?=VZd [0Pj:d7<: Pw[(Y8B禴W~9)u,xS6W &NL*gUU1#@QlбYm %ISal7duE2-8=%t69/7hˆK+m'˸ 1\~u#rhY7c2@6Y%ŪV8i~o4Lʐ9q$GUq!UA1mn0<x0tTtWՂDn?~{_ YvG4nr|l7gu<#cIΝXK>K_ҫ9\ /<и^vNߨzԿWjҎ,IQg[vUZXh`\|4b2Є4hx&c; rV*Q~ H7WMQΜNA<=jެZtRދzCCc0 B16{}9_O|?#շ,ڟ W8߼SZ^8 O:xwږ̈́z _v͕, [0o[vu*%g`á /ۦ6-۶:O{ QqQp@b6ǔYt|.E :LУ$P+>@UY>wQ3W}XUG (ZKrq/;?a?s$i+̈́'HĘ&OuG-#Ǣ/DZi]Oyl9Mدz_|{y9|ўGkWw5w^hTYejj,gQ辻F#_TT dE]hVޞ>څ@$30;>Ĝ!8i./F Ko~Kod~~w&  \r:-,Fhz܉qpLŸ/2`F@3rӘ&ƌ+Vs]̂jskO|݅7(O- fm74̞P4|T߬!""8fXCT=r5J٨p4׉;PY H!-zԁFA r L)."?&wf? o$MdwJ3)"dMhW Q^Y) s]pqBhʁ%/S8B"/]KTQ^5lŪC/iT%w{GbTN?!S#B?N P~5~9GU=[|0 R}=CôB9ճs)St$2WG-}g˷~%!YYYQ 2={% ߨIFE1sPz?RN@ľLE9o'tTY#\j_J{ !6-/Q66LC|WN(eGqioشij+&5ڭRSbʣigk[zg" AWͭ gh v U.*/x"?L߂8 <Kr~(=OMRه(q2ᇗFHZH ;Q*vZ:Pfb?뿻A i !iolI_i1]k'.J/G(]J-R]-&!fGB@juD]>-iȦYZ phc8K![YxbSr\s'K.kN9c+i wOM>Z:H{<>VwWo!B ~(4p<-[uHsV+9wXE?B#N3 E>C*ĝhyCJ("6Fh ns|G7no}O fW1H&SaBN$R%,_y^eEhhJ}վ<sU5;~ 㱦 `L|w87 K,e4D{#_4\j臑 dĖnAA#H ! hgF]ͩ[DȐf(+G (YL~ z?HܾenA~tᷛ_϶|~=gc#|ʄC]^[svs oL"/^u$%9ԱfW,S#G5ss !ft 0H;>V33sgm7k0A>H~ZMyED.R%)>;݌ Tw U}=j=-}J➠$4.ċ Kd? gۦ݇LQk.͏l?\b\?{!>'RrLr-75qlB),wa GFx+D@R/̎#]*P+H&{G`ۼq9mV L"POiqwoX=N3H̥%Q_3?M 7MeJM#_g2BX'oY 8 #4妀H-ckd_@%4IO{#Ӕ_RWQVu<qpM Lhǁ_э> |v{P9k|) ? _ЌmxG5>I /W*;ϭS}MjVRL4MNƽț )4pd;mWw6v6  /NwuP|(:GSj4R˖WңA!j`Vse @E޼p=0ϟFLK.f 5U!3Fc38V]*u:X_qXr98!z5MV4rӐ8xeY8i"(.4`λ٢[Q1Vj쩦if?A ,@[T1 "$P\u 0vwSkUkFvH:J|jWz Sq8 v]uH \VT;r͛?O_LxIjI34q%B. MUz]SKA6y'!YvLe|"V֓C!Ț|s[ WT('#vȿo^b^T1EtZ+J_fP1j$|m Ȩj;8G#턘ZCg3NXwT0Űk"ToAGĄ:0qz&'/r=J`txYIhǮ]( 6TƗn]O&OqPi #4d,:xT!}bq+)a?3 0껌r޹5.sU?QW^y l?AXy0$VŸ!!98 f5e9y->u?-~3Tžo^(fOKŭo6pK+hjUvlOZjp9< Q澬_'&;3eLuc)2J/O J(Q(rhGEҁkjr”W2`Ah'^IO%4IA=+V7>']t/>_FrS'CzipW`jOB-1P`)Q]@9mvZvs0RfLѸZz&hs#0o7ç>/#Flj"33;\MAzmӳ{G'NfdsC_*V.gY7yII܏|>Μg?h&&9G˛6\ݖ;`n@ޡQ$']^Hi/ao!kQOR3+jn =[-~ QeyRD͛[o/ʆ^ _f 9=q O|zό?[fxO@$Qs 13\jL([weߴ.E' ,j^>'4Y%T&-Oq# BY8 0tT6s_rУ'l.fpڝ~;={z i Dv@a$գ.0ڡu"_2_s^~a&@ 롫+{^3 94V)j.q|_mǯ[3#ѿV ʀ&S'31˧ ҂/NHLc=&gYe a|Ye_KH@IOPjX2r5>u53Bpm/5 [!+?xSM/R t塾}4Mx4?RRO>Sp+-`/oG1-̆x彖Id ƘO[ME >sL4&_($kqiN6L?i+EIv2 ao^VVFV?lP;jkDfUJʧ_E +u@ u%'HE_=V-##)a&>W8~x7rʕ+}TGLN $?,ǚD|c˺p2pO(d[nOw'/^֮ZݹVj&1S z-DuU@TR#ȾSkTqQ濕c2'p+,9b ]%w>~;H֯9](\~?0蛥 -7XBut;x6VLDRَoMGdF3#gy{[s%@~oA4aMo}E |#;g QԓhS\@H_l[56RCtN.;`Y݆J^zEoЇZP?毒Yyg Wi&8]K*ݿ;7~ovitXavQ{$\S45 Ծ}MMMFhH@gh?[Ė^O?/{ĚkpNp d~g-^NdF,r\v~M] g{=4btw}@-4`f1SeE~ U[[ᯙVcu\6kkYmFʬ<3&ypDnݶ9{^zMt9~wPa+|Cv`(4FMQ_UE~?}3_c[2̟ 2@y&HC- n^`"[.F1%v5 IyNмU\V@uURI Σ˒|f@ 'p @.!Dhm"tMCaBL OP)T9r:Δ,SBI0PhLӐ쟽_:s88% #!pCNN :PHCS,$4q PФI q72S d{Qo}OIENDB`ic09/PNG  IHDRx$iCCPICC Profile8UoT>oR? XGůUS[IJ*$:7鶪O{7@Hkk?<kktq݋m6nƶد-mR;`zv x#=\% oYRڱ#&?>ҹЪn_;j;$}*}+(}'}/LtY"$].9⦅%{_a݊]hk5'SN{<_ t jM{-4%TńtY۟R6#v\喊x:'HO3^&0::m,L%3:qVE t]~Iv6Wٯ) |ʸ2]G4(6w‹$"AEv m[D;Vh[}چN|3HS:KtxU'D;77;_"e?Yqxl+@IDATxey>swWإJ1h5VQb&&XMbgT@-aewvgvz?sf31~/[Ϋ̞9}6}}cV#PG8(@q#PG8(@q#PG8(@q#PG8(@q#PG8xcYG889GMye6y s6^ɤ3^{ÞWy~$>弿9Z3oe =/sӳbO#P#y3٘n/G8xJ'?}?a#}632ϟdrҬB556%+ _dm竸h ٨r/2 z Q3{r9GB!^2Nͦܵk[dmxdrՖŬj-%+NX9Y`0g#7̾|e2yu\~C>`YBjT1pE*ˬ~6׽|i٠Ax_[~,}W{'"8f<#2#X+Ɂ7?Ч}@ՔX(/g@ ey 69>eӉY c~ɫ^6xJUlLJg/js3?@ gOwp_ΦFKcy1 Ĭc٩v β?y%Lr@xs8<[?߄},i_h/y|HNLw۞lwO} ٜLO3eėT,\`gV**-g>+XXSW,GAO 1NG;lؑ|>y{Ԓӷ@o5TXKUԦ'Fmz6c%Օxd~BCg-wtZ>K/^LWT7of[6GP r}1>/7_!c]}+筮yiKeҖJeLĔ ښ3Nض8nz}1Mƨ>L=>^JtS>LMy-eegIZao}Gvwtm l߶Xr0c  g 1|,ZN1yd, Z]uYν6 |>;|h;NEp2rxG@+0ҷG| !KOMXEo6Pi%ACA6kҀomhY&~q#604aU5w~N=i,+5xG,1gA`YvfiY.!xr+/9k-~Ȗ~!&f+2Gix=bgCtn1.㺿9V>l];X#VO(k"z-Xmulx,Y&_J VP'Y)\*i33KJlK~[y(0M'U'<{Yl̡s Я_:[-uY}}=̭/`UV Y L-"OynS蔝y+կyC!+[2aCȡm VH嬭'6AB  JT;O1 g0l쬋2 gcАoVʽi]ٸx '%9 h<#{vg}I( R=QªcV rV-T6ea i94~UFVJ)ӠB>`dgUTkvb4@ɿD'(/##099z/x`Xiv {& :ʰE#%j;=#%Cfs3ɌcvgPm˗T[rjڳs^pM$H9 .ån„4$i ?MCll`w/s_z/%qWc%˗/Wjc =|3%6*e{y+|,daE?гd7=jjj pH.eg|'Vo=_ABD!wE%1ςVa@;BΆVl&!2ؤUx1iuV\8}}ƒ#q;KMZ,]K8)"[8x#ߖ~?;ey-杶ɉ1l65!beԛ}xb3Vku-lNj/vBb&S.{wz`$B9\ǧlphxnhjhp^b`< a4du5e|qM o#v_exݛx~9{I?}H0naR mSzRh[VV@8`L*rĠ/4{'u 2Yohw/{+ Aco26@.Magʮb{эE@Pڻ)2 R(a P@I'JPȣ@Ca~[uz ?3Y/R]Ih-?dO[hML!&KF(`A&0C,r©xEQ23߶j;N>[ `:>$3 V#L۱ye&0<8cTٞmlJoy]7"TV 9 0G3s/gH_S;N[?qZKi7ԳDRSعsd&a[ME6ð`U 3\L lQ+<{,XUWQQκJff!i9`1e{ʊ2̢ԓ(UR|9dZvF/q۷AH 'Ik[.-jL5jz89.kR5`eHM:U}Nj8͓y=f+b 4>K6NQ?)p`-5fвldFFƝV(59uy "܊eĂZj íA_ K.Z:ZlCw@jb0dSĞ>KϦmzU9x0ISl>rOlm׹?̭[|~97ru@mr73>z -F(EQ^Ԍg>rxAht!ձ*,0|I?@ wD$pzʓ/ЃP#!@@Nd [EY"R[aa>ՠ3qpfs )O'\k5gN@PѤuwhc ;"x3wM _-kXeװG> Z@l/[yؖ2ߎwOg0|@ F"{m_ PeB4!ҵ2xpkȹߏwyx(7>/_Ԭh|i8͙zlҪjH*u޴B/8lGϾo_g/)3 -@e@cvʪ؈٭xQK2xux *CF۶ljgo|yh—|y zeX6؇sdzlVF%ByCXǷcZg .Op@WA"^{ |T]}Ͽ+Kh9(7Ѕcۿۺ1 ;3nUp`?!XLƍm4F1(}I6FZ"I ZJhM8A7(_ MG6#@B+Zg_z 0 Hn&,Ħ=kUWU=cY!f;V)-ȍ x ?\ $3irny_T'6=|km{is,^'>I>~m|v{_9ko6ALU*4z)ƿ}m 0Aҵ&&ǡ3lU&@+LcE UaDjqM9=Ö^e?ctp_}Gl߁Ch<&>=ǭ #Gd3ezVvbC{k–EICkGXG t5ۖۜL_ ٪k`7sN _ {?a[tꋠ[:@suzҙ͢\/d~_d2G[_Oy$`(q#2cxJ'mF'csfr0Fz[K5`ȁ :d|j p @ΒP#%`KLjj8I$"x& Q|-X@݈vl4雵Yp2Ϋ[(ܴ tfvvu\S.6{]5 #ZO7csʳOPsޛ pu=l$!nxs,9;0uƞ0jh}{ڒE F`&a A>9k@|z^^~3bl9 \?Fٶ ɡȳ 0(./o1o 0Px bw ~xd Oq?,޽lo\qe$O :<%W&\ H)/+OxEmP(Z#?6eky&9cEg-]h,e=߶@Z"ơ6j-MRX]-dDDBu"bPCLd"czwNWY8g_;)^?9G컗̽> L`%+X]9eCG^wvCiyk[g-$ /@(/|pQdک]OP9֧VT@BQHkoeQZ#Θ(Q&A Pq=cu5:9k waeS0g#rLh`b{欦V2٨K }p{]: &ࣁs"C],+.4 *<Ns,?~(:!\9b\,B@B}v L O/EP*xTRXr `_ܞ8oEhyDHSz}߿܆h~ ?;)1&762UzF h  ~)5=xgc06-{n\w˷; ͑j V,+;)e/>@,t hY GCC ^dyxatoro>b"-WRu6kمH],%+EY:X9LCt=dO<$q'lmvj{뤶Vs<*d2Ihi+ (}Q"xx^z(X461bkdkVwgjwKoЃ.*SWiked zhF,~VqTc6gFkqŵcHCP&ĵk1LJ9i?Gc*T:/2 u b1! VB(HAyhp\0}Cim"3l5cWx8Qexhz \aƆyk&,e1c$p/ؔ[8XWVH2  F1X:x~U#RE;<0e=l|˻m (Cl8EA_i ?e=u9Vin{?>#ޡ¾v6ٽ{nΟތqrom~fDJ4ic]E\VThDb hK60p y8ם[ v [$7M[-mƵ_m[etfP|]u V。rCVOgTӆ9yoCw+^z-f;w[w;C*ASS=j{q5Xt/\QðCGPie?%ޏַ!' ˼>'~{!}c@ץUcVV5D9'H$;)UeT(M\޵bZ<b,̆ pW @UzWXzozGbq <8+/Tc}dS~ 7`$Pp!z|R p@`%rIu4G M*)a+]{GILX  c$" "4$TP'F(Q:+i26z~ﲅ^e7RReZ}hJ/Lڏŷcs=s}>\n3ߕ/>- UkoWX̣PivU6HT12}}}0N6NG7% ơJƝs^xwnN=3Lݢ0_on8|t6^_fvJn|h}w|'%l9eKu \[d ț2'&MJ(Qch PM.c:+d41q|A@CIx)9 /a,`zP :@J1 >_O D9#3(r ;]|ׯZs|fe1a=A.$1{~N N[suo.EQ?'{474:F-[w$tM:psy~Ci'9 oZ}1I sc nڼϓZڷkoT` ;Z\@! 蓎-Pܧ@[-gIʆyWٓo =nq#<6**)pv 5NJ8Vih(Yĕ}HښV2lvg/IzX( 0>ߺl`!obצuֽo9̋##b|L"vPRtrXUn߹yӊOœNXl";0EliRxiD56IC`| 1$LLA'E7۠БB&GEbx &tRUPSڲ 2oJ(ma?Y- RSdF$P!'A[..aXb %,쇷?iW]t9o8TpR2x5gF#fJ`e:fF`po,ꊀwwb{n?S/QxML';& oLB-4qrUɛ]i3WQl1<˗`KZ*Vy,tXKe9Et8OBuסnh(^eǕ<+0@1^֊k #u/ :mϞ)|.2I-eeğN!ѳJ`-0L7eb^lz1,Lw3 "VAH,D^N;LE Z`+M*GN'[~F}yD ͷpv_.͔H}OZG%*4<}Ċh>dȭ/@ |bB<BNAv1*G&&` *Suj"{j4/bvNK<ƽT5 *gpX,_jXPGw@Ɩ 8+C/o~=Ls8ǮZ|353OٰmE ̇|cwծ' a]2)N'~rJZ/Ϗ;G9f-U@TpeLʳ/G&K_ PlYJ%1!PNH@@Z9/Bn< ,F{”@XP G(4?ş,z0ȥ{wc1*UL"M_}(\ ަgHC5(xg'Fƒ|ak u)oOv+%5F?LBzLNGQx[% 004ٱf:ϗ;K( LoYouLP/:嶴Vr2E9{uj6:ԏV8gP8m*(֯I %h }nUzFW%p2g  1;xjD"4F+**Ľ#J!Zq$tӲi½ZoT QGx O!d<˜T犩R> HR4Q%H-prHPՎ;`꭮' ߄6~"dS,;Y2oW=de/ޕ+q[tb>=ѷ\-iNrz3HCNFxiPuUMJ(ռJ}bo].]UO_yc2'/. X)jѽsRsX0D+a2uѲ%šE͎@Ws&؉$u/ҎfDe*M+Vk:M. #5K:>Y@sџ\j#C<̄}]67-FBjSldfWBӼ63؃$I M)*8ݳV[t9- cGl[vݎ-ox(@\~%\@%I)*zÓxI R[Ę 'J0!4R1?'bxt AG-^}!,_RkǙc^ϡA R-!B0̙<2!f"M/DiRcs bGFi## 1 ^THA8 N/1Qg7]@DpGC/7c@՚(X /1ەwd ZDz|ظ!xyS601Ȇ*r]U Gr%x}# ޏ+TySR˘ː,+,NqoUherk<4Nnjum{CDo?IW>XN^~h GCi_e_3bf SCrah)(0}iH[`Aijڜ)T/+-vqAhoe!/+Űm;-9k>d~pJ.Lzs+%\+¸[#(꯫(3UNb2&4.1gxYs+ƥpc2hC"Wxh.]xXRx@ YZo~*eRYH7Ψ|7RkUw9P9֛ D:Bk[ c1X+vNg`7`Ksƒ(1L2xp@kn8',N$=^w ܊-,H@;}W@v~Mxs1,M*I}c-Rf36ON8 6x]ڤE*F%1uN<,,CM5-V&1ȋwYWԬ<QAbİȸg`%t92E%+;AŅR8ȦhB=ؾcSym7N:'%Tem͜!}~9OgЁ M{C{m%l7tXhxX PJxȵTATb~ ~yҮl2D"#ZμP8yUI0N$r0Y !eDD+ȧt>]u@LFxTV!#!ï9}>Ka cp3n~I ^TDєNk@> RΚoen-p2fG特%m'`mZ7*I> Z7J`@] Xi'e3VU:SKiԙUZ/@TnIpuvoEӀ&8!tpK_ܝ}I~w }ݝ+>롯׃ֵk[cel$1*(РMRtkY1訧PEѪ$1g{D*+CRěK'` Y~!|@S 2Y6c1---GVQΛ}iDPoOO r*qy2e.&H.xj_$MZrV6B;q |yG{@1m/<,G#8DC 4Kd4y Ϩ= @2<$tcUUXhOAݗW'1E0G:7@ftBBd*"ԠepK 6H@Q"Θg̠QqE040qa[H:$PNpB 퇵p3Z^(X.? uI'0ֺ**SX|Oڏp > J{`.v4##[;\sw0ytpt?dlK%S.r 2YƢ\K8 G7yDk'2Fъ 6!XDCcbʸ xȫwjmC@8'`JQWa@k!с0Ljun+`&mϖ^Y@e x* u^4BC=x"$PxӜ~8+Eoxz Vaug!w+_2A:€  /՟jZ13P&3ĢEUFID}j9 Cca(8j Slk^Yx%i 8j}HCI[-u`Jpםwټy.;\7bN[5;Cܷ6ž[62ugس!\EZ٢%|;/Zqryؿ|XViLuwWWrBGzIRt CXip2%GCk˳QA*Z]k0'C7eeh*, Zy,1v߽TS 2t5}ZbJ39ˠ |SCjU+:V:}Cu @V1f΢E Qs;bjR:K[cLv=W⟇x/^bM]zED.Z^ r,b ; af:Y4KI!eL/Xhy2z_-Ah(̌bMONTxg`9q(̢ǺFF[Ϡ ՜*T 0?Ӓ+@1 E㑇%@(t.ZV:i0~#N*}:_@l ?:]{!1y@R##mUErXRaCa50fa._:`{3V yC*ϓO#Q{};Tz:H, .ǟ@f0!e/ZPYK*#q}2FHC*4 BԈQaj]5hEU =q=(ݏFA!  E מ,S[oʋ6KVcXsuK懶Hm@ ;^ 5kkAX1{lw3}:d;ۚZ4#3xΩ3z%C`MT QYrQOt}% }F,XWHP_Xrֳ]'|G D .]Tl,)؄tSǧRrT`$4\t3W BYM `'Vem5vgيSgh HOOwΝO>qO:p$t;p =:<}`K*fC b]9!5#!K㧰D %g_F1i%n"w{9}}Kw\㳕C` 5_G{t ghsȳXձ0Elۢf W]y)W3ɫ2k-uu6##u‹/k?{dwZ%̴*tdJF:#FCݽdiOnJ{|000g)p#B82Zh{=u\jwxvpf fQ?&>K/:N_F07&+@PN JŐ07njEGy_yAs޹cKi]rh.89yRG$0CG.E N|Gk ={g"~o'$^Rb/O?=ߝ60ם;Wy3?m|diF]lIʝ*)# %t7ߗ`\˛+_U@Q@<(#mk'uQ9yJ虪q/cŏxPS6![:$k`Ih,8BChKb;6(4/2JԥB#G MH+x }vr}#,\ iwsjooF%Wؾ[{-"专_amoj2*kqŘsS6*4&B,Ɵ#hU}H:W&Ead-U*ZE4d0e[lKq28%1ua#Dt)(~VSN%atA7ъ7a:fs`74qo&Zw} |mM[30Q0c0uum)ń]Սe(sA@Wk5S#ZLI3aMo/Å9d}g~㌏P!qfPIٸۮ|;;pTu1[¹۾~K~Koς:*Vrk GN: ߮^'y_lqf@ү|3vh6w鹤>HKG p%9GSR еJ)MPF^b2@RX+=K S7Hm72*2t^6_T &mbdpIUAP1*DbڨСx`61>|٠%+Wop~ -2z~ Z8&ebE谝ä鐚30Ћ7>+g^B{?(^A}q"4=Ay-7ja{|`hCs 9, 赜̊eK]YÀ(ҸSY+#ȐB&v;˩&U1ܱgj0568|q7Q*ZqùyVeCc)sQkI/;>3b}#bxk#@RCZ:oױ}]x-w"6Y )>_]Lgp_tźgĐ^"pGZ*;xT?F9U@)ʼT0^jlŢv D4YYTҩ:J V_bkUpHa:9E"1C4`h9'Tqw^ﰅChAZ(>?1 N4 ^|57y#0\Xy?{o'>[lse=j/~hK;O6kWBhFA")ʡ6zy*u D/X |m^)W\juB*>/Z^"Ay =$ tc#XZݮV#Gs& :J;*q@cY1\bI}$8Ժf "Eof׬mq?4nᯜQA|Ʌgw*^+8; [j9zwh?=vX@0s򥀀*D;w3 V.aҀR*8O|2Ѡ,zUq _H!͝7:QiUQ 1),6Bb.s (XKDMycY%c31F's{[f6 =˗\S¶= ڟng?=y/s>_㚚?ZX>&ڹgTљrQ3UZ D)˔Qѹ  VLZq񉹜wA]PeGHf&Vw"nǜ x, {1L+,PSo|bB6yb/TjWTJ2|/˯[vџ1U.;? Hha]vVA&"E#Ԉ1B-OH;-?W[[oyC+j^ \ƅļ-RD]Wbp`PG wliZ?) & Y 4o9P{>K.KVFN%fW,^&1G_{>ONxiuU|, %Z+$0uR)団܁0Rˋ,T=ѝ FҧjbG bf=^>+!#+ _g+P†Y խz0Ң.^-Z >̩1:Qn߁v髜:WQu9JtX0d=Ob'sɡzRn~nhV;oؤ[߽ p3pV._d眱QVPȘQ+,3x~Jd'GIpUa{Is[{#:yc ~r o|~~?<@>vG%cQ:#??/5π#,-7KwؼJ;ڶ{a3ah[0;Ś⧀1Ns倹Wb0-xI{'4a$X=TM6@s)],A#ff(<=c3V^j{T0i{6z@\v3c?^; ;9F ©]k\ޠ3 \"Cnֶjwxv+_bwqV`QS!,(`Ď*/P3Q}4jC5ب=:[Ak }Beێ0;&$^ du?J+nˤ}B !0/H?UtuۯnESב'Pwb9 J*_*TU]jm . 8LR zYO`hL2 0:).Н>.ڏۂ+<0αs}&XD2! }r7wcɽfB/Ppt?qA6o"/J6y`T+ML4(laca24/V?1G-Kި<(xcukkRT1뎶69geTg{^KӽeQg:3NEU-֥KW##fj|]~`6eRf0}5 R@#dr&?L3n^sHq _B cppUvOE 쑟c/;kW !L(fAOl -iEd43@jSEO+Q`Ee~U ~f' ;oJc?dR)=7㯹>ڡaO}^W-1úl$@X1i Ӏ@4BSZ-ih 7O[9 &g-ߔ֓JsCjJS;킳ڗI޷y|svc 3]9s[/O/yǼajn=F7pv^չ:mzES4Q˖dˍf @MI/%7$@]-Yi{/g6֌ya4S޳ZzֳDqEC zo W m3f/jK' iԩc9 QFe4e0**NLK~ WD-[رy,Դ}MT)"d'NsŅlpTD<}_ g-0V}NS^=e\Du8bVr|^)) : KQsUwѳ ](A V!T3 rSlʔW8V]OCTAG[ ^&>A” N@bICf;|ڮGk9'E4¡OuQgyewܜkrnd|\*_6B\.娵T!"1u'6.M֊\qݾoSC5_RgB}_ۯo*z%uSN \>UE@DWԥPNA"C\GJ=#J''@*[iͅkLKN]У>CB6U tQ;iv[oappƮp8B|K5G{x/. ̫WUq6e?tظv"-[7%!uKYXg{5u40eѬ P#'cY0#~xWSlb`cPW(QART]>xHmgҼ v"r}V?DVGiºʨ <8"Oxi\ZCSa qv=!oCht●P`FYb `y&{hz'W}<=XGlF1f r\N?oZĒ~ۀpˍ׺&8o&ZVz8y3BjP25sDz #C6oL]gqQUZ>7^ߍE~P~=s0qWAzݠk g758HeUJvZN@{!R@:B"Uv9diݓQZ*dDZLڋ)!4Zc84RH*]F@Hd@%eM7%n }wEHwN#G/JRo95+N?`Fm;<)ڏb7!H9NGY_ΰk"t~^mS_y~;e WD+CTd"1@a\A:iJd0hT+5ʑDzݎ;@w\9"*u2"){ݍ \?̘%__[g>ֶ9s\pD|sI0 /v1O;ow[)S[IiڟVutki촪P6c1D~s+DEe|R; 1rptB 4_u}R L`dڭs-|#菈牘ȟVG\7['N[@fJXaSZq'}DzHe u< 2c%Ü֙+Lud :$E8 JTg-W)cAJp3M1'{9R?g]H93췖w^𚲗%j:/vU9111|?2 mDnOp8u %GJpXONB ^+ (ZZ|*T/22r>4%/=uT)*y\ V2:d8YaoOx t-kj\j䢨GO?XG=>-/2W8^瘈pYH~h )5\mǐ/[N@9EiJRUUSLc R?{Dr'^oNͺvЗ .TqS/j8X1<~K ~Nc…uR_sO6!?q<,gpj##D>?dpսT[i fӹmMFY#=p _3(9xb9N }8)a"hLey /.*p-f3'qE*at6[EhWw=S{jVS*BKęQˏ[%wcTk&1J]P"A@$V]j{#9툅!;x8fl V]^R\KepB quv&1( -< "Dvþos [aS;<{$UV``!{0QId<NT=/9'==:C9gG3wgΗ3Ak-7woq7e #'`Yn[j΀c鵐J657I6'1%p$N5DX45h |p$G"^Bߥ0'yV8"dܸ 8~ā|g|GNٳgmUKމ YDcNDM< /{3!0 |ΫgBaE#[GB.h=?l\]B0`wV{2Sb?`U"+c`OF~:}1ŠWZ61F9) rV,Br 6"zE:*kT8  0+zd8`eNVx6_!cV1Hxk C2c5&_ uQRjmXBHF+^h,=O<3fP+Bv^4 r%Y';c+ "1y>7.\hGd_n 79n$O{y> ,[(F+,E-]둃B :NW[ {û'R*lJw+IHߴ[D;.At*_q1("tux?5 |ITwx)]DNE bCh (S7w TR8Ƭ8g-MxWWMżj CVơR)Qz<!mULûmhޤrQky;/WpR=hcDhΓGÒ0!l#ϼOMFZFCQeIE2/vJ-.sN:""8Jrg5&W\Eb+?K@(JU+JJLvmW:eAjꏄE^\6ddGJA0XA` (z# Cȅ 6j*p$$&+(2n'L$qۦ g^&{oY3\|~eM58GFj/HQHΛ[`7m[K)a$2}{H1̘mEV]Va޾&ĺs ;vEut)z@mrt?1=$jA3w-~` ?2u8>߮-61pk.ItPv< h"t51"s# j{ܵ,gRRZ=)N[UĪ{!DLr ?Gkg5N;&xM6K&0ǽz 5/u%xy840}{yps^॓) b;Vxb]p̃ENTKyVVGĄVc W$Hj@_+Qԣ)MAC}}e0nH;PϦg@3QxEJud\9*@*w{u5Ad,@9gQ낌/^lĒ r129j8"bCɤӕ(?9p<ǐ/1)'$4ئADCkM}+|AC} 1= c%%ٖ_AHY;H)[n\m)]7wo H~R6#@IvѾLrCq_(N 9kn! {wt1n=hAz<1/%qs0Y{Њm޴$dtJꀥKavH]l4Lk*<4"RimˑZ"X02!;:5AH/A_#DJ먺`'YsWĜ륟%hŝR^egvmz_hT7;I@nQZѢ(:EBŸlJ!HGN8w_ n^ׇi hz@nnp0?QqtP73F-xV=6oNMdF}|#muNdϗ!@b~2K62./TTC3njtj;gEv'PH樦=g0S]wBDdRO DB#ϛzdx0gEkislԾ/a:cv"V\"Dv /E;VTlơTܾdPo~V䜀.0sg9mN\ZAZQ[h9{: $)!F⢌&UՍ.EHdh;!F`5eeOK7فǜ#&g&@ֶV U@K玈$ZEԉ?bk3 ܅+WTR6wMo}[^~ͯbn_sr3 2/Je˙6MP+tpJ`&%&T@m~iX?U6T0U^A7ЍD&N[ŪkxwرWzK䴾j=dx>U ȓcB({џբǦ#^3~Ok5`?ZEiS v@Nئ9na%'FY}c@X@3a/™"vOeГϲkO*5qDWa!qT`S9Ks2E1AO/|8tw+chLx jI*<K.8ClmG sX(b\")Sj%+bȂAL lh[d5Wd7߲\=.hȁh.\Pya}P4 05"IBAQ /;߶7bDcvW?A#ҍکSv|%ʀUW:#4=ǒI\p'bZׁmFiοIlB@ޛ܎*` {C*/q/ԉQ[RJt!'}3t"?8h8z8( ^ 'TC-֜L1^^:1vؖ.7xs㰿OSMt-yo9B&A4mqNh}Ԫwl= jfRR0;!2SӮ\%)6$ui+Q#BXO||Uw2R]r>c++zmZD }918:iUȸo;挶 J. 8r`"rp<P ZEzt:ΡsKUUBW~Wl7Qʹ">9'AHS \[QdUu%kkV.tNP+*BF3bH^`>tUUV<ЭE'\8ΖV}- YNCgmSǬy&UG k=D7.Om"+^I@c +0~rB;Try0UZ8ă{Zq."ԍᏣc uc'ocη_gOV |!T&uOJ=Tx;@k",] (L#8 mS"UNiiQ1 *ϻpF_me6=4 d׵B} 'j@{Gxgϸah /2'uw4*I}@{jMHZldC4J!i"J,hYM|@]L19rW`o'RgxK]Zg5\c >Ϟ+e`TVGTI*rrŪ H53#H{@; lٹN7 .2gjg$%Ccu%l1nW`_dX"$y; ,"lW/_BMNu.MՇ5^I4``H,J3ɱ@IDAT UVP Ajۚ-[d;SZc?^}(7CnxhdBY{܏j ՈvLZ}y1H]۲,Pu {pߠE^J&-MSf :^fn qHA68:JX8V8J0CJ. ARJ3=D%'#+☪&L1؆}ǫ*e*~cү沇raje_2F{d›=NH7m?Է?bi1 zD+me |l:bV[_K`vX{eE-?[ѳr\bIMldϝ{:dPQYЃ >y}I{3H-ԏ蹦 :9¿4V}uX8u)ԡn{gWp֊qWWu1P!G 1Q.Jk(EeӆDvQv2[OUi ;}y_\= ߺY=OHH i4= QZbs~[:+>tػmqMM _2)g,եTёTuGqCN֦ӡukH(JZp /6c}fCMv(S}]!X:1tvkgd|ߡ04 6W8V d+U_}fp ?{?5;q;!Rc*1 ă#=}1^1j+uqyw )-nwi.ԏ!ˠt/E<` D&Z67(w)D?(zV4h[K> vN &H\E|R_SyZ=Gw;[Ѽ+\:8?^"Vd ϵ 8  W\:@΃~m u1N!묙 n-68nB hd$!/x rq1 g'J 4eh(3(E)\jZ{3}f/q A2۳8nрز,k.؆eO_V5//_ץ@w'2ꉿKaVH4KʬqJz~W9j~ǽj? @=@MՍ6ЃVLDrx X>+>^I+Ux!5<I¡*CbqA /`O =9sFg$!aqIլo u`?St; Vf}nph_ w2F 9y6-3Щ R/6IUmAїQ!",6+ >1"B[TRv0QUS?mjB # ܒN]V|9BJXHXy[Ukw`)ϟ휇l!8"Hx !+A]"}R!oZBF<66ufW?czyt1fF-C*\c=tZѤг *5\4$u)f̀ WS9ZEr.^dwKPOu hjܤ+TZ XPkaP1W"("‰&@CUh(5yU[R!1~.i*=6כ Lߔ)wxc'h앉 X9ٮ5q77Du;|mZjX#CCFwD*NW\yd(h3[t@QRc4ơz@Mxّ]פZ_9f!ue|ZJA*YGP kNâK=a***`9g);+4ё5GjB/ ȩr/T`FI!AAFodh}-56loz;T |6E,++p MQhBEh~5bs؜; =U9J@OqA  I)b*n^D!{c/Yeq:͌vPLoTx5Jg"d(ESTlUk?3Po]:_(Ws.ĪƊ1qVZ`*ؼp1P| ~H4IwR[]kR<^v2Dr${f v+l7"W#R_n6µ ƪjO(8'b\j^gn aT#:>N'L((^iswaPϤC}<~nSeewˀQ=#PÃ<.Wt,0p?BtF;u?z-H}UmDݖO}4^~o oф edwj_:a|ߎW`AQsEJ0(r.І*GBrzBc!CHl8/6641P8 "Bt EJ$2F9 ]}6g~ަ4HT$=Dt`率bC80 m@p$]cαeXJ~ϯݔ\&U72!9QzL)Gڡn-n=}cvpC?f4!"sDw#u²jɱ[RJjt߃6'Ϙby\?s98C3,r j-CDƃi;Z4泦@q%7?kJHzfBƁft5Ae[X+ ,̋ވ+n_/:I .:5I/mB-; =Ut׿|ʡT?TTddbtZ[] P(1Rҋ(]U qP bAJw9'@}#'Zdi8jz{)fU! hY(6KQ!.iv.ʅy9 |ȂK@*lL9>oX_c!x9 ҠfD2B\)%J4$;t8MɝZEE=?Aj~Ѥ<qvdly *}/fde3p0$>9;Y4[r17< W@B<D"1:aBe6Ij[iA?sEEGlf OJf2orfj@|6$a~ӻmʕRؾaAlz5;YY,G|Z*aEv"<ֽ~3$הּQȞf)4G5I֩qOA-PllsH'}֮0jzKwWTQ}^_|v$X] N+ۂͳ7ߍZ9*^sݶԺ*9qԖ/Za/9Y766\Dgz fRՐ\".9u\O]tt=)*b+yWh BV(%@}kЄOk[;?ytHfF吿cLw%C.ՍϢUrSE/k8*o:ȇ=Ӗ^az?VU@!z f3Jgx473HT;GDqbRѫhrf뭛]ҞE}9>K!Et[N)GJ+ =[mr܍o|3ùȻ '@cTE._aރc+X?H N(} 'PHΦ8,GpfIe,)9jS$)ѱ.s#@9Ȑ gh kKW j3W: ;rIx@{{"&ђ)wa y| >* '}p2GGhvCGD:MM@^K30\="| e#L A@5.yQ>TEDI$RqQdϡ 8wNeqju=E\HF =9N^PŸD0|ykDq2AVXtJn^+;aU1yatZmNϢ +!Nj}huʅ*T邔t$ErSAvb`w'%:sʑ_Cfk6\Ls kt"<gz9>گ\<4J\܂)2N\_'ۋC3kIgEf D'>8  Xah0v UZ$`[fb6VMeBb8c]};p1R%0PMT~}H/۲U@x'Jr‹5VY^E5@%j9JE_҉NIJc0{1*2@Ts$$Is]_;^e'_=nη~#W7_kQB)PXkaiDrڨ_{n{vx RPH(s$W7WW[R,x~O[[/Qx0JRJ]}?-L $ )a28r2|!pҺN!Ñ{тTִZ:4W&0hLғy/04p?;?8/L|'Hޠ*{/Z٫x|o~/D>uQd[{/ω cUxꆺH}6Y\1'7h~#˕=OK` D}&1VXi A˕)ɮ T5yJ#^˘GՈdft:/~)"6bƥKQS!A_Iֽ5QPiȝSWWGlh۶>%;AT. P6+(pNI * r"y9 TנҘ0'%+ٻn{!P-? `cJv4Ysף VkC~=f׾a{GFTb)Fۨ`>6oZC<s!86.)ww_~r2rV:>-Է@JLdۿ b~3c[{Jbq(T@%mC x\C#t!@]2k |j q\Ns?taj/36IY|(6b鶱ߒ[+?xؾ(hybȥƿ.W=FbkY^~Ks2ŮHP69OE .[=0rZ2Zu}3@c>t[ޕ2yl%$^F_22")#^ Ճ&-LQx)g@΁DtD$ # V@͝5͙nhVLw:m[S3ĕAKHr76+ܯvBnnS)q)hz@(8|Yn_h-YRئT,EqQgE^$jpzHgH!I|)!S<9xk,XmoZgtN|=oqNjABP Tja֬`'cW ۂeyW1S;:}{3n:Kf?-ہhMm|Y5ҏy5EO)OL Mjj+%Ճf<}N6Zny=ط< .&&TᓄB1nS^uB& .eݣR'{oo[dϋL_$U+{#oПYA^?Ҧؠ"Պ2@SP_>@т-[.gW^dkuA0ob/==vF/ !0Hͦ /J2`msK8TK7!yx[[l߀:J;62159ն{=n#1>sX}8bܫ@e_MbV8cO1=UYĜ)UǕѽce^IO5@V-.* Q5Yco>+0aüzNDD73<8 RyUދrr?ы (GS6yJ/⚊aLK=# M NhDxOYd<1M$R{X0ͽr`kD$Q/W)U \st* B|/ɐ!_QdW^_ D bU(/N VTшD r3n|KPd@:Dƚ:\'㴤,x /t8/#ۀU8~NNKOZ@@Ư T[pP>Xi9)=WfA\* *0^ ?UL"uoB(Dn92!UwtTC \eӋ\3E.-MP;i1tr}3pz¹s4sC_I<Nܽ$8o-vNDR%1zyL*$Ui5rXu#v΀5Mt cV~;wԸ:ALpN'h|Wij:e}e{]?ͼ۰"N#uw`Wq R 7;cpql!Gq4 -v=ec!:ERMMԯtztrr9vAbN g璏N!O[]x!u`jg^pxHLspZ&/^C=GJx?IaP: Mu?*~j쉀Մ ]|Bi%y Qm9|vLljYL%o¼,J7f q).ڋTr<9Ta8! 01 ' eUY] FU0p~Cc#7y J-f[9%(,(SNf uftdȥ!uʈa0ZI}i-^m瓇{跫hE{d*,y? #TR/Eo;v|m:l{{Qn,ྗ27!8~ R$)t諭TP6kjqeݤHa:'%lT7Ȗv ߛhTW0ħFZ LmBn癁ylRͧi<[r+W\!Q)KkD si+L:`XB}<z= uU kEV( V٬{:]{|8jZl)+LPUf%87Jp78h<7o(X54JjqQx#酮~RM ҡp *ǩX`KdZ#ٿnJ?={LcVKqy133!#Zw0$B,@hL_4??"Ȓ!biCIG#r( HIp4?qԢ/*J.>bY9q |A5=!XM>ն} G(s[W=H8pEB{2)Dc/67FF-YG*) ({pjICދdMi΅46xȌHC1E,yp(+ r*28옘cB_P(lS;?/{M0"S;8'd-Cgl\8=(غ7-OGP|l$PE">!V\@+b: ֬@/Cf/m7a5"N[Wb|d\ kt\wmc=a;|ˉ My&l,Q/(UTk\BeM孋pOq uTyn31ցMuN0Y<_(G(PW)^QnUԅN< RY&#uGl~~}[${̺<&~aW^h7]vn`LLqϰ{trChR]u¹L%-MƑf!x܀8k(Em흖FJU!266sI1 q (Y4Ғl'&!MJڝϟ^'`&4@=E?xea~N^['[<^o?f~F&E@G>W!^{ۛf6~ ;X [E䂝 *b;-(BZ\N[ZDI):`cZ^.}gPzXѭ7M*= C7m) (VXgglŢyV4gUd i4!)3XtvT%g4E0?J b|tlKkͯ{"jUfaW[ʁ] :T!@ՁQ4Б${UIm9smLPMD2Ty` ~̟ þNeOzn| ٩G^xB=*TM*qJHd:Ēf?K8F49pĞAGAr`Pv,PDU.>mE6m ox~5H?*ƨy`<$2#?yDsnJ-t݆8;vh/ahLρ~=0ie&GmoZa?S{\vdB=9IOh4tsO-m#TgQ7 )x\ ==]90@0yAD121 זZ]U IP eդ.|~33aDŽ:|'ldWz!q^fh/᱈PTH\d 9vi+ Oww0;rlf@.;7ͮٸoi*hV.=E@|sU!}jssN2j#t)WT"(_F i]̓A،p/[5 gY4?l_p!*\sw͇<`uƒHEToZg) `GqDwR u u׼ĀNH({f#N=(˿SFV:[4TWFm!EH̶aШ " /RZX_Uko$}Q,qvF}[_=Jz!>{l$f ‘86[o\d?V]v--ęmN箵o m-i6;򄄵j5:LITG֣֟Oii"O"XA phBœ"k"JJ/Vǒw} fNMh `۸#,σNp_S@2~>|570k_f}h_W\c=ض\`Ou1<Z G[Z/aucdfHwv:)̩}-K @~$$5ъ@ fç[g[M gHlC!$QtB[r,60daJΆ U%'$B0\"ʐo=~[<{V 6vj X(^9֞|ine,bh䂱!9z8qTyHDē ,:t2f*T` p 򧹲;/L"TtB*5ldd#OB[a窲v+/J%,B͏6uoFHM\T|D)auC.a ZigL%T lZ{bQPVZZA9b- wHHo> Lpž;U/L{zZÈA-rLj(kxhDZ9:*!+BI Bv'SMRd|U NJ4Cs,]C W46\wrO^ P\A^MlT{qh=|mʘ/y?C!3~b)a߸b z L".4AԙVz!(@Ry[8EClHC%PWg 3c_b9_ *n~%z(`=D}=A63ϜeE~t)І*U;ʕڝRڀE'zr Ա (V!ju3?[M`@uŘȱu5tҴl~KHpr6Iϑ"1#(A$9rUNxUvpQ[ ڰ(rjΜ~U3<4BVYi8Iӄ|D8'b{[BjC| 4|r/q N"?xڛqp]"qP@D_Y}oxJw~`Qn5PO{Oo~hC6[<#dwCZZfy< ,Z%!NLm5PڍwV6~8]6P ;pbb# Uth5j@+|nKʛ> z:O#rvEG2salǔ@2iPh(=;Pk%W= y\D"?QjV[l(g;y1k4j}=;Q&]Zcwe3ٙȅٜ%l՚aχ H9T$!ؔ@.uliS h=qLN^ѿHFPZ1j+ -UGN *Szv7v~LW<fZ6ҲWRÂpϙᐎqzQ"t#b0``E@JU3p}cQ7[i7oYkqtM!E~R`|X8WЧZ=8L)Z A 2TOK JوD jU%J'$|%%)|{g4x|;v hUg?usxlΌmtBOX qP_]e'>4> Ǜ.f7yǀ蘝+yYlz1{A.~l7 a Jі.f7@=1ۃ+x ?m4닽 [*RQlDtr%tl@6(#/#= KQx9 _ `K6xh42RS BܜK~b'E*csFEH7 TRVw{刨+jë驵?8)E|7^]CFZ12xQ/S^冚V qvQޒ},^c|I mlQZ00:P)U Kdg8΁lpN.up@ljfƜd7{b7#DH*Ke>QH)p-){|磶|(szA$e_* v|罾'OgegOۊsIT̚Y3MQ ?UKK#5l:EP4'/҉8 `.O>SeQqwDV&{'0`pt~\D.?7K"|EO',:\bW2k<-; ]ul`!C=/{6p6_l0ډC8jo&qU 8 Xڊ kD%-{Z۸pdgaƀ1&RZVj:yKJ( UpZ*%0Q帓*e?A|.Ghq2j/T:&|Nʶn}67Ik>\$'%lר+W,B c×3T9#\'P5(y2+.t܁8뜝D/gkuj|)8hhCUl?x} ؔ?n8 AR&i6CNȔ:R}pqAPT-u!-n~Yƴ<f(qѱN@NkHo-Ll: 1}WI:>}qBh#-~sf` !D^KQ*HP-.Pu¡T@8JRs-h+T3\50@{l9ð$5G&٧^ȁzwOW70DOěs`*Xc=t]nβ}@IDATz{UOk5U=XV `/q/\y]VY}"=eDT!%B$ /#_TX4Q7ݲA>0HThv+hzvT`nPt8_04DqK,2{Uwd)ټy Wx{}ckFiIA50ߝ/{5OWߠs`ڛ; &~[!"庍KȁV K hU3ġ#h|ƵIkltW>cM. 'BΫdR 5DD#DjKU*QAVa"ך4-7 Ǫ i NưH:R Bِ%x 'Z JDro1a_) p;I{F.U ؎$>c@l'ϓě)Ľ.f@H{޹y[cFBLKh_9}j6dؠ`?@i'uUĂ2d" u a$[7Zirkosy⥔1UvX@&!@ O))&v0w}uv~mނz^}g;3f*ȥ0 k.,d=OAWDՍP$;KHEU!pG?[?<:S ,?Ĵ%64fxPh BR/[sOvvݾғ#м@ ⓕRyN )&/Aͧ1=M:jG[ւ$t`4T(MΊ~=Mu!l)#+Uλo l/hE/M, Obs|^X#ԢZvߴنh"}aڟW*)}izNF 7b3-v .*wvnXV4)q.TeQ9Er3 Bɟr?Wg߮=h^v[g `_# s@,|`XӽmӃ=,Z񴇡| !XV_Pg;,]wlr)GE\]bPZZ×dDIL+澁n&yz{7 [퓱I6JD !@PMuv! fYTo*{eZdu N/ag,DIUM-REXݙSx,*ufABO7]A?袘"'D5/QJf1%gI'MLm2 qfJxI<tAU8x^ǂZ:H8XVN-^us>{[!]hq>P4^`(6,`c~9ң@0 ;2n6SLW$S-y7xG(SuMV]3/a/Uuђ2]TSa{V_/A5%Gᷞj-rǹx*b d_)@jQiimm,zG UP^|mM2HnncM51SRsL>|d[U$ԚZ&H^` q(e; 2-=(춛 Ku ڴiě[WtP06}P(ArRK3$aPk9h a c K˶_yõXe;0ywuXa%av@ܗ6Z^yxB>4VBWE™suEm3y3HIfNnXr,,-+^!*r\I@tݯ0;݊0w?ҡ/:/a''蠘 ׼?mE&=8TEnq$R$$;`Yь~d~-zW{ܹOk[py~˙σ5#9K ۻ]ĥ$~,] |ɹhjk'c'_Hdx HFbxģqSPmF@݅7@2Ц&S\S| gHNE d9;N&AjA֔=._.t*]r@e$Q߄N&տ]U ܞ0ߔX8w8Lv{K jkSД\|<,xdAL?`OX 555A(xWM2$HO+)ȉoAʚ:TeLkCs.K/ 7ug᪦j>:JaN(VD*YINJڢ Wտ -ܲ+?. iFrKpF )IfII@U8䱩!7GjX Dz3cVb3 \'5υDGW{hkBy.+ZiCԵKats5c 2~L]:#&!#(z(Bbb עE>$ TF+ ]֔da1, c N~7~ݎ U XBp}y*,M`YoyYpz}O[ KVL0QԼOHh{vu62C 1/#-ݵJ>Jd`ĥrR,ȧgNz4RTR0 (aPC(/˧BS-ҭXC皁0pGQɣz{8/0 7ACxK?s xx?3/-և4K 8kL"G8(%(e? jc0I;%4;0_=f^4 hkk7=o 25$GI *+-Q'g`ӒXS*ϖ-.R;uf7ȝ-c._tܜ*MUk^m~#S˨E%s@UyOHN20.XeTr. !B>mgn ^?M~NvQC=oV|FD#_ Sjѕ!=?Jl%,<_=P fP^tH.mݣZIgGJlͦWH}v{N|C9^\DTϼ KN?o70uoO<姏 sΣUN}@CT.㮪TQD 6x/~8rJr=3֊P0+Gb4Zz o:MGD4GvQ~ *,xT$8}H3WRE&ӝSBQ Uuۺ+p#¾)7ӊ81$`zi ohǎĮ< E 5So~7s ln 6z] Qc@B] t jTaW'jEyN'ᢇxQb4u4x]'9x*Ix!,%+ة#'mnؼ 1VP EZ-Ik8PġDrfi_+]X S,^P?1d~׭$N}p|f4@HjBJJ䎗m{x*+lŚM$B{TnrL@4X(#z8>WX*Cs@\1q@iu7f6pB 4 Ha shKjf{{ԦŔl7@ECSn2vXq9F;[t&lJ'L0o5H(Χ8S_rBy<ϑtw2'{` &9D?ڄhS$GHѫLF<@_mD&$|'6.yID#q{};:A/:OM]p^O'w~Umc~|'xX_{dL9qʩUW5>Ð)d >I@Prt .γQw'AzRRÁzEp+eEsA3$$atY &t@ T9 0DAQb̂C3x08}iVw}^Y'"Q7]877|tr{ Fݸv%%2Cf|,|%$=GS 茈vj05@P=+^ᐄL5Qt4Puk;@j{;S8 c.qŲ2wMAoݾooז.[Iy{漴Ɂ*pCC>OQzh,nIIu1:tzI`:H\E3.{}V7Zxc#$cV唬u;/^'^=o |v(LܜRۿ{@,7P].s͝u/}(g1`&1 Y2 JW o ?%Yw# (_c@A*vNBdVR|V^$RA7K(ˢBÚ6Bݠ=P%`# OtgY7*􍛷[T^wmNƇ~A+,ڃc&*.A@?%._Q#x UE\D%i뗯M8j1D{o?UoS'V-W^LP4A*ǖ{W-,q'H"@ctb^ɕ6K?B&/EF\u8:㞡'N[&6FjaGw;Jg8"t!G~{_{FlDUo= 78>JjWA(̜tpsM MQO1jrT`⏿[i;vl-C0,;yWS"`و}fSUG>23i_r7;j:[~q!u{ztDD!n垩}TN4z  Vpq8D]5hL:9g 2>CFq{>_`[~_Ăh05 3*+{Ǜ{sE8ynƪxo3bsZ{ݻ)>VwO>,)1,L:W|Abz=]B% K~8AFR}g^Z* T ;A@DHMS*55z#~^QYC5M_5\W?큪5 BzY\S.@}.#@O=رq\~| A[OB7bd* P(q6BDku];78xn\>lxG !9P).x$r2 Q/Cc TV'07X[7UN *Q^A pcxgԠYeE wHG VpmdMb49-^1'Xx*PHxW[v\8x[vL FRN;TyBbhgn8U $zӊ->$4^h`@7DdAZ(/>w{΀ GdIrJtb Ɂ:*z.\6HX8!ɕ MR/vvdL$>]]!&W'?ykô"v$c8 6!?tQYɚz/qi*}+B ;uliZ[S3@˗-ExwʌB 8DoB|AKC?O!)Ii$["{WXv9r8dM]YYp1ښ)X^Z h3x tUؼ}O~7Y: 86V}iszrR?x:2o\pv)"0 5VVKR殮a~pZbYi_°(#'{#RLN(җ~|PIȶtI1 KX``3 rwܼs!P)Wշ TM !{y}r tr`]}K3@HFOhf${/:-C2M1IZ[[+ PAZ < hܯ~^W_h}nXx\mޱAI/Wa7m`ԯ` MQhJs4K`bzh6 Lio2 :C=i'gsM&X/3!Ғ}$UET gOq7n _O$ҿṾU_/X`2xn1扉Mu1TUtP=[rTMI t{nx`{:jdE5O[zrC$vP_wK NCHZpd뛒ۻ\;B(x KT: 8]Z1uǑ ]0IH] OyAHmeօQ?9U ͿHbG P1PC>(CBMMޢ0a2ܣ^,j_Xi\aY/Awb*)GZ3Y9NSgpo{ǯZgk+7,Bs;Z▭^fTdjA\>t I8Iuc\k-I8ڸg O|O$P2 ãOR\4 ۷[;PҔ Ww@Yxk[o}/^gDWrpEQ\s~*SclLk?u#D^ڤ؏D[߸=׌A/Z|0d>2~>g^mmm-mkmCsk0?]ogkkܴ*^j<޿XsSO޳@Wޅ-&l~j7c,c!GҦFg:^|^Mcӄ4Z5$' n8b£r#vA R&vy),ܬ=Iez.&0ѫjUEC%ҖEWYkר57 PC]@'=0~* څfO1mټZ!@=tU|#p t6@@K_Qlvn),,3gC 2jLABY'ZW-4>4HP(A8DF: T?]5s; / B ɀLixߡnn44^N#no8J6aS%jۼy }3y]E*aSCnyc0ԇ\i^abks+*֘3?p/ \3!J$5)~UvP޾ogOI~.*%@FJ@#Ha5nɒ喓Mw=jn'ēNUZXh7T!\l4bD1<bV lZ zDM+ ;*0m-vi;umں+$C'aY\A/`-d[h|8 +׭z[8uܾDi.K| Bt*G眅(",ed3Jš~LFyR O "AR ܥiB(Qg꾒+zun;vrrv,*cC@PG ')teT]:: Ap-Y(+Ct5~FJ `jtnc4 uAfU hQȤo~P_\/N0'Fg`ڕhqK: lm+V.m ;F׉H C'{X s QFD# Ƃ -do¢t5yK!˾? #?\oҝ3bO-+P 20 E6: > ۽J+Yv~+ľw)3Vc`kn OtгHݤjsyaj.zswvub4='TIio:eE؍NhG嚎J xHz"AȢ$ 3܂" Շ8 B}0K)HiZB] Z, if/ǻTVU0[_; y:i Q0Ww/I4! 䉯OA9,F^1E1QB6:ۯ|_ԹN IO 5ҋGA3 ic{lEYŅx?/ܳ~Ϋejtt7e/<5-)!$FP "InڊWm '9|5s~6|?ƃznֻ?xcTvsOI O, qxylkN3ï2{zxvxKVJog|xH@ \4Ute+sDU2 "".XcʪV-p*Pjm8j~U)4/,TЀ>ͫ2-/ѤN ):S] Ԍח/eG]Un Su5(` MeP%g`&b4Gh@'q[ojMÇ6mxi~gOyJ!g*0v iOǔB3ABu7G"x>{-:5>z\4;js)B_`0 of?z(o{>}kMZy?V8 )-)Ÿ?tL *u: y8++5BS}Xs׳GZ!Gqkc2*{BԞαn\-@!r;k`Ǭ)#,YZܯorֲ&>.oY?z:h;6=#Bm4H3,VT؀ɏmYqqtXm@A&))v)[3Eg=@ڢ$8㟈|e*V!)$2 PTQgfQ}ƺ \֯s"SamړÚl1 cA&$Th,VbO-o|m-+d1ٲ@>v&'v$B8A?=WU pg}K/{IGzD8HBz}5?QZϿ SvT<_̞?{w|.V]kczo %I_g(f{O .sbͼdÂm\Bfl5j|?r1xuVSi`:ThĴQ)N㫦vWU4[^xJi]b P!Wa?+˶QtP+ WP 3e/A9cc_AFnR~~A0f .hC*ڠ 0?j&n{ם58]MD6AQ 8@?WSч>~uFT)PQU[g\LLCߴ]nqmj{_;&9U '@[<ե\W|c;Z)6(?Jl:n'怮j| tDD q91ut)<"4Ỉt5躵wt:_ȗD$XMIqR:ݣiλlBzE$tSOX]/i[ ᘽjq<.W &h%z2'H@yoqpY[8U D,5#k\8KVR&˯nW3K(%*3 QUh<.mq 3.pICѩ3 22,y^o TIҚ5NA UT|Fs>^jZq&p:pY2#WP 9j? .<2V޸G/cSb r_ a1%|Sဤp|m}.) -A&"pSdo!Ng 5PEW gsz: +jeN9$r&G(18$ P+EՈ泇h17ᾘ%{%)2~!q M;ost@qi ^ et CPqTKjBHJӠM'8YAjmh3nV=ힻoT*E/~iAVÂ$CCAqxI8J pmb BscP)|2.PWZ;Aäw$2Uª}Wsi:{s!#$]{i>pOe+lņۡo_znB_xM|oӥ/^ <#7 ;Fo^x}.me~e^f·}~|=ڦUEѩ4^N[,7 تfƃʲ L[H ,80*RUSآuxK@DH"h|g~ML^n@IDAT@JAu69TBII<^V(5fŲE0G"]P *\⣵t hD5zկ~t@%a`1_4JXdAz_gRk*L t3-)#uս>*^4‘Pd'D!ČtI édAr(>3pCSܔx ?`Y(a[VV4-$`411B`xQ\T32J2).].x7g p Ac V'c2RJcTa%~ژp'&d MRy/,4%_>A53g$$VE(ӛ/t0hI(tzE<]}EU "ʧ-!#'͍aLL %xO^%kI_P~nSqϽrw\{{,B2n::ӳm6B7 N^!.^R{hoU,*e^B,s$=]tQJ ,oݰf)¼D982щA'v` N^k 뵸’*=H@ *IcMa2^]wD꠫`B,V`_%*Yjd$RYewlGh`V\40$knek%T8 ]Y՞qbwO#(K,zAO%`q!:ޜts.))VR#@ r}%fCEWIAKHK(ںDGE\gZC+w4Kp(IHI{C>2zHԩ*DJzDc@(ÇH8V I*ΟB>4GB6/V`!I: dzTYUِčcPiI)Ndƺ6w=p/Fkq2[b1Αt=@#,H)iPe_ʱިmZ8'IB<8FR%Dg:ڑ(B#d}禈Is3 (DǗs#AӽҼ%C8~>'ģRbw.trۼ%wEzH;kc}Txm8k(@oa{:'v2{슿 NPr C;Rcaey. $HI_CC|h`TE\)~'T%@Usă*"ng{APaˆW 4^>4. ]b~;x%ťJ<6Kr5>9H$r/z,A-9f l۾0Џiٓu_>y vmθK_C.c++Q5&շyUJ$zo l% QW]  t^Y% 7 [B!QѶf&nqf цo%)9?0Po 3J@K") s!C&U٠5h'[vz+#իHT;lIY1p~!|D||h}hhQRcQ7ͳ)n|j|$ ,1CR;UtC4eza̩ΗH`L2z3G$1.-d{d_|U -xi*bܭoϼC-D@]" Sbt9vEt%~D忕]BQ{< U y鎫N25\8^*0 -kӳ-jiя2 C%LP Pǥ&jZxmZK}/3@8x_/ZCK1Q*^hCF@%~`8۰aL淭i>N3V P1/`<.A&OCz#a*L) .9<(TURXq IC, r=kK%`b_h7:p)~VN@ڷZWWl³S$Y >E*(=#T|JZG \P,^Q%Ί [6tz3g^$} *vN^B$TB%CmA2-SVfo~[Ps`2_\)WU/sEP2} jN<\~wfJ!34 J^HfI|GjSY~u~DA@xG%I$E[s=Phkdh|J_nh$Yz3^fOb 9){?J~o<G88q(I8Ww?oojZI%DfwedCVT|'x{LR>\BSGK&U@׿6)N[SXum#ֵEtg(jFC2E.n@P:~,2<9II .ݼ!K&!$[!g dA3\pz ˰}G?qk6pֆF}HyLZj!پ܋N.l !sLDZ4pi(+]2HOբ4 Q$>s%6#ahPd2# 3v`Hn -M"][DPfR};:Y )(KV>*Z;>LCx0*n`rY1s-!&c`ޮ.*k$aьZޏ*?6fHSZ[qk`oIH(@i F6)[YF2D8v @k~F ܬ/c\ĄvG`vVu_DF)wE%V$Q(.>qQ3P^N%tJNt5Bmď!M6Jd$QcmM5OC|cI3h!!WuWs@}{/ \b9ۻ\4o6]AQYOi^Ѿn*1j/}j|y'4!Ѥv?liA|wb :tR+Ÿ` IE# pk2+oB"*~(=kO"EPgڡs4Vyt4x&v7if&]l:; Us\zlrqGn&\ rQ&r-m1T5TQ$2+#I|N(C_ |Xۇ@~Oߐ4>:(k ܄8 kՈ$x}O;Շ "(6U!! 5Q)}_(CPZoC0I0p +imKko$ 7;ٶmݿ׭YD+)[s8j@[QA6hI &g Հm' "qI ̄Ιd |rj[im[Ev8m3炿(%cgW8&a\Lsr \wDV}{Y*;TY"\D7[\I)Bby J"RTK>[ȋeB*qBN8ns L!7E u2Q |DBk@=LՃ&$%J&^eP%% B,9 m_F[aGMɞWweN?Nj}f'Pq6`s|(os]O '|~-VδyykP:שԍw?~Xp:/ODo9~[iF|(a*>c2PjiV ݁ja젲mO pp*T~䪼LF'ۉg@ǥvBh(=vx3]ۛij-}X&8 X"Bn .r$6ӪztIccTqsp,U&I 6!G<HHj"6׸6)Mk/EuOCP)CfZAh;^(0A).Ӥ^6 >1~ 6 4D'ϹrmGS]8t,3XGˠU7@"qZ9C3׉ok0Ntv"%p̂H% i4tNj Hb %&tTCgf'ND;B*j=(sV,_JA-/(]h+["MaI5hqLw=g^ᦻtI(4GS5H8HΟ#΀tHPn֑\iЏtMná.uD{d1H3 h)Pg}Io?4 jYihG|@-.'{~%1 .Wwā^+jO̭Ios]ƽ3k>S3v2˼a^NOpz7w5۷,^F7 hA;JVfJϨiDf$Urba;uʲf~yxTX;ИL֮^IPJ%P W`/W/ C! yTvJSRMV}7ƻE\zf{w6R 밌:&I_`t@hQOSMMP5O,rKzNM}UT(i[N;1 \/!ϙqtN/׷JZաݏfd}$$SP"J̴1)ԑtpjQmrT΃b|r_?Pg%&KN&]\߂hW7> T.~GTXWb6q H㚯\RFb%h + (( pOɂ8{UM$Py$MT0 RD\hi'څ6YtKg B~ZBUh )dG?yj n>{ma*HCOS'2@Z.eobvn*. bԳ% 8r64 *'!D40#;|?Q_]~?yM>;8]ozpa^>sܬF^=tx.>Yo5^ % ʙ,Tߛ 2oz6fIts"uHr}'@d+`Ӫɱ์nHK}tQmyo@Z`?|4}03+%JP=rCϳ9ۂocd $1K#e:#T߫SzZ Q=gl_oS-;5x>[t>WcoX9>׮p;sc > |wMOw|ӁvZ'ڶEi.@U-Ͼ.xַ^y♬6I5+7:@KAC_(O@FAEfj$,[A6A qY, 4_.{n**h}nA'dO<^,Nz;MuXf$x[2DݞnAw, DVN6S@' b!4%Ņ2~9;4Et6FHiT$ o-Ś3}@PҮu8*Z;d+@ű*񊍙LMĄĤ+s_|4L&Nzo!9Bdh$\nPyQ@D; A;-)Պm[GI4m+T/6x[ہ^ܼLs p -:!%9\[p`ʟ@I#zJ@z@yx(%Ҋ+nHCfLʳG?{?d|'BߜgBXaֽKOn%]+@۬{ 5X.߽>,PIDr`o)m1i+˚\\Zk5ES &¨㨴cQkSU#NHNuJr-iw baQ4/~4H0#?DHºiz]Cjj5p"!S@I@Ɇzo I> Lktp7FxX̱3&(H7O.9És ~8e9.^i/ܼUKw10Ed:/Zl㒥uQOtuvGQ-Pjf bbDŅLKN X%0ez-oF8 WNm :lph~p<6"OUJ;7329KH@LPf͑Lr$Awys!`ʝ0GShUJp&i&@{N;C3,]jOiE$8Y. X6ή,$G=$v“ "n--)r݃[71*גlC8Rs 4\!`"'l VCK{`w'?g,%></lm7Q5\䨧-pjRqؼR$V1Xy_:TvRC.n.Z^inn.-fBTD=hQ V5wם SsUKh 4@u=R6PU_!?E\AmwT2sIKexvkG/;Vv:Y_>Zp88Z\}j䫀> wǭ@/ڝAJN kHPP^bh /y#WM &h.LE%^:ɏ)E`/`15}@'slEUyFu3t|@ۡ*6SMmѠ ߲!/ii 5]=jJQo/HZ4@>'GC )(5]O筪ZLkliFtp[@,4+ z/lZaԅo}.LQ:²%6sx>$^QFM}?CSqU ɔœ8(!@3Btyo+P\"A6!<ڡvCbe+n|⵱{h9_\8G1 T\ydϪϽ[BCҭq5#'7W%Wt۳,웾Oe!íuZ۪?:HR3cRLMO4,'Ij[|>z㩶gu_|k4n}xb&8^,q?{eWvgzs*rsN$[$(,kIyeyi,j6mk&N 6^F|bue b tP"<-#$OG 2SY(w--W)xauR\"l~Zh{Ds(g$uz[_c}%|:pm_s{|s_fݷoFF0m/^JZ&%ktd7> eMBfgaWJH3 f#._ƺ΂dIad(h(&69@l ֨kRO'R,X 9FOQd}EGG6I*BB"e{&[u-cV0k4u\E`¡#wG>8|G&e4+I\37뼁ꝧ,~ B!pR@.a/GX b:f{p:q0*Qޛ%4v߾XڸVӤGl4 F{HffrOh(#qB`*lb,;0<· 3@=*wtqh5;38-F޻(83g~`S#J_h!8D("HBm+m!p>f0h*,J"n\1+b[a,%HK-xj t\ZĄ1Ve6.nNH=8HJUgntqnq 6mX{>z^V|89yH{pP5pLXg/m}u,e>_@{K&3C_$zj%iiWv}NGJic_4}1k&n0\G;y>uNFs=f3JN~XJ$ rMM.j^{F榬O'TjfrnkF5A 3:v4`?t7Ss ]+,cIQa^.9u\bW<=6v̙X" +nz!#&c`cIeA !ZςxϭAbm[M4c$Bg({` pQ Ƴ4dr}$>K~ XWIxuH(l^زuBB} **f("@Ѫm1:WAZđS<%Jњ럌ra}ar殭8G6: :hQ3 "gYpq(iniU뺠v>x*"Qqq֮h0uB2eFUMiА|y86 kg@RĠX  U^<;2Ϣ;`j}]; 57*!bΰΟe*g8>)=yHH4DgB-:ƼpArMspL:a[MVrT6C[ze_⿺)b?A!{c2b-!}_CsD"#lv+j'C2]_ &7w.ϯèHg _m$IdԜƮ$485֒P'hZ%>zoܨ݄5~on2MXTS|/,{El3 (:Kd>P̯=~#?/JE$gRD.٥fs@E@,aRƶBvэ|5060赵K"m#ͫa9p?Go8 ؤC9W؋]ތh+0HC&, |>IШݎIٰJ@K#}Tɺ8M?D%<cԖ[~~?vv\wp\"c]Q$SKѸTGN}IGd+ZPC73FՖMћɣSúUThK1QQ,-ҘFs$d> A4y%n* v,ar* 3&Qb3`Lm4- ״/ ϶ }8 "^-/~&'c!#}9XW#8TTZtS>뚛.21t"A&8'~>l i!MoOO*x7whΝ*ƾg9qc>wgFzo- yz8H||3OpW_rN%6iokOJg70:sJP3mU!!Q (QQE׸|CRzUCh/zH} 5A(˟ݜ-DioF(مzm۫GS+A`ԧS~) {wY! Aph,>y9Tr1^SAMFQ.cl:~,_dRGc~\é< Y74I< 6޻ss  r_eHgc;{r%~\.˜j̛<3l ; pDs,L,F>[ i0`  ;/F՛[_AcXt1Ak"lI"rfPOt=3$2pPS,/_KFgJC3 yX+9b*+a r6ى55hFgJw䩨gihtX>'k'A7Dk,!cUѴw_ ̯<88zpD/l2亏r$ֹv$ 5_LYuC.3_/zӏtY_#C~13r/8Z]#m 9ѷY_DYpraI/}ka]Dȭi(ͷ [ZS h""O6k_LJwr%;)X 5NwCh Fb·sU=u*1H3R 0.g8w/ bG ThA )aQy\I[*xh@E$Y=z+6iҽa6P^}855:1h Ѐeaي%)gzd6185|mwf~-W+X)2wm=N:npиWI:Oo4)ciÉ,V>u36U5z{i !8g]3kk >[8Ca/_u[{ @@q^92/B|('4Q6] V9{)pgbUΕϠ9̋田4:ݠ%NwI_ XilػPh\TGgPI=Q@e(Sš9NNP*?#dL9I,`)u|}yRS1S. ڣlZGUS?&"+~V?8.)Eþ>i55OAU(,s7;w|EAz̙l2&;年p.ޝ515.nf%G xZfx7L ]F&j79#7 Th'-0lB<6wCb 1~4Z=Z:3gOb81j2Wpfb#Ќ('A>3 7'[0\V,x_Ιp<{sO-ׇk=t-^'h J_|Bo;$4qJZW\=`ev֧Q6p H_nf>-;18j3qtt^`  pTW2&Y5S7~ !VV4RV.mRn[g@Ig . 8k33/^ .BL9bYяat^]+=SR< zkrއg/@\@\Z6%˗yPEh)-e~\ѧ4^s8V7/Ɏ+/ WP4Zs[{C$Idq-zIQ{Ŵ@ AfI٘jSC? 6BT3 ΙxΝ_zf;sZo>?#3/oyK G̣S?#=wivWm49shW8MEei( ?k~ިZ|v3lt+l 4D,xR3חQV]ɂƼ+f͐Si4,bC1`/O]WH; C"|)lyٳrr@3auJsR-aQc aK}Ly>smer~Պy-lG;XHsq_@i^=um ?N3 l޶{ t&A8J(%"?1} ` EU>R)A8+/tF=ub;kۭ35C}o =yNI!uD Dajq w@HIш?!zQX)\Ag{TW<" |9_|I{S2qR3@|.}N-gxqXFB ŠKϸ6tZ2uz@@LXeuh'O'åVTXIÞ#-_ ;a"﷚<$`Nf *D+?0*G_bgr+N»9;w8v"UypU2 wMDNQp f1^mdYWBdiZ{kЏVIyQNԼa݊PO.=9?3Ktja+di'x ܨ[6a5}$z$5%b rŒߦ&:u$<啮<lz)]!!E*}>OeKq$ݩ8-:$-t 2c$Mir"lI>JnnA,}啗nIU<xfpMO\ԉJmOkPI_`,ϷڇތpSgf%9m%_~01:xN`) ]겈 \hqcf@[﫪U4g$&@MiqHUYrMgWOt28 6 IC]L(+#vVt@H'HKLӀ7IH\JZtl fúiV4R[}(|@,;xA|%bKZ(i,llҘ #LD/q|Ò[揤-pŰў!Q#(zdl\e jkiuiS2Khk:6Pg`GĆ?ǖn9ɷ?a)Aah5ZBr310u.6_eEpvC̷|S0F$yn Fa ` k^~YXvx买` 1aZ$7x'rp|U)|s:"V$<x{¾w ze* )(Z"EBNt50H+2Pᥧ?>ñs7QPh[IH'g>I %3vlŹM`KJ@>5Ж'Olc0u a})/߀c%}4Q-㹡<+󖋺| ?K<ӷD9 3֡^9]hvr.°/K?>x߾auyq!ꑌ4!>BFj#k7Bt#c/t+ ̡pu D?Kӱe٘z%tMPHR CА:vb$9U][tIXаW7I#]mwewXripvUt*LnBN_S@dѨ{":]=¬g`3Y㡫aڵCg~e>eqseu0S`)ޫTd |RZO>S).`jbЌ+Ί6 D,T*g=Y^ՖMVg ^CHގ;o(1pG0|͑2&C8Úﷃu&f6Љ_B+Suw|a8|kaIy#uօKm&[Fr[dkR|j.87I˱1[ۏ  c⦽v)jߚ59tĈ2Cq W BVS/d!'RTee׈a!,l֝eazh_[`-_#l$ޑCBz1r\gm98+ 7n |Q䋷ERm3p(1r6`C(C.y| %{$/ DG=k4]2FY`;+-_9艠s0]p:o6/./14ʃЀLR yt1r\%aK x|GArH\n܅a> q&D:S#$=xO":> 4ȳwR.[6n_g\3%M' P}(C"JPW.V47tȡpx%J qݟY>v%7`L7<#3Ma7 /?ɭuϘ᩷U!JpdǎϰSގ݂gB9*"4Ʉō!{VEtfDQsiG|? }undhnߨNAnfBws% i:ֽĈ/DuNUE] QMQdqZ3佃GT#Y\SR)9fDY$>\-#;P\4PA~7sYB9`W$aitG\[ 5Ƕ$7'2TN J 1dg4oӤCe?_ ՇE8ǎM4^D 3a$ڑG~5>i DME$y]Û6 qc; \4$VOCh~k5u%1%M;P<ɤqv`Kp/kK̇8ߒK"btϐesާsd4bcDdѳp:8"9]?© c WC=XиJݰ@I%L☈*zrR&#*1rN k*pl wn g|STza~1Q5Qi)r,5{6tT q1eiE \Oh(~dofN7pO7gQ|TI%8eǘNN¥gQ?NP(YGIY]'m\ Z0!^ݘ qB9*}{&9ZJsIs%*+"['-m0(I]ᐔfB\ C'д0\ =s?:@Yr:;6|>T -SwA9jSZ]%X~ .R=a`Ʒ Ilero/}ɔ7XrIX\9M8q\{V#jVpv6/mo)'(1ғJ?p~`/cG Aݵ NP-R-n(sbf'`'}bVf2Z( 7wYFmnFFd 9qt&ȗ{= _:lpn`mߋ2bl1 s#\UC5V\Y-!.Ft&Tvl"1NYΏ4@`^mtT΍ QH1"e,r7}%i.dcZuܢK$! _ c[n%8̃9(UA+P76` xY. w畅۷$湗);LrcvMyHtҩ\+z0-"ڞ5yp +8k9aEq 4.Xf3-t tn\;:x=Fr Vj2ZA:h⦨Q/ƶ\e ;8SQhúD8<11^GSc8jV:W$yY}T}O"*4ހCRrUBQM~i΂l153EgAüHN1q%Ua;/=Rذq]/UZ;==+ƛ0}G.2ٷT]xz"u[-?X}[;A"[mЧd87J9`?"Go=|p2}1DneM.񑇐%$=DI^$4e`uܟ-wpcԎ6 r&34v\KT5]39m\ Ĝ=۞}N֡#umxmS*jς`Ftyj'AJY s#3Ңo0g/Z0gSW~cѺS0EQQdBe$,8:l>[LɸAT&S>%Ee8SЉ{ ;&6$R+v,R =5 Y:-55Bߴa X&LUKSg_Z~V$qZz*D .fPφ^^{+ L ]nkAE)gZ]heT ǢQe.jA|Q%(wDvfe;5?oYa?#{DW4㑙?goc'Ǵ=xq6oDDqYyz; "4Y$L1 Ǩ (- 2R9.7d7k7i#Y жD8F!gυudE{Nb:#?:q3SahdhѪy`sBFޗZ# ;O޽"k):Hy1oFxcifO0.8|K`z@!/L8&}>(U5ϲ+$Ns1]UH(^ $^GHg\HqFXsqß}E I #'1Q^83>V_EbnW[زy}$ĕ!z8/:M"*Bϊu E!-X 8 EŎH2K-W ]f\0H,^XpZx.'iw|g߳ ÉAZiHE'4N{ /[F-E$꤈R:13i,ʼn%佉EX&fWy(i}6ṀVtpN^w`;gZR7p ɋg$6,QgQ8< K SX y2 X:GS_'aD2w{5sg6__y 755w'ї_C8;yTȭPFVCq7g*9HH;#Lp|"ovKtZb4iMq9o>5DlFF6~̓FD(ZAe)і DDMv{V (B)qⶐ/=v3q'S'O0{HܲΒjYci 8%}Kv+qD1yZ٤/v߲aFv%Q7£.<#)1""NU覙*DdžMPв}= ]]-Ahi~OHΫ rK~As~l"TTU*sMNոx rVcPD5\TPw4PgaC^#Sf|$h:{DX8ttEϔ#8adT8ydG0l\’a"zjkw^زi)\ pۢuwmϻzb]U8?SGGU;}"E I )5z\h!`CI#GOG'8xE2D૬Bap%j8ӱܴzk[ܳ/ZzPعnV wn) Rv>7oƓn߼ 33ßces3o:^՜?h -pʳ^3&ҢkPMI2̷b$#= `ۺI) ICwLtrtS @N|7P.1xcϋY!d}їWR ?Dp˖6H9HMN4>҄AfXe ľw^"MCMomԻO5Gx(naBFyQX`e鹎Ѫlg7a=1|ѻ1=l KLr s)4AU jL%_;*2a~Ug*<")#<=Wѫh@1_'ȷ#lCӌu|ATǎK15p&~limˆΈ4JM ;*ׇ.%BdƱf3SCD F l{4p8*+`/}9XQJٵk`MUy.DS$~9gBCJa 1*T:#Tl ,Hꃤi IJ j3-\8u.|ӟ9{rLCegAtCH/Z(br/#<eNL JA$A7.]J-ߴOAesS8' n)*HO&et,OG4؞̰+ɿ~1F;v/Qﵯdw=aT^{˸LuT366.j`Ju "D_> YfJat!W)B'2}Nyy,^=6Q#SfOCnU'DCYID[_HahUPA:f„}9vj Q< _k׀8v)q^g -3-[9LUTKG`և{J:RFSpܐC5hWJaN;y&(d E8OTPNIĢ,(պm]J+oZ˝RxR5^q}ss!cA"Q'杨rՍogg222__-}ͷ [%B2[.V@@* {TbH#c:B@T!1EjUQ5Z.$ZnfJԌ c#s{88qA}Le dXdmw#'N'0Tha1(Sh!w:) 1TpURY|Yh}/)r*؁ϲ$\IMpFó/Z`enFS̻&5QNp(v5CIO[eK!k<.$NYe Q+ taN~>4 LjF~ӃAҜr,I H:V/"8Y>)+B44KyQº!R|}@yMo֖.8YPK >'hʳ&W)JzjkTTRAnwуXdEXtں|;{yMuXgI}%,Q ɦ1tNzӿؽ'Dz opOfq?ҷ+[Ν (-bc"zYOP4zT%a=Ƽўb6Qb7!eCdA7u# }cDُMimky5GIV f3!Qqג#w+ۻ,4+^ӘfVBޒՍPŵTyO}[}]M:%_NN~ )pLN1Nާ1{>F /CjFkwI 'εG΁FcF8 '9Y38O4u킺H~t@KKklb$,z^]e f@+ȡE78A~ZZ7ʷRĵIq>`R=#RbDe!8V{p"WSa%RPj/S5?^{CظnU)A1C K bh\DFRi?P1uYgs<|OEm}o瑂A5 J#|URGQhuZ_sнOjs,hX֭_v(~3n̥GHL@ze7nXŃ @8]|V(ݶ; /#t: 5ߛ|w"9tY},EZy߫(>~ޫ/m򯲦܎;WN|6g/?eWҒA+DBj}l+;5 G1ğMmL4`hT☐h6!YnivwKdAQ, ޖX|1YwfP9ܭQ |ДhEirNa0DH$FjFJ 9 Aȭ\4PPuAj-\Ɓ!Y;D^'Xl/0scU*"!XxL@$@+(#MI'\2sȇ@#xC;w dH!s9)5!A+N#ޑӡ#U|ʐK{uS-I̷;VE<8[igE1 5Nd1F5ԇHo{46Ѵ{o5p3`vYY̯(@ckt4FԦ 1jЭ)#FjAKQ2(:TV`!yT,sh9L~H+J!uu))Ʃ TI;hjTbzz8%8+)'!D \͂nxYSawLq>:qxy4r\C\E$A ,}QgR.C΋ϾQ95P1ntȜ< =RT >y6tP )PK_Ai|Y]v0OyTl|g>/8yO8}K`7Et5_x^s߬] wf{{| ߴmv>m6Ю+žG0&E#-߳QQ'@?2j/6h,MΜrd2 >ʦU66s t&f^\,B8eXߣ1 (BUlB Cc0 76=Pꅁ.e-74G?ZsW2]r"fB,0I:Ŭb7!Z%rȖaʕ1b7}ۀ C3 ΀-iggY3"0er6m'9q.<=8S8YC ΌM{jP: bQΘaĆD6axp-apEgkH?NB =&qx#!w,չ"e~XE.Mt󅻂/dq*Sl~ Zx!Ɓϙsq"O?̯< !^2@7%34.5UVB&nq>Ϩȉ| gx:5淚/gnC{铔EszZz)h ñB 9힑p~a;v|q3PepS>ZvyO'!pYZbU hO a^wrMNѹ{3T:v:0,\Bk†5G.G۾#?ah)E|DRёhq湅+_F{E;6+($Otp <hrq2wfĪ!iI@$Ȁ:W `^#b p g $ݴ ܳ=lݴR%5j? cl{gS4VOt I]%RhHL1N%H!dY|[w5\D#SI Gc͸}&y\X3{ga tR>TF2i9HqB/{p\&v%dsoHfex|h?9>M֨=ݻe9H_7/o^}{Fʜe^6IzNh!/4SCKX.fא@pxi&݈b c\2edYct.D2t-Ҁ9 k5hF,#7zrB 3h |H#i5%YJedFs,LG䢛趈m 6P× %r5b- ǎ6; ~fobP<2 |4u [Dd8؈B5&2UD1&_gscS솅,y&,,W %[[f7DSŰ 5gw6|VMD"4R r;yhzõ_^xyOX!TW~9 FiUXR7s.C,e64^0Cűm[#J҉cҡPzלFVya GWDƱT 0բCe+WdOy%)!!( l2=ry< y7u7*|"(FEaJ>y5ë(3t{@j}ڨ_bI>ևA*#NiQKAyb{,R 989=P8v},~.t|JZq׆U+Q144>]))_dXLh*4ا}YIKpt'?᧬Il*NN5ʀ~_-&-9%2 .)d_Ԗ._=%JlZetn%+bPF|^A!MMoIl5CD]UYKƯ'jv. =I`QHɁ89|c,3(%\  >9D'!U7<՘XkbEQD,&ۼΎ$B \!^&N0"1l Z'P +_ҙCԂX0r.ΒW;~1Pdpqr·I%t,#o]Hd5 HhG8>UJel># U!k2qݙ!*pᘜcB9v␀ D{&rY : ly|sCj򥜛gpr"{߫i+ \EtZ}~bH#2? $[4Cg O)5M)c@?^c1io b$Yurt-_U Ǧ?*IgNj N1LwN$6d&)| ߔ(v69=7Ϟ̰C#׼8?%-ͳ-/M ^, (2-m]16]nHTy b9iec(vE tD,](,(<ӟKLg}6 ; xNq^O*9tdbƒ4|' ff83+? L1wqWy.kKI?v<"Atg!Ukͩb@4g鲩{EU,,-l|n yl:+W- Qpӟ~vraAq\7 :3m,!!:aT-3ss1j;J4;n.^XaV+7ZnB{=SFnlklbN5u1<mqy/.)mUBג(\Dy=}BXe-b0a?VD>cόD%|"|s6SS[ px@W:HM>/,1 ( atQly:.8v+uk㜔tvIKJQAhk@wPX&YJiii {6.մmNgA'VNМRNNF#aqM, `.zp\*L|ܮN\SQ%YHŸ?4Zg9z Lk3fq{TWVF{)ɧ1M~Y Ju\њ!"99,-RuJI7ZZVo`wsf$ [x>n˒e&$]Qϴ[g(1oP}I{.WSO^W0K 6 ʑ4jnFj1ξeYx:B-^g7soW+r@ ["9A3/uF^)ݤ5lncz9tjSDˍhCL!!ji 7_ʘCJ{nFlU,Ff&^WFκXIXxz#3f<{=Ill"*Q75 W7 nO|aiH^/q;q?C.h9v"k#t3ޢ"ȣ%aÊrD8O0;:ȩC/"P6H}4k*$PCH5f޵\nKEܳ f||d:~9BA}tt& ]Πϓͧ\Td񓼯㿄kc5)4T. QJduA^, ncbkя<5'Ld,;x$,^P}bK\SUk ΀ɚY<ˮhI>G㣊w:>_H|3QYPH ^tpVQYMi.FJLcQy)W1{"OMU"y(c,/Fs~/gdoo܀   O=hB{y]{̙+AoD# &VɲDJ-2c{c'yXr\Rr؉v"%bj,@D6^1}}}؎+ |gp朿{o}]8>įo/팹=Hz ^>?}]xݡn"a",fj3G/B-5}:aW#Mt4zM 8+'<͂V_ҫ,~7mjXH"FUR鋁k5'dMi/%M]ʹ />q&7,¦\;v" r0oQqO}c;B~N$|gOXK8gdc'`5 (}9}=/rFavF"0Gu)Km}% ` shRU @*w%au 1G0i  r)T I{0/_CqlN]6 5:z"lrqI-*tY:¥eȶtdDadG>jW"WQH'y8U[ѬlTX@Rx/(K 0D6x}V>8cOIx(2k4ӐHro#<Rwӡcesdx@J:U/H7BDuH9.i@9,.V)o᫔ʏ\b,#iTM U!ncw:c[;hM/ xRcc]QT'tؤWwx30-cy>ʱfѧd?r,΂.OQX}Br@tFϾ Ys3Mr5jbąmqs@ dU\͋3Ғ Ȼ8zudG)i4T*UT368D~:~@kh%<&8k% KkNݑ9U>y:_:+FY_]b0~)MC#7,r@=׬[6_y:/:IqLܷ=㽇K"aPt,9BDe殹+j  ht Aj+(|4*$^=q8 UDQP=8$ܼ)^G8Z L8(j9:?c;W$.D_gC].x{{ [ײOIi>$&!6Յ1ȡm-J<Vk萦MY(yZ| eD/d 1K8(JNE5EGE'1ҽ:FR %.YDHP>"D.nMYϡo"T76#{cݩԓ9. ]I3}Jx=@[{ h؉…w̿m>K;9HU1Ʈ#{awHqyohSO:CWqE5 r)x+7Gd,tY'-iV1!hG=L. N ,& '``h02ܹmD:?TlUBs+<Q>Q aYLZi#*`Bu^uX85:( XwVl^9jH8&BN}nǴ=ƾ8}Uאj@Xi|4Kي dYN_O{Xѡ_M Yu} P c xX|Q PBUdS?ur)i NYhQ(z&E. 6"ۺw{2$yzqC#dž{Lk8U[yXKLq 8v)M}%æν"1PS5=qT9z4,4-Bg  Q})rӢaOS+#^gM`fiª+=8e`x8aH_x![RdaXI.~FH (#Yܼ*usÎj6t HTcc\В|o&ǎ>w܍+sɜy K̫[+# *~0;c}_5l߶y}s-嘟`Uo7{I̞ϦnҢwzx{;>wBSve߼(3tC|@쇦/3.IEl)_0 6M5E%yC2皃S0Nnr =KP9kV(_`osDFY@_oa6c+H[i%ga7tmiUQ-vS%cs`Khb%a\u 42a8*IX3W|Hn(ehG 5> M\p4I= Ju$)(z: SV bWϥ0Hv[u+ <~P dGf9 ֍] Q9@U:<)Ϋ8^eTKIݾ׎F3DE䵛!z^%@gHUFyn͜дfEdghp*9{\kL9SI=F6iY2 [j9JDLO@j߁(iDi):c}N2+%Q9UTd Ed˒>:o^uX7,B+Ñq,,%)!kx>+Ixu< 8.XN*j%}}<"M)ĪɁ>)Zo/U:Et1RHBtSKt_Ͻ+jW |oHl3PA?LgN[ckH~0#q罙GK$9NbG~Ę^UA9s͙M\r/vņs~k?w5e?Y!:; O&kezZ+2>9)|4r{Yt*+"'œ"ۺyPL4 {aoDIAnzQ LmrԶp-Ozv1 Ֆ FMT }tј [,3 U,"U\P5.jcd(``p"DsoR]HX%` `jcXsaE0 `\;Zo((yDإ䜏hμu:@25&X-].PBZV7S4;3 5uѠn*/ 26\ QR<(D2q``8^硃nVaՊX`PC*M8DD茭ʴl@5l(8)чHk,Ѡ#w[ж]晷 (FZ@d sAoFZIjsUT^h٫Z8'vskH(-0\N:/$[ZE8a)|3U.pZۺ,Gk>(fUKA1 dGR z}UETf~2RPb%ֹ9I)K)u(LYQs/ _׾f(8.tڕJM 6}@oϏ T2/F@ i¸}O?O02gAO!sĵZ bL~!gc7z2_ن۷'Y~qre/P #2:ZiJ>ҶHcu`qJ` aڹK2GPF6D]2F=֭!2 VUζ_9[6n`QllZl&.,N/֖>o e-6A`;|5!}A7(;z^HSmpEQEiG95J p( ˶/F~=ea%1͞6eK X5l%`m }c@}='kīBH p!a+Mw«/ [oԄȭkpGBrV Y ^^F$΁l9`}焘I(\W_G_#j:ԩ8.9%I:t*kjKk ro?;v|ux ΖzPkK%\-ׯ 3K)mS/4=S#ym' 9kh&.XHA:T}_|en\X*Y+/9·{-d8y(w\%O$7iZ]"ƲhF6'?cujKbv?S7Ul\1鉬\e}Q t`+ c$Ѳm5rujh4T,]ZImHJm/ ^Gaa5Dxr5Tc "$BԐH.`D pѲ=ˉxUT^cE$w%[ Yc"*P{><tDʊHǀoBfqu8Aۥ{bD[HnjS+MIk͋~(léPd1ƅ/;>}qȺ/B"(&L_>H e,B!й#Yпrf vۈ}:㻯R lcCUF17exn\:߱8JLE%1H'5Y̭c{Ac;UuE{!2.^-\ojn wFNw"1^=p0,]ZPqL8'' E2xvtv;7`'XS?Y6N7:ь<kS:\"%yF}H'5։FTdN<(Ml :$X2S,/cI2RA;76nïرDx ]-pΜeĒTQ+nXZ'2SNߌ!bwA;yt뿒!,̄oo]O|HcmNC(2bt-]î`VEL*.l}iX9 $tCr>oY˽6nX#S;r]cC}hE]M  [ł/EKgbc,SsRe>c17>f3Yckq(% } גQp5stt0hTzhE0JRbxdHM.ETXfY'nktLa9 th2:6SsяN)t͝t,5L8,Un Y%fAXj:} S[Rs$srpdKujollȇB75>S">|6UO ,Cttd咈L$ }Ǚuȫy)İOrU4,"Vx:%p'l-c'B.Uٹٗ7mܰW׾OW?0:^LZ ShW]#0wMo2yzo;۶MwuÞΆGu3*Ú5cBj773z>D$B<|9~.Fuօ߼mk" _bYdKjGx߁cqٟ{'eQian$[5-&Mp! b1 0P%.mDh?C1@[SshpWB6D( ;Û~o7z#^)BD;+ АJFuF14jw%eDmeqMѡ:u4S,@}s/m4Y qx%[&X)b{pZ"IЕ116o $ 0SRZĔ= |nHDĝJk-p!M@SD#fp표؃Pjm];͢8> s 00:r'+l|d\d' uL,{g3,tlEy#B; Cu4S{FtwLuFD1Dv}5UIXvUk!&^omAR9x*qQ2J!H_@;%p._AA =)mg9qP+ :3ʊj9ut2>r5<sdwel"-5gH?V&P`:˨׮ G໸cXݩ) # Qja 5*0s1wM5Q΂{Lśv<\c+_/?{#ʖf"qˈ]=W[o }Xs.¿q|ײ9*#odlh+n*?#]*ٚq5dQ)"'O=S.:B>y6jHP'wB$`| "^O7BޗpVM4.4ѮN 1B֬Z^aKBt}>FYf].'^+QF\TGO<Oci XDsr^=QpG2YKG7>8jR=o #a͍7Z14rl;wQ4S87_G*SOP\*۠k XJ{/f3Kq$M'e:jLXjjE(U+3j o~)y-\96ܽpv 'wIFb $JxmGf/뗧t>˼߭Q_H~lԗ?\uf򃡭(bxJF=,$쒱/$bp, BˆōM,+ݸ!ou< hx(q>+F:?O6|+B<9LUѮb~pR9-ɠ+kɔ`?.^ m5B80 "Mِ*U!H_2`z#qh/Lt禁(ZiTuL{BٲNau831Th ֌FE\j09Dc,{>;0cq 8`i" $v`./(FTb[CcF0a?hy),ҢUCAG.sO{g1ND0cgk_tg|A5RX\Y|0dz>tw޶)|߃wR X ܊ōU0$8۱t2S$SU&PBDïmWL&~Χd@M^0?ߵŜW_֯πԎ&b'&ON7!7=COv#al.BaC& ~yȪf.]󟲓_ٻVP f}):fa]?a6ƾxu]dva /zx-Zg>=#=] =;Px"{ҧ#]<}'Sa0}|8ZX`4, / B!4I)͜%eKCh|mh4V~^B]}{Hq ), SpZb #/Dg*"Ea/|5CgƟc-1-1e{PR|]aEVڼE8[#;5 pQ1~T& Rt"-,(T)ggk+}+%ٴC9pvk9s&Y묌Q2YD~Ҩ9sIrp34֦[trp2<bļUAWrDjmO P+OY'~:*CK{WزE{/3%)޲G4Q {(4?[^Z8AdɨrA+"fE0ϐcoJL`m7EFcJ@HRsHk I:#p=S" u |7ߔSu֧/侥{p. (8O&S :E~S9sԿKlbxff~?mP8EX< H%*wӈ jԅ\]3Y@hp#LâmnT7 >lut=ўľq2$zmU[daIc}t<#uwm, s&fڨ 38 sa`s.~k_8ݡg0r#A|0gpOE [[Xݳp4űoQc* : aR~?0v("Igܿ.?y#}(1Du l(J4τ]80˾q9-!N%vi3~FJBfBxc@t@E}r6+“Od|h ;] I(7- =0Ԇs5͓۷qaUy^z$ґcp"߱GtET+ݜxظim^itUQ޻oDa1 !o{ ܔr.>wqtI{T0>c:F_;$8;vq) ޒFU*)1FjJ ʙ36B1vҐUPAH1/mna+tZEt6qMIUWTrKI8tnUVu xj+o+/XT.Dmgfܬybvm{ʣSYsOxz:fK$D }xoa$(b1'gi#lcd"O&+>ՖS#IjgpmSS k+yu*d)`C¡8N2ʖfzi7sT"1H e d;ZB$XMЋD?)1s%+'Y]TB*Y_K0΀9Zd̟*&]X:*p ,( /<<|#U`Y>=`a w4b_|2q64LJQq}CGcD:0pF7-is)$ H4 F^1G?y=)~ibn'8%[0hӆNrlV`f1:Meyͦ\2ɝW([pT팙:\#7vȅzl+#Qv `[wd@IDAT+HpqXfuս/3C\[kȇo/ H3̌879<s~Iy-IN"ɜb$[Í[6E|Nq:c/V4"d3&-΄ʪWj Wm߾8o ^r.+T xAKe*s7׮‡0ם_6  RN[9ym3Dvbo)F%L{;,m*(._ K>CD칎$Y7#ўO+޹/.f)0IAci۲4#AEI۶m!n[0^{aF CIef=?gEDU,]z6`"JP2>oDE$|OƪE#-u'u0SBo_ Gȉ(F! 7m[ivx \:{r`#؉0 W}8j w+0\5]SB:Ԩ*AIi S #a1o~JVl?k @.1E+Ka>b]ШsB9/%39^&4hqo"ڳ߷#K]wt 0t(jnR"@@Xp}mCcy*<CS_aZ}\$rJ`8IbOP$$nٸ.J;<%NU|uLX[@I{иxqF_^&˧]G8Bjñ`WOi7]sMO39/̧Ȕ lJu.; F8<{8H,ѯIu0Y$KYX4<"?NZˮ`6zmU:]*Cư"֘Y$|sO l?؎l{qzޘx8~Bs-a*9 g¼Z'R@5C{Nئ4"9@3Vx+y- ?) t/R*; kDL˗cSxHC!HǦDcՏ8vX|y !-Pji9iC ՠ&텣%JL`l>`cC=Aݰ1~" ([hɁ3Kf.+gε(\9:Oo^@'خ/H]o< WJ!-D% :)^Vj^dӆ\|!e\?II)/)].|CDHl c~ 2a{GT |E D2|oKp: a"6ݑ`E e%(v22֫fH$r]۷o4pemk#~~tDNχ/KdzSOe'Rd^sQ{59'_L~Ԟ;K{mcW2.vE.Vro\(I 5s=YU@cdec ef1 j4Qj卑}qr" / <V/n G;CSa\MTӺ+^ǹ 6{ jlk}m#] E)=QS%Fܲ6)~A8dotM~Q Yx3c2A<~'?Zk/b`kXj`FYtAB\Tk$^4)}~ Иz|4$^?|h " ,]= 3xWfC/zQpJ#h}YO8m$ G@c4a]$ĚP}ђY75qMKqS%Q`/׭]=C]΅ It8(SqzLlF䵛$ۺmlٱ;ݦaڧˀM-d©v9O!]!E"Iy.0 P Ob?Kl:TXEȗ,:Z0ON79$mon$Β&x`8,5l:)zX&oF1MK$y\z;;e~RLĸ8X.> zܜdmxq6Ő ica{">"s{$|?qۢxj$4eg! ^5UDMხY 'vz0r357̐ǷQVç Ah0A7ֹS/oQ=9@mAX aFC}.f OQشq-p9DqL{7F[Ӓzޫ ˗Q>gD7[$+g)g9NΌiXҋ'-_{乾Gc<-V.bɢs\[ %44gz0Ma~Gw 3S̟s|s3=kX>heETUgXvI3P,b@\(K%gZ(W]>yW/-j˝YX#{_\v (7>:ƅUFr U'F ҷ#4BuQȅcӒGC 5}5"Wɤ;o: DS\.2ͯG#" P]A.w`ظ&pȑh'Hp'CgO}

zo8W_Bi矋c]M'44 krt(V\8Φ4֢yDJ4Ձ<Ej7EQ!#g;(}\*;8EQes& 3'p v̊/#Q/i)8+z噐 T'tv*0yo~e/Ol)]خ78k/ {3J[>zKN`ˍu.u\%:r!p3E@| WѕƠR!-C+Q~ϻ U:Bg4!b#0 20v}aPf0:f.6։ pVpzD4Ett5 G ?pp7FFJ+иء0IE}#"B9 9`ҮW? $ ᩮhy} Yx ˗#O\Ӡ +jSAБ c^sF{h)S澝"s2ac>4k8>۶mY޼k 4Gfy7%ьpk$m`D\TSB.1|DZN2p21ZFBJ۠G]˚I?I`zɽoTqczGGe#l&m'RٛrF ؤBd-}mI#tͲBY__a} f)<$[3\U8-= R"-3ttv6::ِ,\E(H\2qQPHDCJ>2P~m,,SbwGc PG%yZ-̗ (}UW\zKWi¹Sט7n{?KwM˝/{shNɂi:̅ѓ‘ϦRJq>ze4+ul8:5N$ziAM̹LRvځuWۿ SqkF>3N'© pyOr%lX{?~=*b L̩ σc˵쭎+ _QŬ< !PD qqŏƈhv%YQ͇ŮѦm-!#Jo:')\CE~?n =]wրoj_s OQ?A4YSŜj -੧1~C6{zSF5kH"Mt6Y%(k 7l85(ݽڑp9?$kTlTNuc'NVA6Xag5pB֯_^xd3gǐ;D7շ%uKS>hTRQhGGYZhWsTH{$lXo}VRQkeiCf68:,PѼ h3E E|3V>'qb:x4cK~ nXvǦA1O15:POchhEL_å /hWWEr%{}wD)jyZv&_cm!,ŘQq3r]'\_6B.'AGEΟRiqã#Uߒ8QzzEXI y)y덡(x&7:}'lfU][ٮ!oe -j 8]3H1띩O*R58WVX?XwqEnrR9YJ=4|d qbbd%K9^N:]scvp{ouږٟ!#+*#1px[V(KXm9k!7*Bc}tzoT3N^[?yfDI)@CkLq:5`r0BvJ1 ~O0&7[jI:7|">@" k]sL @ƢA"j{4sʁ!jI4F}}D5Dш`MTTFc]c(0,υDL7{cL^oQ{}aj_g;/p4K !r scDm+'x)n #ls5˖Fا5Ajͼ_ /ݲvq|5x 1o.Ja= ~}]mt2ܗ0s^aaHoS1 !QDK+8 qIOEwn™= ^ ?]{oDZBF 12?2)pˆUzH^D$wQ QGi!)0KY1[ PGm־"E\7qD[eŕ0t7_Oʘ;JkW n-pgIpY$2 OW?KW?Z@ʓګ `llq+OO!޻c;>uw֮]fXs@ХtJ4FVМk+h\{;({ר= Q88WGMr]p":r>F!Y@s<焎$jWI6*B;귂?}USATx:J=f?NR6$bCLZ:[NT`QRbI$" WN9oaW]8$/Kw>aNV^/wdƠ(]U) 3w=1b:856dv!#h$ދf|w WJFb,){ :QRǁk+&jtY$_Y,/Z>Da1q:qEӲBɍ9 } #YZsK6N*p ch#x ƊJ~B/?)w*9)Ƹ&748JC5 gdg?v=k$DG" Z6^3XI\uq*"gυ>L{2No0?;C8y-(FV|υp ƹ3X` L9]8:RPDq1Ϙ'gOm%7u,:~ |%˙D:,c%"Bvt&K/E7x0$?#//!'ȩF?Os61ʼ" ):r\Ne:9E'tDW/쬿޶ bG DP#КL*D|@k6 X`Qnjԯ}dN_dC.".Z!v.BH7}MU1}Dz-,c+BV0 K;B@Q$RBAmaq9W uά39GԩcnXmn|GF0D#5UDw.l\B4]h3ɭJs/Y{kI$Cq?s%օ-7m #tatn K6La`ԪF()bZO:G{M,jtzUsطgظiEXuSGHSH\@rW?аl)BU("̳*{hFkc^o?;?8ڋ`LIF>V- ?pFe@y0XRa><;(al:Yi R2<~&\Ĕp4~m0k y*uzvpmE'A )q/ʳ`#`s7<v1$-QZ>ϙy&q0'r0* ( (J S)*Í#OߗL,|6sϷ|f53g3Gz?dP]('h82 A_u pSe޴ #^wDXJ #5.hFXLs \%9ܼPeml C@Z &6.Jz5%y.t4^k\N΀ʨapad FȐ  auB#Fv#Bݱ){;cPDd"OY9FNA"F󓔶besaP$"u׊u^ٳ7":A rrg?9EYnHn%QUO)ww_Qr Jwe"NsvÛ9U#(㽌hS]YnY'ꖵ?GcQ0OxU~JwD1`\(=ms0}ֻ%zv}y|7)tk2s6*>vD1'Q,qKə;ƥ!#Tdq4*貇ȜNXUMqDX њ 7ܰ>/Y^A9sz)ro%Еg"j-uCy5H8d7ҢzwI#?pi\(0Z(`ׇʃpD8=M~hh@jeJPCf @2EB)d"@y|ǮHfN4w/ 000#l8T}%}c7D#Z$2/ft+j4]PoswvPu@5)$.nSQ8@4,n^WRNO==~%4`4ŐzJګ i/gm}!qCىO̧$Q6>7kjT54:*r؊0ʙz2sܼR[ZQk%A/.ydu֡wQ."jV?kG%@ՅUųncc`=gݹ9 q>[ʻmasmI8o01q<nzupēU(]Cn z5 /D&57i|΃P!l0x4xڞѠRp|Чau t3svKCGO5kb`7/niKXu#uh&_s^U36ũY~ 07V77(94-W`(+iTĜAj<)εu!\~cvrtIѷc΁hDr4 B!esQgH,LX=ݼajȘKW,ct?T) 0U*̏LŸ|+S|-ʱ13jtP Q zԸt(/CBK$G`c6!} +a ڕˢL,Wydkǚt>a6yRD %3a<_D\VŪI-/n,9\Q.hkg)2X>WsQyvQH+( 9DJf Ec)VΥr'"li=ψ({ʦPB=Wg} ǏPF9LxYFFX &·%8ƆX:(žEa׋{/o>fuuL7PZӞcaD)ecn,ͯ=jA}ȩ+(z8ECQJĒk`TZ<ė thܷ*i}#ok ey- I2]!\ui$ZeH8tsA/|DyܿZZ:gG_6⠍';}<,y埏kI&$L K+-\3d1ρsԁ:9^KwJӫ:=W9WuιRZ(` =z5ی8\xg3wp"LBKԱ+_yίx [ Q_8~77NddmxNZ0& 3JO>٘([Hunl:6>VJpb7B6P=YilB製~u9M%17r ekkF]hU8_vD.\Pqo9rEa aY]Wuaym^`jKI)2O3/\P c;e֬Y*DU8L e NDƫa~K}伣Sl#U!-bp^kʸS-AAY04=,rIH_ c춗b3|$E}9bAIvBDc*h ֭Q < E4f'Uy6̳G#f_W3,j g!ڱ:z[c : 1n(\p/Ԓ.AJwrapӞÉP[J({zx RjlW$ѮѴFR*scmψTT~ XOQRR2wc(Bx]j90]j@#)E@;`|6$DNU0.t0۰t:FFs>Ec_yϯXPUni1 Au7ZAdj rcx^=iHE/#ok ]v1J*a@ rqp +++QҫFPCJAݤ"GD@#zvA]FI]eQrSm|Ft(pݢ6 ,Q)I! :4`DzDNl9}TV`jD?-m0NT/:fo獡s% <ǎ *rB(/}nߺ3|OukV)Wypy%]h 7[ptOg%\OkЇyys,swVmo'F }V,* Œst|lD8jw,Yt*}99|zT2\8W6֨~p"apC0%nY\GJ[%^Jlcaʫ0=hC:[aE@١GZgC5l"Wr[,D%JɺPgUğݭDF(0GCa袷{. Pee#[®qFaHxa*$M *W&=C0 b<5z6l\s- yc 0_)NتpŸiE<4҉%i@5c-MwuqT\3JYrX%͟l+ ! 3<8Eɀ@,.6g02.,eK|y{T \9=q1!4J:&Vxe/ч<$Yј遐6ogG'(Dn6,GLT?" }o." Lp| $S]yOF* ~"S* TL41̛| 6J<4S)8׮ :H {1J"@1$}a8;X R~H&c:ZΓ |O0d1o#ݗ9,9>K#[Qt03ܲdV9Ascn&imM?׽fΟU$W~!|$$ O~$ .7y įj"q ri,p %Qה nfJ,x=z]9}|1S*VLZmzQ|"$ A:e..l=A2;H :mҁ#2SWW{O<%m@T˺c[BL d"Fv,,#w51%jTf\mMm-%>H}yPaϧ\06ms3s4;fFrK;ˡb5^[)Ólw{a șbGlWyxtYt){z%݀'>q?6Ԅz(-'w4*~Vx`ۯ1ml{XGF8X6WIexiѸ54nwX>Ɍ:5J+"GC>hriQ'TضX'H'T$&jcl+; IV a7ap1x;ގbJ@i~^*.i45i Tf٥;ȉ9?珯9:ehpٛFqEFu"3!7@"h'ȃǖ#I@yW Qpk[gD"VSusź#$1R8i5p3Y>Ml@ؗ>OaKK]%34 A0kBdEfr& AlғxkVDkfe-mzZ>gvr8OyDuL>}-}U?|j/d/#,דO5L RoﶰmCpt]QK ]4, v֪sA-y6 tM ?:r!90THTYaJr.+,kn֭k0sI9P90k7iJ*+osw磃Rmn%ibNNmjȋ:Xcc}= ;GЈ\\h4#S`#Tޗ菒 G@D*kj¥x=Nv0֯ÐR ,W C1#U]Zӌ*J[V28` mU94:~hDȖ[ bS@4jƙ _sg4䡸w ard8<ŋ-6 0U+&p.Q P]wD"QҜz vJW=S_nNJIFUAeF#yHs`'?_, t}X΁u_ԣߒp8tD$xL*`1t2O|rT_7b~8QmL]p7'yh|b>mw ց?#8t92HL2t^ C=7>*3(vچ2'Âjvm.t*]=?gEtQftVX0YApݽ}{8>A1(Pzt F7 0a8.D@.\9; b&\H osGC Zt"8qM~7ƺV{7%U5u4*(=!," KVX ҺPGwNJ0BkZ`:]8vhdkXohW2P,>ljAI$\ ^5T^.\KbTJRqxF%(&0s0z9>z]~ Bb))ڕuđ&0'F7$!硴a,sϜH`sl69 thFT5Ea~ Fi|s",($Bc(^ap*[c%dĔ'\:Ra9׽Sd,x2u"Yx~":GE9b gEpL 2p9/&?--T$cRi=#|IsMےpMCasL=e&]-I& z֜8J5 \/Lht<{$qǣC7μoaCcHF?grj4;na[ X Yg``ˍ?t5? w[b j֔ }O@pQQ]-D} Gfԥ0BX(SA>XxP!'ܲ,#UYԅ-[6~Q,ChhpJ1z5k-`и ܅9r-->kSan [DO@6nt*,_H$%3ϝof-K ip4B;}F .55֢kD5h@:DJiReZ+b%DmbG#ȏv`K2 [hn w XX'l{R Gh4ӕOBXDyy# #@rHצIQ*" !ʘr ղ",繘 #>_GM=E2·XA_F 91mxظIBDjq8kA rY:RS@ҨRg2d{v8 8Ee̪[-=+yiBb;k`&x;kc#_N&Ο(t47~4=ֿL0 \)BMOaMA6Ck'D? }?ʻ.U}EZR +i@\&?~t,i3b:Jk`?ueeMKG60FgQ#jII"1ms,B X0RŜMjЊ Ϳ IHҫ/Put!d}]6FUrjn4l߹:`iH4}qpRKk,9!QE?Iy dByss#|S: L@:iH)(2 }k[IDpfhNO"gyHt`3YIJp2$s{ 2RXy{ctljo#9:I+J~'+Q)kޖk/0F-N4Ka6}sSiw^WոW|X80juL0"㯿Bov>Xiȳ Yʾ޾mQ|A4JI尀Y<d/y!jlY{ɰ lr~6߁g5J3?]In~(9K(͈?d'IYy 'gy c0P1ypB$$6p >8coܸ.ӈ=jdND{bl1QIՂPiq!8 Ou;)#Q0G8b`8-* [_CܱX89^&٩(1j|[I=ChgkELLX*Y}ށc8e#oQ2 h)}I9q6+blI|s8f86O[n艝;hɁOASUS8s6(:G4ɚ]9t93g.8W/ 86+S8)l5B^u4!s{,-@)đM1IHoRq'90r3z FrRWؘ`_^;O|PVHx<ɖE! bt &=;lݵ* Kۖ6nKJq B3۔@BF7?4)8x>sw~gUԆ<#Lx eQbF~`$QfB#b8E5šT\ IqReJO'|s ^&#]ǼU"]cndv~Hq1ŀ! 񍧞#W zTLoˏDsu*'Ȧȱ Uff#~'`rG[fDXel Hf7\r6A6eR8%kk6m ;qWz F R\ϑ7&12렜(?Z'^ϔDSy+_a?Aeqa P녢!T/@AtZ.&t"9 D-Q_qiF<(SGTNrmTz MtCLbEpRͮBJV~vi'6Gfl$B4:Dw`rr@tHܹ) sDt\|S/VFPy#瘊$ _AeiqsbD4ܳqi͝F5\x#wo;G|<%%D0*)ɬ7plN!>Z7<^=9ZbF [e9l!4{{ɈݿWiDdfRZlڛ`oٲ6Du "6H^QЁcቧ`7. @ U$͎Γ(?-aq#b"Rc˞|^1"yp dL`-~)03Rr6ZG@R%\lN!M-Ew 䂯u9MI"|r,*b]1+Q, |Iϣt'SQ yS%8'̅A4%{FVR Pbj9|HҐj$R֣߇2cQ#\ |ttt@uth3 ΁61g@űe?%à8Lxrc2AA@hz+pEO'ͮ_VCk\I:aܕ=_`y8{2jnk oW3*l'm&BA"EXӨV"Ag7ӎ^]$ZXå0shx5E00Y,^=DRF!h3lJ.vRUx)6)$l`ihQDGbpv{5/I+TjK\8]#r@ %BꍜC+d]_.Ϥ0Qɂlr:Xt'V6qUC%?ձ 9p FNx)i=!};U]/`t%Y1OnIw":SnR#+ѩs lQ+ওBi:=Mxq$\OGÏs'7j>hq$E/slwSVZR1B^:BB:pV>Tdsn3_'og-φڔXR çNpJFWa9噳-121>B8,&vdx( qyV\FFQKLbz_4%>ˣ#9ePMa'T,Q "y(9V:Y8fWȄVNLL׹pbeW RxMGWш9K_Jh'@)йq[n%T7E2/o[B^-}S] aRkH Tze33<œ?]+[YYB˅S™h@ m6qa^Pkj+tnЎS_{K‚OmQa+ʈdiγp^Z'?z׭ ^NouCC IğMn0N bn6c4Jy`| 8fł"HԨxQyq_i)I MOW4BFri]MS>R3Nh ح9ުJ1=vwp |-/Mx6RNHRFmٴ>t֝SIaB4@ay=ΆQccע,q?y"UUeo=w8smjNak#bt*[TH"DX-b;G}</s~(dyc)y䀅M xU=}='z Y8:@T-JhMu1ʒ^lѬHGo\yqq>0>81QsA)Щ|KЙ*"}AtNu:q˭ёi1eSdEǥ)pL_x}:qfX%#xpCIݶ=/J23a+ %໏һ/m s[^L "%AJ`=kF0ӚM|&ه~f/򅣡Ҙ].FdÔh]\Rb;6 Aɺ9)<dӥ#|H0>Y~nSmt3*X"*^ױBw qBcg@b$Y@7eՍo\B8 K۫1=?5I/ׂc'jAlfq:CgTNC(\}%,"-:08Igտ{c1 'w?pIԌ8'wL0v_ū|=7yE"̎1So5@;nsF sњr sdNq _/:R#hV B*D?<{"91&fA!9FFRPb&ΟFC>2wUE gc+ J*'wrJ[{?CI %b2!QbMM8#㔸Q8"pQ~P[ Xi\>+aibSy8B/?KKo^Ĕ@3[M#դ*O̵fU>6e /F#b.S8/_&kWnjm F "ErH[Zvb& ɴut#Ç-=gA5BHY fJ`s1]4 ͗"D ^IC-Vњee)A!zU#l] lJ Z/ '06!^8[: ގFm, 3VEٴ?|Op{ː/ AWjĵ"ٰ+2%} '4fDٲnޜoN jj=ϔFsPx\ ߕt0F 3pξ}7RFߩPGynE8߃lq5n8/6H0j4C}lްsL 2@@z>s="iM)Ĥ$hؽu@#ܱׄ?#6(c\Q4ҏŹOuFɘ"J= ҖӖz,mϳRB5T)|cALqӠA8x&Iy\ԁc.BpVG™_#O\x=9N2%ebbJ`g ғfOkeGѹ]_1 D@Gs2d7XKx5.ZH)Q( W<""?pl{[Ah-ҥmo;?0MeNqOgRg}Al`jpY4FyA*ܰv9F5aXr(,;ՀF5NzRz x! F{a+ ;nAZvg(?j+Y} KZ8bttR9j`u%i4/beiM:7ַQAj2T\SA.F.c89a 8 -s-D0ҬC"&gJ4aw5H1"]nq_7lӜ͇\E'5 8)Ix"#!I<ILojJ1$v!ݥaS^Px)3m^݊s gD Ƹ ?ss N\s& R56! 0i-''.aS Ni SyhWx0S:8}= LӸqM5rf0Wri'e o@˱_fUvi#` ,sc0Qn,2{C?!o3SLăYr^A\U+eAaPd3):Qm|{fxgWg|@Ŋe?.8]-COP[xN&;X6ibRcZYOM-=сۥh^˽æ^XFzC۽5zpF?^ )a*+l܂8VVA@(A-ܩƲ) lu.2P~_@_a +CeO^ xj:y]vES#RF%%zww\$0hG9K[ ԟŔw#Zp⸟l2:55)qa12RyZ#{. s 92=%K\ҞNN[^6:!#] "ЀCej@3Ts~14Dvxr&i*R{8=5vp2NXgH gp› \Þ-F ,=g9K iio s2O.t&iG8^{.ŭ_]7g9Qu'Ѷ-vc+ټ-¦A,KMCΰq9@QV5:xcF)@dI81$֒'6Z2y[ {VUa*5<,Qa$YZ]׮[0@ VKضu#1AХ60r0BF (ypoĨq<04ʟ'F2éa?;|^;{ܰ~պ7 ]m/\2C-ͧ6#'He0w~pLTOC#٣udb &ۀjc^.ILFМpv1CҘmUγPB(ZODn.:> P1N Bܦ԰PiikvڌXdym, L'[{;PqnAHd>刑A6ukV:"^[?ZڦAЊ򨟯*(4YDžŇFȦS<a@@7$!0a-h46 Li}-' )D -=)rh?8@G\#񷉒OR/(O/B9M tJv8iLp:ԷO#IC~ T ^xD0tO7޴plgFkjeKęQj~? C{&yaJ-jƁ¬Z!9TK -fuog=IF3]t5r֗1ΐo98i-Ku# _]YS ݮa{@84 =*CfJr 8^ՁkPɓ? ' aa=BGg4OkX.G?B^8B^"rc+.`<aoQDYJ}@:'0 +sXLiT9^{ .):1Owmr 5? }1ʜ֋(DZʡCasP_t $IY%Aḿ `9iHaӬpn56JM>-NUِ4,_, ɀ M0%0b |iR (<Yt?:*JONQOQ  ]iHr{'H-<Nj}u%ߥ_bH &/|i)dGfxcsh~Sشic> 6s<4V06/`gG\p4(bT`]=խYW] -_}Y};ef%Y0OuOY!!R_6)`q/{ǃcéN#mq1Z>)bj^3v ""4N]q5KF/@ e;jS_#?#*~hk^lXy&!\F _N΃>Sj*%)RhcnzjRF(QH(!"Sx&=-]DW[r^1^:µ@L \Ʊ>J ڔɞ&{*eI3_RR&eτְwkM#;)gc!P LӜj4v ]jv"X#?,Io@ʭM m =glZxЪFH:aM;J5\^Bj!Fe= 33]&1,,' l^\ WnX`/ߨL36 ̈́lhQ1M_629=7G8ܥpmaU3?O4'AȹK0 ">GkLEjt:^=#@ =KWE5 ZZ\:Nλ V*xm+B1,/Ͻ9{ 2=mk1*v(Ա2c#Bki7az(:qojL*wn-w&-E" Nc*0c#3z^\h`+W @ O=$ Fv:S\f0]) u&1F[髠XS'u&,OpkE:f)A"C$ArD.U %FHc:^il}ŏ[ry^!q̽pTO EDG@w} }3\ AX^w#gJ`Ɣ@=9_z lok},gr>7\h~G?[T13 I-6,/&V EӺqaavj5y|]} _Xȿ%fݏVxo@3k]Nӳdԅx6$)c^jej|h:U "*Ĩ86Q0 =Foz˞Ar" ]`h*Rfũgޛv8f6`BY^ %j:)ּg s +dx{.S@J Iɀ@'/*F}|ͺ~紿K'"S7=8<>ԇ~I] 4G^ H^\IQ@aPq6~?TXzg'~a&=YWmڱ 0<nG(Fa+" %4Jm·D(p~{8ul~&RtT&^&u"4oJE | ?DRzE'JC j+fL9qa~8?u Ir/?Njpe$~G .dӪK >ɞHم}[^nQe1%@U2f:PpQ<¨_HYݼdתю3ڑD$#J;5)D=N 4 adGX$/j$=au\Ӧ|O#.ZyrIJCf+Qk?l1ȖXyݴ;o@}h]b.+.^JM Б㡥r4N,ˆj-Óo~>mawܰkKthl}+MIyiOloqTŨU;*:(1wt% Q39FE}|n.>mPsȋ(5ᑀg.r4&ep MZJY #6Cww/*)"8ߜ$ {1zȄ;o~g>8_7G5bށ_RaNepٳ87mL5x I%ӣs5gML) 8Y-&]Gu(MI!RSZSr-lznzaYmc([G1T !u5wy( "<ƿgvlfDk I/^l ?{(fЯGf>\Ā:PO{4pOj%}9DhBOk^C)t#XgOsZdÚ {YYK0xns_CX,1 NN"ܭȌоs* 1t,t)Sjkf?O9NF_sQ8iGOCk%ᓿaݩ}3m̟`sO}p&<}icm44ͯ^V/D-lPQ )~Jy0~ ._; }p+\srNsXb(x%эb dNga!XSWxÈ)TE @BKc"3k[>S"ΡT;_I =Hqd2ȷ1 3Tܿpx??mi~FkS]`H]Ik 7Xsp GfiKxE$Iou*Mih[=tDXsD}~VV=zxe0kx/Pnsv٥@ L=eX0ualF02O{-ub,s(X7>0M.J8!Ko@v%+R",BE2鉽}M_B7ezx."'!ZWAv9LBdll:Fy\8QM+'0(Ɂ2I"5M&3/^*#OIx+_7otf~z2HT5 8}#a%5[#N rӦ{OtN;{P(CŸ@Ɗ r|E!"Ȏ<sX,4:=ןǘQ(A2M89Ek?.4Fø%gyCnq++J;UݣB98Y9"3QW";?| w3SS}_aoxwFu>՜~t~۳gO|7~[oS_R8sf^,UḊXp-DJ,*D]2cM3܌]tcy a@U>z8.mWF */T]h;Ie]9=cD\a]*λJt#I W_& $@vmm8CjKHȜ{tJ}v4ԒגcP#b@ZzNolHhq tv"H-fv<)P ĴE)DH_+L-ISjR(owV8Hyeݟ΄ǨIn~tcWOeܢa~s]yO||u x/Q yvSI5My_= 3p|`3MzG~I }r8 ie.}N@F6U"5B9buM JS=LYa.H#xr$[9EeCpn3~i̗42KG@\U[fuU2þ#O?_ٍpǾ,"3+q\3Lpݷ0 H_Hп)9%-"25 0ۭp!6{0v)E<Ź%`ku(x1*%l{|AK9>kɳHHUS] hqq.($>0: 75 aW˗Q.iMyg.rޱms,~DƟrjKՌ@@Pp 4 P{:VZM GUUzL$)^JayAv-w~a90;:#X0˲>:[V>W~d&H!)XYk3_z2yT=QE( BN% *:OyHt*?wS;`؈SBIo-3y$AQG ?Q𮤧dp±@!z0Hu[_BY "ƄY8|cϰ+H<_?  +ɢy8AjtrO?\H'7$yg=$=+[syrF$$AHF5NlkDHHhF#Ft9wWWUwW?Ok`Gk婑z]]筮sحo_.Ѕ҆l6O=-?42Q`R:){nH:nevlhwn F C 3uK}+ W %J_lQlC6йޤ :MߴwV! F`6ӷ|o]\+6֊11!޹gU+-g [>v}yyLN>߾'hA 7| rE tT4ozk:֭|}z|c]ǽRwr^VU=`Fgؼǻ/OZ*rjo |ƭ!?w;GMP3=}+`*"9YrEhS%)jLz{|s  xV4?jG#Pͽ'R.O(B=Gu{uPKLfXEO,k$prѶP{\BUVSKg1QXcVڑǿסϢ Ҷ$GϹ/f_ajeh|iAqŮ9 JC 8:6] +U:=lZA\0Ιq="m[A+rXu'`e.̌۱2L0urTSY]muF'f)>Ѡ}?ḙ̂z }=]?O٨0E55 UVVߺ\ el\R.!'?[s 7EWy/j~lpx}~̟"9e&uFG۶wt9yer{^#~zE PdwN}~Koew{ۋ[+lbԝ636e TֿxMT-^x4^8l;) \Pz9R!PChNg.}Kdyyq+h};46  µ$j,nK``$Bv6? T~{Wcwzš@WL`&/}JvTv5~2k-7c~a$k'A~r[i/є>tF4Nr=Wl~˨  !z~V Z7l7_i3{ |g1)sC@L,ݻvr0סCPw?j[Dfq {\keDzJʭ7-;rpUk/Ƀ@TaBx /C(q0Y5IJ2{P>z^-: 8-%xmoOX(V>/_ػ$6Q7n}_AJ0/bc[a߷/ܰQ/?j/nz_+Qy=ҙÏ`^nѲRz]-Zk3ևMgL( _|ۗ|ʪ$rejXlk'C\CC$Ӵ7m|8ZX}w{w]\?W5U?srծ^xfP6Ȕ5<{{ۦ V:OI2uRI&Q"P[iL45M)ħn|w_Xe_)PS~Bkq\f Aֶ*+57 M/ \''Ky 20moz;ޏ74,̹ ]6^x~ۛ @y$" yA,wG6EjPKidL誡uRX6)7 T&3|XrNӇ(~u( }jF즇Ix& 6džWry^SBzm#nA[iZNtKq@8ͿdShԚ''@f.뽡ZCTQk1HO5ChG!tRΊWЉl=;؇ZDG0 b_^Fqy,yדy Pҗ4zokPu2m?N>XWCߜe3j5G. rFxVj_;,<~ !,CEF2NWee+|'k~ ,ЈI.bNȥ`T]]cQ<\Ế@1xe`j S@wv8QIy]\0( ȑ7$ iSƭ9ʮ0( Tąch aNdq2vāvIX$?y3#zM['FCcgEQe қJ ?iwg4ϡqA|vϽ+@V.[ddPՇ&hS{ùqҍQMLN~ D/ű-udRG!?K3j  j-?E'׶e|5*xu i FCSq5ޏ/ dN )ܱ,w*s0?HIhK *`t: +1= DM8ZFh# k|0굎n[Q.DW8oGRCd8UZ_:˪TS(/A(m4# =]}GZ;כӆX\T$=9ќuuvfE>d@zع~[FQ`TW;*I L/?E7̀߉͐'|\`=_] BwyvlͭN (9\_ѾlbV`߼q2<ўc7WviS`LF>5+]TxCnmP[6 h냽M@U Nٟ>e"jV}!E(Qюڮ(+s(gN~=}4`3O[qy<(Ƨ`q|Lֽi Čct^΄ziHL-Ld1 ?@S',FK4R6Tٺjs8:<\8?sW f@H'vK1,e/~~WHKggR~AoVDy+py|3{QO׏oV(˚ToW=UC|kf%WOU^tY eX|(_NaJ2Upr K\hc1K 6胼F|w=<UzU7Yoe\,NE?1= p.͛Zmt|`AbѰ=;c*}j7C|(ھ@ y%0ZB33`I'~ͮa7Bՠvۗ__O ޾nSI w}DJWxJw 8.-y/,oYުۼZ\]>P Iϻ:P~m89|ڳ$޺6R8iM*v il[=p8rBY$ K3vM، *CoMVDY`=LE@׉' zߵ:++)vC J0/y $I?+.VOӿFߛ$':m|E`'V}!ڤuԦ ]^43M![ B+HS /ƫLO b5z'JITԗ};!s s5uMjrjJ4$tf =q}c/էG8m ܧb9h+^HTo]]n=%;` (gʓϐ≌4ʪv͵W0qNNr6ޟ ohB9s9iY48'0YPLӞX}:#qR-+[uW;|޻@Ne  ֮B"5"6;KF&a}?8]]Ld*XezżƦg pζazLNuR2gD42d !a)&B:Jpe_ MҮv dk {uqwGm&N`GW4fS/dEX~i9i!~JO[QU_OۼeK|e%|=hZ?Oww ^+Kd();VXQ^(Tn[vW]ssﻍVgWSmfˬ%+kS2exXeojXWEW*x6ƦF[ jjSo΂jZ;EiAW(D% &@o-/ D8f4{^i0 !MvN~!. ٳmlmru//IĦxĴ8wg)b2Nv:z@/K9cm7҂Km^Dy3 h/mĵz}g:aC:Ϙ(ڂ"^z3w7#/;>d|Ç+}s%_lvi=!bO8}_lv8#9娭?08BE/7CW~W? (mոqF"V~Q hF˵mvvѪ *+Э:BD ^r  {>nS9=5^ So"@\+یXYJfS"9ރc&IXy:?V[WL{.{}7Ow" yMڌ`0}G!=EV ݒx\@}}UXFp1UځǾnSGľF2Aw]ⶩLKKUYA= /U=UɞW}~z>L/%jbdϺD/èOA` m`COEz[N@[Z.O,e`09t8,XF@Lb|mg+\x>knn.5(W-3x0vE}Im nޫ^wANy"?bgGy+wms5ZB ǩ cl̖hˣ^טU7 se<>+ck%_m7^0>:]cPI2Cy8vNz}PK#UJrnej#}LF xƎa|Xߝ,{Z .dj`/c9 -d "̀ߦWۯџO)  @=b 5˅#[t'@np%TYV<>?Jb~h_uckA ) 5/}j99:l]])cV@eCD&1Y7@ԓM-bk0k32DRRA4섽-WV )PX=sv̪dv]?3f ìZC./{ ]-M#}&YoQ(η-;z^xR@/c&3߼u/퓀gldzSסA#P˜`YVMwS @ԗ5BXb&Q.cO-dCAkS[P(XG˹(}0y0#iom; ]2:T{GOcUZBQ{oo},vxEWݪy+piW@?=}ϦY_+/ʷFZBGgSfmݼ5Y>̾ ]Kloj+,)>۰q=">0/ʾ'j2=ذdz?z55*?Z @`+I"+ÈuZcVh{9 &_@2zQj˓?Dv/{^iɸo=|X/[Uy%y@'ſ~ ~) ?y DX|̄a"W  *Bk]wǖ QzWl(z-?g)2Lo+"ˏ6aEIҟw <Zy|V`,-bpgqNiV/?o4TܑʺyE9l{KM9޾'l~嶷@֟GOAZ?00L_x\LzFj((~MtS<ɀF/@8ٷ]sGT`(>*2|H"LM V/,}nMNs#kym&{|Ԣ^gK{ѻY(aC,A'>5l{W+JkxÅŅT2|6g6mhq+BC vUߎ7@CѰUUF E\LyLK~YWO=+W^_쀦8*};\T0 k3i൫ K~?baQ0ѐ${׽:gq%|ӭ7,)}[Lœ5]ن?ago+¨i-r® .b`!644mmmػbg.jh=bYhҮNLm{`﾿}lii/p<'p˞ dY\gZb>.2mEHdi»_F@/V^-y*k,I/Dg V טU~)>8eO 2bMēxYJV:ZǫĘ[aC̡Q8t4ƍv@?Q/mlp+JԦgy>%EPxiG)=Yk7tsIV_~ynig^ _{s\ ?4o?`4 % 3Oy{"hA:jսH+ k-RG9TWxLN#P^ .{3Ⱦ7lv،> ݮ寪 y F) .d $&vej&?yƉe TPSd 7of ^z/RG-;WU7ۼ|V .{uY)^Ksv࡯șXB7O+?F?j;vlS{rVMui޿\c$; ]UP= aFK^Fc(/),f/j/Զ: $}ڇ ZdTqii-4hb[Bv7@4H:;uÂ: `FFq4 0g;98J_FϜyo4+Bt ;69|=A?̽z++?O/ ɋ>O,N۩ǿcs}glvzʫU1J \?1Koݶўix $HXU_RK׆dJ/vEܾ @_0;b6 D[)m K .ćL_})"t@ uN($( ;?X0 #{wS\ABTJ(c# rEL'T!s 3@F%db֫ȴ <^ofW^"1r劁p6=5s: .AyyAL "wo D(%Ƭ/D xo籃XN3>2xk=ү\{:?wMؾ|ɖg1ƣFZGӪ7ccJ#Z<j L CO_^J~kK(LNC+/L~tlW\u1`/  1 5tMY?yUd0iVqd n8L'&dc'1iZ=cfwiM|u.2piwPiB缨("~V=G[EM[ 03Լyᭋ33r*:jL[_/[th󂿉f}u$xm޸UAYؔҫ{ˁaA݌hxQde}ʩp6gkP2d[?+ߏN, cPj*Aӎ1iiVI,ky2+*`!EC7] jy!_{^zH4yh? @)!-|X#`XC0=k~f{˿Q?X&#Ue^pYܦ?I"kjӎ憭 <LqTOSOOA-YSK45^܋ʊ\ ^Z\=kmr8l2RZ]ƮYۿ5ibg-N@my҈^|MPu3Jy)Y$(Y\_@y`V~s*Y[w`C6#Y,@in}0lnu?:)rn^)2]  CPpP]l3<6REYenCm/ D3Vq cܦn/ԣ@=3>mlmPuSS CKztT/d"_WKm\}-(+V\I~MeSd `(B| GBkT[(D8U ?N2ve W_Mׂ{e~:FÄ+W@`}5͐D+h Yz cTqu=,?P1G|" ,k[G2f"uV}X6hKu%^\Elz#̓#`] ޷^8334p|X_b~ʶkT,Wxt>& 5j !EЉ@`W@T- a>@uve8y8P ~_Y`l!'wsISl G@yUUBd bHLx{=wLcrڮl]J azbB7 `3BQF3cD7|q Q9hv9((ё Ҡ"ĉ R fW@eZ fΝ!&`2qg[orv goM2w܎N ZvyZ7ԹmML2~Għӱ@\<\^Џgd^hpN ~'`VFstMG<MKrn20 iƮzX "O#qQeaX}O[>L~tW1YuAl\F0H é3=pck]ǁ hBWHf#gBejT{+KWQ pMq >qh ,@[ddf ^?T03z(m/%fNMo`Qoss 7KΟR}2ގvx-9g)ki1HE[+57ۆ;(($Coj)MYAWW Y-§_A~Q/f2eNj9JŊJh˸~W,^bg/HPlDaAP!“ FK >ɧoF 8uvP8 Qg'@>7:A%=$p V:{VA5Ë.( GIs' k[N q۪a*?XA`;F +;Yyٶa4k0rAyI3G8kkj 4"b$$Ny % }$1==+(`_\gD qa.2A!I瀲%Gu\I4 eN9*XD@~|b!#B=}j,Y]SoK_Ť9 oD+qإH_iqS$u~zk2,-sN;\2AN_B l X4eFH!𝆪H鿄4e1cVWb֖+nȱ3؉N j> )Rhk&M@O^q5T vD2R2s6@p5?5gZa=O R]}.XHfYtSev@YK$0VмC0.x|y 6V r ł{N?Bi}I}/Z4iWm^}shYsUNuUǏj1j7x0ټiרMNmA)`J šWQQ"~ǔGF٥e86Y@:϶;*Yw{gu:W@f> Te#bˆuͮ-Z "8F\(7׺V)W wZ(!e$0˱L]Ze)J%OؾB1|0&"V׺GIԚRlh(|:,7)d$-@y= f `7q u%_yz+;+s/rLD B6? `SEߚk2O]&O%M9pL'bh PY^ 'S) 8L^Q:p`!S3)2gQ1j%U0qq gY(s2tu"T0GSRA?WE *wʸD8ED14:bWζbMuM&88վ])A~&JJ( .jacR9)hED :?AR Syp/l<2qN $J*qsc ; ײR2Pvn_oɊa>4{}Ү'* =y{++9qr$`}_cd'/0ƧP/z qL|&3NkDW֓KY{EY55ۯh9ZePu3|?93oӮUn}[i>f>ծ܍A)^*/0Gŏ3ofvv\'}c4j<0Aɧs!j3Jz sD  g:y%8.s߭R@FզuUY!%A#^Yo'XoWo_1_b"b0c7"e0HASeL*+T2KlY K0)͸? ,?CÁ[\\/ŻC4:-KulvUg*1~t)?82e3P[6spq盛CDi O14@KP!#'c_8u-۷z-PsNXf?dͱYN~< s2  J6QIk&Nd+uVцaK6VAIeX Hޟ f:A~}@MSpSGBOAoY^Y1 Hut"^$Y*!\{`\0QmFBW@^ UUN%8 8Bɂ!JHU!@ A_4l2ɶOy+@_u9; ^{̇ީt Vc=A?KލV @u38',83"4~9bXIK +@S_-hpZ| kM`+,$̒Vn "f tT|RDY 쇟uI-ƧlQ YFQ2 ✇pRLFXПf1_| }0mǞ:='x?z+pW .㏎b=59fC]PVZzec9kTd&U!fesW۝,pի/pAOSڗ0jee#XRѠl{ʊ[P D%> A_v@1Ou*("/l F_[| ʦժIz\Lr*Yv\Ծyt  C "0_Lz`a {fFmW\{<_Z\tb8THq|?/uFv9aͦa6f$Ux͍;morbEmCe @a9/`F~)fx9^ҝ>}߲sgELmlV"ע&pӘڡa擶MQҚ<˭:)3׷@aVPq? 1d% )^6@D0*,_8%v?j_Z$( A}'8Q(]퉋0N5lټ dO9C}M ^EM!T~/lD`bb™I(WI~m- ]P&Kd(@ $Ă:?ÈR0 ̵PZmBԿ^@,KdAE#J H7 2Hcd1/_-L[9:o3ÈxۏߍC12| B?i\4pu ]R@"`#Od2/W;c6ors 7%9+Iy}p'aHWY@% _!B4 VHZXJIA,0 / ~nqTڛ}HxlUQh2R@X8Z)5AFmi[ kПDa1ߖ6y;`]meӪwp(v-f)yLe B4,q 1W]N{OXmpZ'PԢ~>r>T"WA%@^4rӺ&paVf3ss#SY-6Xmy/Yo՞}OOdEE(aY+! ( /s':*{Z}u3q$a@ɺGP7a;:YѼns_ӯ~/YE\Ej67y"y{[X/ȉpiOeyECO6?FK]q- K&):jR쳝;IȀQį(ЦW@\>  Ɣ`kS6o*խ_td@M<@}۷&i-H8]@VjxKS KQvy /3gΑwi O%u4>čʪ5{@5)#^(9uPj>0+sM+Q6IߘZs$0'Xh%t(mI S_EDK=iO5Wp; C 0F븅SӣkަT pQK-7(3xs?kV`Ե5x]O>O|h"ȜL[P;":#^u[c: .UH?Cww}bYIzF|5F :8:m=cvՕ;]4~=#-iPQĢ38-׻lYth,xɊGF].1_LS!1@mgh[_J_@#bCYIA@>tcC'=B=6? O$ _mqE َvV] mvmlc.Y*:~?Hp ,\$,~wSV')z)MV@%,{[b}C#`~ڞk_:+!y >BDne5H2_|YSHTcڿdձ..r5<6|ǽȉ $>H }G[챙!n>*jpWg(74|Ek.=e2F7^^,q wnq{b]= 5*ťENUK:^Z)1Ts^(YJ)aWO[,@҅N'qh{u#̓9Ek?Խktb%$~zy!`uP/M"=j讀(!~^-̌ %][[-x-WQ}M}嗣 s=ݐu,'Km9Ӗ& I̢V\y6C0E'hT#\O%5O>tݭm#c n>PjP_&2߭, ٧ҙ#\37M|[\Y/Wr;T2P0O|͟ aݘte(HzmX"PgG?\">v5W=(GxeӰڷ\.'`emQ+gKNk*]V*12|[tM}E2aȎWUV>&j2Cr~ph ;Zѽ!}컦:%MThoQTCg+L \bz  'SviBѨc?#v?MShd#a'bDG !SϿD|0PL^ૡ? ,T/D5y ^XP\"ߓ/LNЂ7n6[Q0R]rQ\fq-ebbuWGԧ_*ÈйeRD&}%#&X8#6qD LY CT_^I4`'XXab+Dq2JP5d%T̵ !3 ƷƦ` ͡3Kka 6zq56]l2N%F`y)mO2[h)%  dH_s\^2~۲s334ث_xt!/Pזqh,`%MqWOqQ8peN*;&xkc#@J~ )XY^B6E=1xz+Jfy(+V;u @r~o\bW0g[ٻ_̄1۰Y k2kGsCj9E](Pi!T>WFWiu|$VŴ/:q2 I>XHǕ0P=`@ ~Vp.Ld`D |h֒o^h#4B|Ib/\qh;¿6Rmrx3ui>r=n{~ 4M|n<_uQ7NWMYto/5i :F'tu ed꿗C_N8_j)vJr>G8؟%[h̏"$ݨ! &9Ge:Fa;NXyH*࿚g~[\z=+V4TW=>kʯalP@[c ub%.X?TJ~D t$ƙ0Xa O$9V Ge)ky V@02IG?b 3uNnN'NYM,/܂=uzq5!&]}_] ߭(kTׅ3ŗx0ѴM֘ )Vȡr o~oo 'uF=hm D-v){mopb;=_0 - -!xbLeD]4tEo7ScmS_E9P~u b`#vD:5Np']X=I)Չζw;^D~Ceb&Dz(@b@销$̌t Q^-/ۮ--v5og犏oE&~"LyLSQ2Ԅ]EI`Q^PS;\uxe߀DnU^dSLlTU厂/ hhi!Ǫ`hrf ˪Wop꽼Gc^m!xl PdpLJ=WlND̻q pAHאHǬ%wFBes>@.@9Q JȚBJ@#2 G%unJSXđs.W@I"EIE"Bؑޞ[u qaP o{6̆ :&,Xza&8']a򓱝ox [bi^n?bջXyMs{ x%W`/!" |{_@'mnw\*nW Mx(ʗ$:3kW4L XG]ɕ+sR= N׸JԮGd@C`Ơ!U@q=f6Ʌ;O<(i1-)onl(BN@<ƸO4c$+žWs&&f19&CI{GgOVƨk I9uWIa%1{&Řw6Bֳ;dfOխZAK bdM9ZCEL?Ĵ {{pala R'!["@Xkﮛf<ٝ7O%xIۃ_eE0f_Gvpߣ]&>-9dAȨ L).굆:b<5i{mM78m;d-Uܳ*Rt8b< KrGf\ YT#bf ^qgFۂM{sg[XO; 6a][vibEBi+.C~ͦV5!i7zonjLmmݺ)3Jn .peDzpTj|UyH^m=%~G7a M"Pr(AUb4F 6<1_{;rF a 7mm>WiC>c`@\AzX+ K *YHǓ_l@5;w4]~Ex]YSs]]> )?8_ fפ@o3@IDATu}ߵ|< ̹NZ>H` *E3;?\}s54P@ ><2GWӯg0>&#mL$ԚNe?iʆl( 2TU`U2"/TmΆ#&NB`pR.S6=t_/8}5e4d6Mxz>[V7e\SB3?2`׾fL)*K:b}&'\C 9JWh(U|gM$?*kWeTZ,ɒ,a%[`0 6`x0@nhCs^e76-۲dIUZjߗ5r\cɈ/첨=JKQD"2{wj<6#`_b~=5_ڗ0Wy ؏6 0D%/} r@Le'3S g!̩DQjYA7v}#g)*5 z`Zz1z:]?wOs[W {;s]7^i9=U_LY_i;q~pkwf Xh1aڣ,;8z1d5r*8Ч,w,p-W6EkY,b&JOw`^R{{$y[\ara5̺)|PPu\v1YEH4Qa)ZgX'_:Ak@ j߉8Υebt=6N @hO k=y`AL&="}Ug`<n/RE]䢾 Y^܋=)}|TY˾}0xB|v1Cp㭯eyw^ǿo?ݎHc>2Rz|ߒ8u69jY&+NMn<,zr."9 t-}3KWB#oڰlW~K_HFD$ñ<`wu311'gL y4XW"*_ (ؘdȍfӞ ăQy'm nM8ȣ``N}Pz P _=jSr "] @ɇuӖFnkQ,xbI.ORV=̦pƅWOZ6gy!b? K1O uXE?g'N5ZS-i@D<xRB'qjXggzn~kcSVx-:ZE߶bRŖq|\ϸ-_mYI:x4::/<};΍؋f2B9iTzd|}8aԞ(r),硆UDgK(8B=ixNSm-vc .[ 4)Sh՗(a 4N>2? sݷLZ^#Q0%5@~ajWEp\[֔@O_qȀg1A-Aך 3زr@&9 #TA4P=DVS:]h{`z[Br*$!#B}g_4Q\Zܪrm6>8M`ys= 1e,%  iX_ Wg Q^{!OUeUKǥ6>Ļ}/}ϟ{ƹ?_/cC/~v~*LjF6=G ww͐(c_Nx==}8օrWטRzKxN:B8Yj MnMMSջɁm L4-p c1[ě>,aw;'_y2\?zl簵=V3pe (YO۷1J<ŭoQKqAI?TaPv6n MG,˗y/*PT"1 0JDnLOZ|J z=86Jno9``Fyܼ YT?SKǾd k;w ^u8e7jy;rUXQU ) P)ۻ1 4ƭI1"VSj1NOEE࿹ 3K/5@bxL] S|eeOtv2@?c %6mhr#l'DLĕk^J@@AHϰJk>w vlu࿄8/&]x`rY,~ofKa׻tneX8҂8 G0YV9U}N&wN;zy XX߹lBHvJ*OFQsKo7&n?EW5y44}ea5_0't`>sׯs5~N,xDૡ mR^5e A %\ x ԗ5eHH2UA߲"7`jQu= y.6@11 j_7t&Z?ٍ|8؞,q.0PgBn4ݎܶuHG ׸ٰJljPRO;]O*& $Ț%؂l5HG6`PYp2?$BF 5W,Az`k-6xE~tCnĐ0n~ ]DKs;ao;)|z/c}ޟX2j?#glG$'ڦZْV;rw +3jLo7&N> Y>|bϾivs:@e]5yDud~){}N`+kT 1 R6 t"9t d2eO#etS¾0Ṯ/ jrܱ}+:$qBY>['Qr upaoǓ ]U @e_|5<*oncry'=u 9$Xv>x~_ 2( _1ӠTwΆ*EDY aH CI֫[pٞ]ծޏ܏w&GqsfaF!OaP J X`H*'l-2/p22g3tRl{῁e 1EOz_YLƽx?&mwכl|g@>;-S#ܞ[#dd",+ lqy(k]N< x:}{8Smۖ %Y:(J#pTmZbKE~XWD`?8L >5m[6Ս v9X/escـt>ϟ`C 4ͮ֝(\56ڮ]쵗u孟f4l@}vo;L0@r|!-@K![g?10t<<˓<'"I Ou PnuE%1PG3 F|L2+!u¢y_`vxuxuY矑?C/)`޺pYQYu]z?NItIēnr?n駭 Hgyqvͦ-:Yeic9~/d3d dëje.W8~HJͭ.PPpQ]YEsCD(<y(h" آצ>JWB e`Q+-ѹwnSL(\Bmu߮X]a#SfءEo KBÄ'A n/m{$T>޿t<Dk+&$b}ܓtL,RnVY"A9 8 xi ? i!m#7g|hPۑ?)Zck5yI/d$r*kk _nOxT'87ZA& ]eq@lSk[Ip{ǬQ[NQtvGg-Bk:>|AG+C/9Ωk]&?EXN\eq\_ӭ O7Yjˁ/%P%E|Jate;cL+ 1O]F /=xw9:ǀHCR31d#!IL %9̀B$MԤez0aLF,CLI;stk[hyx bY8 0+\&(ۨ#1ck>|n)(&~d>s/^?wiET'k1+/M@p Os"؇ZA@f2A'! sW}VQYia[2anͅ/⤷dj{ɩOuy;mrj~ D+޹}3BB|12d0`~꠸d\ \9`j@@䦀Ej%ڡcn[[ OpE@Tm͍̄8`1-]ecXs[ PO)hb;4 lq  1E>B,' 1@ZO He0Gđ~;%yd̗j~g?/+2Qw=p8G'_r!A]u޻C'ֶX{%? W}K^4p5ZGS3'y&Kk(C}]}9oʩkqFz/L@G^y%t>16|P5k\)uU芚Z׿/Sy ^Av 7` œW+_G"A_0ۆN<cr--˙XU u O3X?A/*ǵ \'ڿFjV ٺD&ejL.`xRou8s?*?kK![aa9Nv0&$ 'b2!#cbW-IiR/m{Ӟ~eh;wKMDfՔu,Ϲxj=Dڃ5T/۵.N_gMaK<'͵W_"ʈͤWptQ{h~UYynN{23jήnX3N7ֱFQOBuv=B (ذe BscDK+`Dtȑ/ 77>{ՖH os_9 J gkoAZ zK uA2&o6ԽFX;!Ƶ-,Ygm_WauUs02XF?RӌG itJ'ᡂ2E(a$e#YNQؕBӤO?=rjs~ɱw-qJ]|?03z ?tZ'_3O  ޱ ܵNy; ʯ[|!-.Kħ zd8I>(DM0[WcM) n'!q* J?)%PVEE^id',g LtK{dR=EQxR8"T<pY  % XHG!#D_k$?e& Ĩ1h U:C7?\0 J>adr8AI~M`HH$RGgEb ߰,όԇO\I`׉ejRrWLF+PkZ߰ dsmЄv),Z2UΔ:p ϕ}ZfI(L\F5G^{5 @VEׯ_9 љ ɵj4ۆZ_vÇܾ>g[ohiQs!.M3ޮ (AA.Z;-2ìmDK}c5})}ļa6fs,d.IpbbtX/ %A|胕1^+.˦h-S%Ƀxp}?]~_#͓1E?Yяw5Ľq\toFwmpN7f /EFy;_X8H{u\vYbã6D=~ƍVBС XU5VÀ2,B_E6$g n*08QmNBڨd;B)l}*>u+s cì"2^67>$3Z1wఽG\-B!C &!(QW͛M|,~ i{ïk*A g+*oxI[ A||y e@Lxi]T @O*uE2hi4,-o;e+:<վۚnnqo_{Y$aPEf\qD iZho3<@n{>tuM6=&d4@ $S@ 9AB@մ'&'9<^ufr%N(Ż|Jȴm,x!{z>Uߗ`>tE:plg^xl‰|>ZOX \JɴGQDKg ǹFh~1/`ORH xhz+-̶,'p&AU|%@XRWlC0 2R`@C/EEBB̀qİ#X7Gmwu, VwϝD}B^փk:KkV鍔Viaߺ[/}TtYCm7q񍀚ܸ\p^ʲrk>nը]?Ll4by>B@P! o+2L"3S{)(ՋAZٱD%JJ]\Jˇ!i|2j+E0s'P!uRZc'EwMJ ,Iʾ󽗝85}]w]m5a\[. kyj\E_{'f]m4jLh`u=x75PqyLΛiON&q! KsQ K^@\(;LJL4"M3/̳š].v +p0)֦anz/lk:[)W^x9J^p8'?JݏOrה@zGVd +_jO*\ć%.PW}ߟxr oEU9:)J_O=00; E-FQNXt=ݯGEVp!V@&C J ݶj+$Uw=qSB};1T'86+(mlJ]ٔ(,1EWDFִ`{VkF_T_ay=lm.^m:O&/)`o|iMkKO]'X-IiO4#Z[#}5xGsg)U+zΤN>I TNB.H*߼i= ^0bfl+wo`64;3x5 ;8דt,_hcAY;-&rټ_~I&SI&_̀ aq6X`x@/}̒y d.O*d7χO X/T*mdS`gH_^3J>4<& T^XRI\R"[Ye+H{/@@sW4ǹ:{GƟɚ_Hkn.^sgwO|ɒ (·^yQؗ$S Sep?-irS>}:\BY_j`-u u2gy)'z.Ci(SG&/-.u5];dɴmhɉ9~* HYdq EAq'v]#X>ε^{=o P.03`C]'[6^F*`q} , &㜯&W_HH0𷵱3".pplp%|  -1ZebOĚ(@X>V`js)"8|k5+z?L~P޸bM3tpe__z$YL~<2Ӈ~`.dR>t=t_G֞/=I'[ Swmb#cdRī.|)m{iOc)p\F_}zok})Ӡ~8 ZqKԸUO9%6B`y'; sֽmw2 ZʜEٲǭ;ƹf@0,2DV jKo !}1@ͯA:eIwT~K0R֘w4XG2i;$@DAnQ,M3 1Q:JQZ蒖éYfh&O!Gޙ.Ze(_ &dԮ7*m4wv@:w]:GUnr|C_FYAKDgʸg _Beč 5h@B&̵% |jE߷bt`ʺiuc^2Q/:=;+}x>w *7/~ّH\ i|G&bgϜ?s.i ҦHtQ< NR|eP p. LjHdpA۲i##@~/r#/`;0j[*,f8@yyMZ dX*OPu"Kk}!PYE6"1#mpҏ?_̐bלeՔfv 32h _Og[?%uL|!V̑uo-N.%zwq3ƒ4zN9-ɸkϓ,G#7f* ~Φ:ejS e׶A)tz j`2ߩ(nY)j%1]=|E @v`-+˷*Z^A0k4x!\:"dJCl}S_:繞}K6F` iz[B\Wp9sX}Od (tVrt) z;YS ̓Ge@z,ClnVϞس O0m K3|a7GϏӶg gSa^,2%Ǹ>M0"`S "|ͣg0Knb'6f/yw}Ê1;ñR @YzHxo}T3#{;㶴08&d-&1^ hS=YTFʃ_6}?aҚ7ջgh[T!<XEK(ļG&:g &"8J⯪(`Ot> p v lg&ȼ|h)>(I$laD*1%eO\AVo~ƹO|tRUQ>tGgu:r7_C#% ȣӟ a3'#<hx9Uߋy-QhkrGbWAz ??DIZu?L$YjÑ74lo^ϐMnsz{JSwW <>y+i\Uz + i9Fv('lS"1YJ~/@ 3d/WPxR+KeNLEIk#>c~0 }^$=ND?=_A 4OVÌ`mub s,t5 vJp.|vl%^)pQ7瘹7e;m7\%`Vf>wkuP_ %`랄O&eA,DV$15=R@2'Q}9E~V[d2lDE ;5 HB8UPe 'h"B@i8Ƭn+ 1P•6һ^<L?AWv)_׍?X?t `;܆um?&mfs6WW iC~2nׂHN%F K(["Jmq*PV>+*]@vlvW?I9_BkӁ'eRḾUdv6en ]j:7/PWҁ >nf퍢 Btm۷mÇ [ 6_&>KQ0l]2%| PK/W$3? 9љ {h{d0_CatuT u*dSR0 H4 Qn=3/LΔóZfamG RnM#[m () fj@ro' QƩK_r@}pߧX˟_}(fN/&)7;]Y*T+_dfڍ_*v$Q(=@k['e$l7dYZ㓓T@GD8vjh<$s‹5s d 4!|w3E/tA2Hph`2w}ClLͬC ;`7jޙ|]R+WxWiK[XرT|'D~1]VBR.~FQChb[0ɷP㢒oB3W!]PL诂̹@;/= !F< _U'8MK{m@Cz2~H' 6 ^;k&@O^>##Gϲg1:4xG,@Q] glV[Wk8 ^TZPAB["̘H ve*(2VT|*>o̶5ss`7&BTsTZ&`hN&Cdjw@IDATɣ[̃JAJ^| LR}E0HfoǦzЈ˶ |?e$Fԅ.]bĈd Ǖ^l[yI޹%V S"K|ieoב׬?BO{y1ްa+T;`vn%hC @"j}GG^Pa/[!a@|=S mկeZeMS_Dk(h~\Рu5Hf cæF'(da}o o#&>|~q7Z Y =Q_}H9neq iS'A;? ZΌͣ @j]@_%AFPY%"{1 ep=GGYTA59커Va;&}WA*#}z[y;_2{%_WG@r[Uu޹K i`y_FWP}'٩,ۑ\7w?^pԕnr .SG6HN,liOwB*Tg?@=iC %8Z Il-bWw0z Pk pn(3&Mb' \z/Th1:ZdajP;aUe;'9 =ڲ%(Np^d3ܾ?A2cdVV^b1jx:OچMM}'qp6BL\0bE1{Ba468g?]zI"VA}-EV_)L4;-c AǫP{,@C#}UPK'?y!#[TA>c!<,(.`^}#XlF9g|Άy-AO眂Q r}?i =>la" ЪF(\P5uUN/EκV{)w=L{5P<''Ȍ#ֈ`P/^f?G fǜ@P)J<'[//rW8@)~H(N'Z@" K0bn }U'':ʒw C -z*Qh{1vp@y6(~s9!Fa+cGפAFnb>tz<YH &NCGKD@Df4X倄@ &EKBvJ&4Vs_DJr|4YFɅ@.MA% Ɯ2D@ᚥ7@aOga>L62fx[򭏗4.6xۺ ⤯17n#S~kDKgIZ+oX DⲖG }R`pC^m%[K,5vtX]ULuPC[a m]|)' L,D^REqutR8Ơq<ӆuQ#knmmwhLGj?pv6.~EXJ'dzbXjѓ?J<4T@ ]gg>2]d| {1HP) ,Ծ`>AJbqg]ۆrK&4KX&d_kҵZ: fu횐-'<K ^"X ۿ%atY}Rz TaL@& 35_ Df=lܪ׿5aٔb榸%}ٌ,@ZFy f$ښSr>fNqW]QmsUK#єm-n߳/pa嶜W \}}ܽdAm;wϿp6*(O,ךjʼ}d2Q^(U?y@N<1x@&)S$~ ])I=uhNʹvbģyaؘ g[uumݲ赉ƌHVs?LBg ?=!`>fd=&uU˗O .\,Bf6Ǥ]@u֑vCQtAh2ku}M7H۽֪"f}'܉oU'h`G`=UP&OfV?ŵKX)-/ N+8$כIPn_= 2]>X@O@. Xg~SgT~&L?Aqn$Ví5VjuVUDJ+VZHpOUBd-?\zmJ7G 4}Ssl3[q +6z9hMqӲ涠ktUZwJ3^#QigF߰6 (ʊ")*^5)&M^6X O{]<`Ɋ%n]\1ɯ޹ʌ'S )OO@ Tsv־L-w/ejT Dl9XX 0Gt~Jx|1l4_hx([ޱk_k=wPW[DvՁ|$fAařfzL va9 .,BA&Q`jqJe-qub6&JxX^$A%Cdhσ*Wpq Щ148As_x쬜ۥ``sgHxH`Dv._IRrM{^6KAO ic"}Hл8M#;[;~ w/G{\/̝9< jh_]{kyYny¿k=-o$99y#˔]ulQTU޲i &@}I}8l[`^~ݱddj ޱUϗ`nn[)%4S;E4/q14 &h֤ lT85"+3'3_GG?b;:l G^C`3$LTBk=CG:1,uq2~k: (a8 zQ0 r9V& ]Bx/m LJ/K&w8ual6!dK-y!; >b C -oYEQ9%{ٱJ*M5iqN|40I!CvAVV͂NI(q LPMA}g Իk_&AߞO$TWkNo` / h9;f62`%Uf.XbeF"4eǍ^Խ&OuA}'p[{l]# 设5pppV"1x>^EE)N@Q-:oh׬ h^yug;Ha tXLcc,4~5`U!@ x> bb;t]]~a-s(DC(žIj7Ů Mto=6,[2c}-FP6$9v½4"o G/O1#Mz1)CGa>1RF3\yfxhrVү؞E i?ffŝߎ/6 t+vE!_Q wF:SƟT:XW4\aqTb'>3y#İc:TgO~ezG`&I`zz/6_hwS]U_}EA*%(PȻlu :*^~'ln#d!ĂGQA@1zjϾwyI$iz'?S6BC%j|LEehy ?e`=-`@?Qٹ ȋK{`Tϸ߯'cu}#R N E~JK$! )P_UCFPAUT׶t*h/t.BֿĊ"WS%/>aF+UYjf*/TOU75 Uxz7Ek.iVxqӯ sNoY>0r3vUSP#Sl^IGv}@d8ɨG+2ku,AH`Be 3 9 PO()CHb .EOPGsvMAu +EPc07h.Gy `A6 ha")O{2gMz*lcS=$`12fڹ<@R}Ŵ֬Ko+QĄRƚx9h#SU\L~&AXȊgꖨNy L|r,$h#`}$g \(61׏큇!i'Nxz\<3 `C^2s/<, Z1 i]ŞHT; +"(lfON=:ߍP=>Fgs&2!-EA0@:iO!&fyDgރ" 4~˧щ3q A1ESQ'U|q] Bd(7ԗx++tC`)/] ɵJ}qGak_ǭ=T+R~ nn༎B^|zqu'oYw?{&˔F%uOL0eO);w VΧA@MBV _QVnm]-L_~\f Sǎ3F6dQ%a1-m uLR. tݺ&7@ py5g`f~"qF+K? &F5 C;;=Zꪊ{'ۻkrh, zɾ/v_)E>L|!f2ͯ}G(`Zm!:e35y^{u+4K03"t ]}$pZ|5iR\bį8g(,,U6} d^(G\mzK+kTJo@Hႅlj֯*u 3< 8Y{ z{pa[oAX"wM3? 8 #X=\񾭀"H@V+AF#tEkr`(;le4' Tَ2eO #;YE 1(cP8p_T@G%;"~[S!X q_tRr~¦f&zU),3_QU3Rl_?Θ?v̜ b}nA+>_'uMߞ5UzW`@ KfnÛ?w]8Ҝy<z n˦&L!@_ P6Nk:]6Ծzw9W,n#a3OF9jwS~2-73)ɬeسckp{EP:`}c9 j-Rۋn8G߽k=v5?99kׁ #'@x (u?/"L-!C]O"@\e)_HڼZ1A! v^c3/`[Skg, 0ͯ+LW aru1Z?uc/eX#'F8n/Ĩ;"_2KV,''gA&M_,46B&>$@ho`"X tVtx~_{/濄%Zſ+p+&5i78 wq[wW* yWb}l~ς"SLRNNVVej\ʖ46 \Pڵ/JXz j;{f{2Q/~q5oǝ"Ȣ--5zܹ3ok+F-\҈]t%ey㝂.$l6FX3&&&^hsye|H4s2ŸGav0"b4* 2(WLݱT /w%QndbsXL2# /`@&@  b fE!P@ B>_PME& j"?46ӵ$pQ/ {[.1_|g㳿[_4k2Hh7WDS32WWhs6DV]VH]GE D>2^r ^mtE A?jϞmS)9|< Dzh'ֲa-(so>rq[ZrikPf>e--0mRK0ukјځ.|U{sgjX>v1facqc4x{暧GNcC8舐&wT?k)Eyȣσ_ ~BW(L뵦B76l}AFЂS|`c Bq9\UQ,CÀLDб5 '[` +x(̰ynbj:sͽt`2X%Q_?Kgk}~zzn h&K|Ŋm{?\Q@,zI|ԫcmoZ?; %v]Mm[@!B{.,3m\Tst{9;y5@d@v~{X\oWG@u}NH(S!:s27\,W+~T XPiUe$8[O[@E,,ł(ʠ:|t 1\SlPg ,P3kg@f(68(E--)q:2TPG5jm _6^ %PH$!dd}#m OHNn}̫t^? I0X7;&  #գ[9{ĺΟָa` \}SkeWVٟ T#V&cԻ/L d+@Cs ڳ :;\&2@Xzb $Ojh@>:zt?%!0PΝGlXlrAe/K9juO|X lĉ##C7ȱ;za }N)~vyh(I˜zV#mCs,0ܼ!? C?Wׄ &=#y^DŽBxPW^[8]`u`q@7})R%R%:l˲889l'Jvv5[USj$ٙKo&x qW<x"fL%;?}}z{?YM %ҋάh {SN9HnqiľH'{d4ӹeBl57x?t|q]>{rՑig`ξ@»_}jmfPk{Yފ.ϔ5QW7@Y hDLCFL^A utHO J 2މ3[@$ߵix{/JW !\BG.\v>᣸usq0w{V4PSS_w >86%^j /,:jFK""X?AK4W@7BS hː7 < 6:n(h^0{5Pɦ,>v bi%>n2&00.uKQLLOJ _˿m{ yx+X7`u= s3l7s/.훯tHiL+ֶ|lqm۹QdhIimKV±5My]Fj .J|9mIr;qۭ/A2sM&C*eo+9L'5G큵˲C\&zv1gw;#}'X_7]PY8{wcLy)L?r"ˈҌύӱPm- 2iП޾h^J'c BH@+?2YM`zE$PTGKlg1Unhfam,z5v*sxhD"jT+cֿro 4q;>x+!]4\yr7wVbWz]t(7WNrr%7R}jmOPom%0( *|*y L D)䈧My 3%΍N(Z__-tFȒ]iAC?Ȅ)PlkTHP20FNjأ s>;onp/L@Tw4w߾ cv G+aڟ uD( py`5 d_,G V,*8gv~ŌM3Qp *B[1t{z椐u_2eW׺j.’f8g4$'2˸ &a`h]r<']YeH0baȦ4#!N&KyG&?7w?J= <[ 9J)?;7rr3o{+h4W__d.N֬~)ܕU lպ'y ~5>H؊0~e/NI䑑9~Ӹ HO=`A^|%0MALΣ4'k;ߺ5dx ^<`xӓl[eFL}+8^d?F_Lࣟ{0n8PsMt+' NנL_I!^%Y@2ׅZWI%6C T0Ԍݳ Nim =cӋ-$ cf(ŝ\C r2Ę2LeitӸ& ^~^ `^*#C#BY!Ġյu}܃O_s {t>#}x#Q`G`+*HrScG+_2 _XP$. Af  1)k/[}SWKK5rm WЙG@ٺlyQG 4dҥ>Lg\O=~snx )5f0t[q{25jCX7чk^YIā2V 1칋vLۏ2$S#w\u]f?PsD~ 0Ep)EWj*EHb9^zS{-4|ƠL%RDCPúM ґQw^u*OK3Q- $ ً?zu/y:4_' XhK`\oouzM#L9[ W"K,FՇWL?\/4]>8A2Nqs~icS XԶs2ixq^Yi)Xpmp`0+Ha@O64>ki[aMv+,E }|'?ib_HM 3`@37K(Dzg;KN4R2b4ua"!KPWBfu |TP|`JђZ 0);q8~gJ;1!ޡPۗHrf* s" TG`b<~Xoxs釖R 0ۆ\ z9mgr"B./̐P_pzADvK2u`)9jAz=/EX<_eWV;\ 0cQ﷡(&pkVu?8`,80GDuS3 PM% 8a SqGI뭫bW`_Wcs|h{ "^}?=GL@ ~*pJhɣ2)ڿF)T,VUHqX$-&?0bVTqS\!TpII2~t \̡HdHҀ t?ǜw! IAMM}/ōz&{!2V׹ou<6(F#Y/gw }̩8sdAQZj\un=.ji: bǾyvE'+g:yJ["9e7 ۑw@K3n}c`B 8Yɹ+Ot`D5H46S?҃ʕ.gF;ũ7@*X$xm^|PއN=vmzN$.QWm]C9tyV@< P!($0۶ZKhYQ 9 faO'~qjal+*.W/FfY%O_ҳ$o谫8-r RtngbNϠԀ r~Ҋ!y+Q[T5gk%n7oJ\vM ?O~+}-EVA/BM5GI nЍ|U_,h$`1^z峀I?/K(!7bde$p-e:>nmm[ 穩z} z(Qd?d/wn߂>]Ȑiou~;H\F0R|}+W}] <[v%H:2L-m _"/Q)/lPb#^-ʹHֺ#k#?r|Pq]s9fX{9ijGCX87KQک!pd7tH БQhfl-O?ڽ[ P}SXҶFB~d^}w aܫ@4(KQkli=pM~ԗC~)ΞH^8޵`HPݩ~iZz=/03N]C(ſ+Aom3L:wx^κVYU%F 0V{L{&pצc$^z`KIX$APcVy2_,2Y8mYe- lI3\"eNM4&\A=Jȗ >'x~/1<+/e-kĉ,_mvy[@ 7'y_b{-[ PA[2@9]7/xe?@:x>6 ^Pw7")[*P3:THh @EL"W3z @;8_!@`%#OPǕ.(ZqTu{->K t1 H$yzāqz?rv[3S_?doqW [M B1mJ܆Ms ߻: RT@MTv-M 'm6uκ.)%b1>(P`B>Vkea& cZ΃lAš0܃ܧƺfbc>ȋ?rOזf0m#LRj~l탏(䵑b\ ipB~:BȢ#xp{[ȝ6z~jSϾ_A+ Y+Nw1|e[6'Wv$+##VU)FY:Ȅ)GGȐ'^v_Vjs_Wc ~QWt4򛗮@z3Q1k}:EO,Zg;o$HN9]hio͑oYwchs9Azׂ(bbb 4;"?﬉*%HfdT_uW;}q \!VpA?Rq ?k;},Cve*=#"miԏeVWe Xbtj=s Y*(!H|`c w4R_js)+t݇ 2OMLZ};kffg{YвjY伻P k>#܄Fd-ۡC\߶i;ct$t%H%cV@ @q ɔ5@ALF0 zD\뢆O2W`ʞxp<Ĕ(5 j4!K_o`0, (;HQ5A~ٺ/xy:o[!훔LJl^|U5+J?u~y40U?+w/}/u}V`Dܝ1#sϞ=VvU~e1C{"Τ2✺0H!+&^Hei>C//e; Yɣ(rVV*Z"Z`/?ib8Yp9O/49q0}յ/B'תVƍ\{ 1ux$ڌe\0pCn`_9nvXLMa z_%ۅn rkfUGA<k $ Ţ ?-yRuV4CtZ"[;Ġ%c I&s#~Z>ך9)!HW!PY$D ;+*1j!\f=Wqp^P2CE5 y H" kR`aB}l;so hğy+pS+ѱgxaY v`w:rct'BҿYlr%>>|uNY)"# ک.;21j~i)-/j{ɉ 4ډT+#{b.a5$HiQffLr̺FtvCjA88WaB+0Ag#Jx= F8r_wSޓ(ʭFu?Bw c>6=;6Mü 4#%Q U>Ș\6wRŋ.3PMJ_ pS_ٶeTSz>A Q2[ nsCOlPFP_/(uu-hj)5Ǐ_a7z4@%A lp"d?wJڍ \??A {IlY+vY5,p>Hʸ`@?C hfi+; "0Iퟡ~ffVǘkp%./ߟ"dRd“qNj a뇧\_pc <>h-0"WX&hl!C+λ6L4i?{ug`u8yhxA ρ%BںC>xއ} >~{'> S/2gp |hS&c "Р_@+`] )h.Ȁž@|?NivwɏYYv*S H/\F>o> uԺ'Vkkϸ`E ș[sDV`>Fp>2It uw;4;PDD:i?;`XU5~(pnP9Qr&xh%”a!:7oلǯRV P]_ 8~#`M|0< o~챯z9]V@.E'ϔn|(h3'_~a9Xi]U֖1f6 }d.Vkj2[V1^oN \xm )+דS3"]9dھ2 Y =]ȶVgc v΍di۸a-1Zwbre}vϯr dE,cBX+ ./ Pݷ{izU=jW@`5X9Q{ nꬨyO %]8@fB5O2*&_:د17*I:&Rs3|/{5w'w Em lN ==pXvA2+*^dXݗB "V0ahoOٮDpU#W뜨~Ӵi jkj1͐53G M GYR4]޽ SnF`*H o? (;瞇no}. KBlޢ\Bڤ'~ b&0đ1F(f)_`:L0') GRڱfl@"2)ksPޔG5k5*ߙh(^UVakJbaAd?#nߛg`mfj pog՗R2aSs7p'@HCW&wU+0Ư<}إ gm.lj rU=_ &/:Z4W@-)M@(pU3hHN5i_iZGՋr.6P)5(`|j.ookܢÍ>2t6oވ` zzz9ۧ:QᖻV{+k:^pՃP7 DJ102Ʀ&{շ\FJÓkWPhx^ -aؓ 2UEz,edVeLP_ O0B |K48X l_c2*U?!n ".s͝6=7_=l __c;7ߵkC622bLHg]c[S2-q+@oEj((wܽ?nkorןaH9ﵻo 29uS a (~y৪ &4aW@[ D@ ],j_e:)$zI]ghE?qvSaw$>t859[T[DlbBb-_1ʰ5o܅xTَm#(mOs ';=u&XX~W ןHA@5`֕z~vܪ03̾-d P̳0jgj!2tNi|5nA,M1C/W~QaEEȕjfpy8g_!5ᑰ`?뼮pc[$±)D; 54?ԃE;rLұ﮴/\>u6k=r]<6.{ Kޙ~W쮻(T rGPc8#P`,$_FZTHSXMF^_C)Sw$J^ϑY@ OyX1˝Nw2 coJ@4Rwwa#z#n#`0\Us"ht2jͿc&;z`lmP`<_Lc[GOҁ $a4HlS 17}Dà?:z& 3,aL0&)FBY:^!C`z{9-)TֹAccc0T:`1BDb\4OPEF/$ Cѩ7 (u (*Paxh`/ \HZOyf{!#/ܻ@:76|񙃯~%f&0)98]ԯ^VNM_Зs__35_^븹9)[v5q9 dW[j]x$5h!ێO7bk˕7߼i'khe UVltgx֮鴵}g/:4Ѩ/^uCcK:˱acU@٢@DٳUSАeA%tKpUiVɉIo'刂, PRkBtf嵠N]pJeh4JD^Թ?@?d_#9o&YIĂQ|$]?갭3;}W? ;iEs']-_[o3o'qse#S"(HXjiW!+a2^PE)qx %:SV4҃.~ 짷,88歑 !)tb2lh[E/5k\+'6ݻ}cB4кV]]V($7kkvNF"r,$Dh]TagFYt2RgM v(蘮Bc |rP >}w'yVЖeM |Af.TQ P?+p"!Z+X\a1ΣX e|s@@,k? k dltBK&Yu>ۀ<=6ox kp+k){cNtbSĸv݁*oƦjYhty9DnKE+㢥 1JT4@ H.@~I3 *_AZ:{z&&ca oss!Z5m/~AcrU"M \q:Q[M% @ɧ@~׌ƻs]@>vBY.`&NLAzAg;EfǠ (8 2 动ie6I1'a7s啊_ _!#z y=a  @ V0 !> 8 }LAZ}V  fykͮ?ojkcfՃgIJ~jLx`Ɇ;-}d< :%F^uЕM9Orj$Nc$5OBp7׮Yű|oelUgշӆ'`iK+0Zvf棴)͸b'N??h֭vJ h @d{? #ꁣ `G *B|||kW,cf\?iE2z<8U~F>lZʂKC[LDa "StUu2`Tb//BA4x2t|)ΏÑߣ A7v$ u(XPf40qJĥ}Ԇ>6oxgaԻwV `>7Lt\kEm˖{lf1𦟘v WZi0OP |4Gz 2TUejGFy:˗mn!Cf R/+_4`^F p -g6vΜ2_L^N|Wd:mIK.@{7lNTY[{2ꉗ _ˆ=~+-0i@fA=w?z6)]>]-/ ]>kYɉ!l~cǶ P@E =2 ą9s8 id"Gy`SN`;d1blPнb&?|"~>h舕&`-f& y=/|x l+eߞX_e>@ pobvjQ͉/*Med&[)}j %[({ [mYM3[}x'-{1j (AH784D]w/\co v??DB5 *z-W-x3ԮEq=G{6mU$>eb68S MDwmX g/߁<_~ | iS/|%GiFB) S" ?@^Bv>3C[}`c50x #H\  lŖ.PRS :E/le!J eO`%b !W^=`恉~1%IQAhX Gm罱kTÖy7y三j3oldIܿ \2IF2,[ :0W;Cg2` Q_zz>5Vh9(gЅMW7wB]R5] !B]]v}*^jav2bhiIU z}3_?w؁Codn̍dc/jwL1(7J'/N ]eP[IAAAC|'>K#րK .`OԞܻS"Ky=<]wp-=OV':,;? 'uS D2@;7|:x /" <`^h2G%ٹ3ĩ{g_W=wK}V]W[ ۼ hw`ds @ 2dO\o_3 Q6$^"+?e/V@~,&p1x_q8p308_?o\FW٩hl鳎_zwnwPO׍rf\va Κ#癖WLp8b9}ݺ.Tہ#' 6\06H`3bvZy<Os x\ŤQL0<;9bO>S t_)!C`Sc;kFݟ10j%6bH >$/HOd_e ^T{`ܵd/z̪pB\LZ5rI%sC\Oj5/ןj/?jw W$=m h{駇.p-NN@4ј*Ws^q+FUΛLtd+ 9Gڸ44FF<~ֵ>^tTCEH۟H&]pus-FOФ |56>6j{mk` ښ!e mtE XQQnPf9pykZ4Zϕ+xlv*zQs/ѹ0ppvI?|e \'wa;|U( T]tA.`tzIL~j1>N~6pu$SGZ+n2ھ\:gއs=v׶mv=a:2`f .\e'lHzZl=a{/W ?趾Ы,~D`z] DSKO,s'H*oqL|`PK,Zk! Cۇ4$OWF2M>Oo>E%3fIWz>ӒOQH`F%"CIu'+BWP#(dxx= q,εmve{n&qy;fH%tD|>|]c_wh聿ny++@PiRm j+p[\:>Y?:cqK6=DRK,?pT>}ካ/3N @Z}QYA$CU@-㋲) {޹h@>9}>kmn3ݗbFPKs]e P1jQkmnuLQ763m~ȶ߽њy[:C``prYv]܋osy/@TG+^>DK]f.;Jph (I@ُ@v% I#}b|4a@@ !c#Ӷ}7PY1+*(+W vB$jkF W r RhVu4TI%\9 ZH4yֻc+_W?2^Y+ @ݦ2o<3>p~ߓV-C;Q0e_r]͞V,S ۴a˚`W+^ rDyKʤ "fV쁣 @Im5-p TNIScs5O ].kx+p+ܸ|$*n O]>j hvQދP J"70>IɌ%SZYK&^jVWV*zvi[y%:̥ާiwCc$T~Ppú#XLe)}'N0?BSz)0~mX _fMwqMs}Sm.fz 亇\pDaG\^A==h0HLfGf mm3PaPaqFDZ[ZBHX,}0*`HM .8)BחU~]UV9pഝ8~u.Yh=UQ[r[٠fl;O4wyؽݮ Wez ,>}P]|*z(K,ԲC5k GhSK_ep~.N, j՟ėqϫsܦ2nմeвCfܔv\pyƭZlU] io7bXOM"PN jfҜkݚv'q)~ #9et́Nwtub5O3H'K0L8"z,EkbY$eWRtCףW`#:9dAO[[q{52 <1}M%aȘ :jS߿9o7>x+V`xE wgOO_K?{/5@Ff˩O^unF AkK `=p.8:2EYewoV]VPng`&(Ej@kԗw%|Mt5GD _ GsNz7ڷqN"I/l{pG">C yD GA@WAEf c$p>s !# ( HSNpc_]vy;|,^,rNJCcDDag9w~O쩚f{ZD/OO\8={Y3/ښ nP=~p_35ՎR3u֮)tR@EA(Mf>>i ,J;!Iyanѷ@Tr\{^׋GACLX^ hubDcUMB!1E[x?%~={ц?| ɀi^Eo/YپOY|c`i^W,& >ĘTVb#7@e\JN93%C-mVTg?i) CEUN{5VCBGv¶&ij\;7>d)d`dLԁ8afJ,9ag/Tj0 ob΀{}[߭[+ IO,v+\]6c'`Sb 5v1gHiRTtҢe0J̶&6u !CQO$S@pq" mɌ8 #kimh;Zp~7sGm/\F; 5" k{Ң_`<ЩS0!ʭ1Vu}7i#_C__@us6 9Iid6?K RC~rQ{`tjֵUMhg/(*sLTbVE+L-_2t "ҔDMPYAM&J  _KpT7krBkF~WDŽ:'gVJ,DB~}JYM߹ >x+](1~~ бu 3_m|7ysEc;M|Eڸ |T] *z(×]2IM -B@kM^%.Gv@\tꐣ(HhkX}֨Y9 RׯL| }+f @w !HQ'x׮[]0o?x~juWr#qJB]E j-S:%hR@ppsipw23 RHB)!JmD$0Cd'M0CDYS[\MD~>k'<(U%@/ X>CiΎ~U{X78Ĝ~5sb5&!Hg.nwwݯVxgxWW`1z%[Kw&ҼJ]>uѨSW{DxD2N2V>j}tXʸG=8;WuuS;#.f6(k˽ŭɵ)Y akBY |jH(3 RΜ`?9^z?ª 2&jv7xm]Xe'H1՛,@H'dD )uf:d(,"4=:1L "b5Pa]DwA毉~0'!tV$`n #w듡/Wp"+wB> \LꙖ3샎~t59 9`M]ľo{ +x -y@.?*ۇ; :;IbKh^%vWn=/Yilhij5 ,7W@ @4j@ %Pi(γP2மNZ nM[d&2S{QO=\[l.hH/zX ekVY }g8M XPH{ %<`P^:4@ɚQ* ^ٺ*) -{v%0h h%eJ &YpB ] itipb6ʈ4fy-4F'&P!|Hy VȌI=:+s\p<WB^ v]x+K+@gK% { mUn}߷Z&g$j-/-&,se z̶Qɱ)WY}Q@]́B2Y|Ԯr?I9!0WUyķcfJ*9 _GmCֵvmڴ󕵏ВXMr4uVBa|r^~Mx1)O_p޶ܵ'ß)09s"`iVAڅyC@?>daיp К,/B#P#6ˌ.-CZwv3GdLS#3D'P/ d=QeA!ㄗjILi@S f{i;~@L~X?ʷPqW?R *+VV,3w(/w=R:?zŦ L#',2ժ N TvYĀ2)^esI1V&i4Nv g1`0KvIz%@(GG=>#4m;=W59 P*^ʾY z`G>G}⑇8c'ɨl}K cWCu *!$T Ӓ7P? P 滮djy/1!.<> A@>w 狆kaPcV >~]nBB%rmً.k~tͮ \{zQH.{SXJX_u)ʿ.#>7Ry=nK`#G/Q Ů4"ӠjuAb)(}yy5G ];?\9צ6{k ;}͊W08JYfAKc6OPN]A@/|gon f7X=~{ @[=r mum@{7uneKYŤ'a^ 2Vc|MӲ9|c8.yW1޺}Kd--680hC4џߴ.;}A> aqހ+` "c8}s>Ͽl{v3LKIKph'? w7272~}ֵT(s/#7\l6 Bv +HZܨ^ HL }*U ^HWP|d+_ydM5Od]k2ePmgKSC'pLk}7p-_P,TNkooUM?(}v)<zxlbm߼Ƨ&mzykVD_|Ź>xzleU0 _/;}GX3JkyΚ1p @2& Z{ਝL@)ur]{#+8&|Ҡ_ XW)ESY[Ϩ__92x2xc*drΓ5? K?1ɺWVT7`:[!2rȧ Srt>+fAn [X #xH\UoK$=Q^@]%g`>0Im.\&Kx 5N'// %hW,79eMuGh dR`$iSZmH\'Vv̢!Pv!;t=$Ó'FXg^3߫a~z^RS`{=WK(uS}vV;㳀߽V%Ez_&F 2)k َMM,S )\%22n(ֵ$c֠`LܖJ'8BhsC7I?dhx L*b8gOz_`]{+p'޻}=*@6 cYYqTTҩL`@HK Cxȧ?ZZԔHNdڵ~W21ׯ !>X+)# j[Eתv7 2M?p@om6`]({:C3hބ@^)x˃@mg8t.A%'T*U2N@iL~Z=;ZqW(b fG+кGD zaQS#Og@$q7gvB_@0imGx͵~M Z |_mW=;}V]'`Az~FgV=듈͋zW xȕrpd+Y:E&ɄFcad&ox܁zEA'˱O`=P͉ZZgW{YyV>Dka|>p˴*Jup?:8hWȑCmbd.^q k\|RX`>i/GNREAO-vڒ H)(P;WbP Nǁ?וI[{Cvn:p8DDA8,{Fl m /1n~!0iDD'Yy|P9 ^?1't"$p af!D@QB5MP [5o}~᷿UzV_i>7=~heKGawIMS'5LG٬' U"< nP91䢤 ]YvA\}}=4U <|cj\^q6F_ XnvlhGt@S MOb@2r ?m߲a=rN:\_g'1pO?\u(VeJ W{DnB5.aq\ȸ"]kȦ'H][ڱ)4x?I4RJ'\7X]'>To:(sHG3LDT;f}MNksrēk& B>Lsjׅ{iч/Hy3o=_Y x+a_/w+BDXf'瓎>?GRVdy,o+^~v.Nͽ?ؽsOz3#Vg}4_rZɌW9{]:$g}{mrq/ڷʞ9NbVS28} "a!;~$@_+vB3GC@Ӽmr*,a:B-/?V/%JXA>j CM#@ eD$t'"n 47e@Cs/ ˇ̀%1wK7K+$V\#F bı>?Cn x+܂`}kii_1qfYlKP#f[]2co4VZE -XlAt  eϛ&.G"2߲j+M25m5}&F6dtvnl~OV71id'?# : Xt.%݃__ \?;o0:w6t b1$g\QٯkMBΡOӾ2S Ryj6A Kf5,*oaCDN[Pҝt aPˣ_F>C% voRDsӚ󠏵ǘ*0\` >[ 5g  x+mX>o7z6M/E,VFZ5I?~ k0r Y2He48g @QPB s]sd3I"E %RT%Jk lώǞس{v̮9;x=dE[EQERD6C3wSuT},)UKdKt}}߯&U3fWa<8*_wi wnǩ!$$Z=<uNS)|wﱏn8vagdogG)cmjj}Qޮ*{ lR$cU]69y.M6G[A/I?]wU/B5 .0A0]/R{oeݮ TFgxWC= &/MRghT62bk:F`  Й)۲~-zU9v _ۂSvh% zKxF?F[@}tR``3Y'J%x_ej(&@-m +s J zaΓ& ΉxlBYD~: bL%_?~"0AA~=Z@`h øK_kS0@9U6WcG\uRᘜ?ŊWQ`-o{结ww- s~le6PiHV`cjH ɽ=ұ}z1(fW2vV\t B_\R\cidqu6K: ʙLWB ݮbEmM 5z#XS t% GBs7 C菟`dqvl=NXZ;qj؎Qٷ47#'mt|)N+W_]8U@b?RüC1!fG.OhA#II:FwF&:,!3@__!!(#xHpy[FW;$C>"ibw}c)=t5 x+${ˆ?Vճ[@H*[|S!l* 'cϭ2w"~eyg9F$DZ0p+M}r.)ie!DZ1 P Üx\-V]EK3 ^<>N?j]9g?O` ?J *(f+XQE+h6v7l}}$i5{U7v@tvY `b@n=K[[iX]k8rdq0*\ԤN"f#! 5xG(ez xMd? \c81w.ԫCϭҘ᜽x(A]^Cov9I|Yr{>72d]s94F8gW!P[b;- 9ler~9sS:4PkW+d+;`,)Sg[43Η<@Rm} ,sX [$\D~d3m+(QK059i4ִ>(fѯ5OϤZ0*;jg9Hnw 7z~Or *Z(-Š/);8?PT{w~GWܺksNVuב񫕠L{'i5ԒK޷e:,HZ06bY_Unq~%hlD?@cY?EM;O²AA'Ica0TISV }zkbV[[[ta.zKQEW HSO]G5K`r{@;fn޼n\g{ Zm݆kmn)rB=abɊ,4w"=0 ǏcCMp=h(hCZiC12GU ;W(x0w_Oxy_埑o<W`B' ,+yV-k@>X=ľYL UDٗ\sj4:䌒d:iqj;vܺQÁc/>3Ճ8 ᭆ V2ٮ][bINwng @{SdzNAzmzy9J)kڿ6V ܺiBFAnLZk+,J @8 ThSQqm 4h!a-X지JDlƚpNǀYl ,[R+Oy (遟חӋ Oو[QcfaMA0"8rǎS.JԳNۿ3L{獠齯@>c! P%@Ȏە]L}v̶mO=$n8SeCp NҸ ԢR֏`3A G=fCx"?$Qf'dkt۞;x99m9e-j%uyyP8ʁnT@NyYH˩,glҡY&w ,Lk,Pj$AFJ!a%F&w,'U20=?2sM 4`Jz9Afi ibxһ>ݗx-p-(ec؀i[q 7,kkq>% Pd|ҋAӇl.~@7jdd! Ed= Om[]p̛6>*`OSV࢝>iCJg1E>wq(W@EOo^ 8whL- M$~X T<=mm\wDf .B%JL^*YR~O==69N')U/"P A9:&y\Y{N. \-ANvY޳ wP]_٤m..J&~lɱɉIþ 8Tz! jqMT dMmm;~1T߿v2_]N;m sN,@vD>EknjGA 9 өI۱uWx=T$'뮋\ *MnB uS1 Ax3LBd,ՏCklߣ">)$i*zR󟚡ZPQem~w-paYXC {&gy^,Vΰx0+ٽgA_Bh}8vC{_φ,/?g j|p>HJC"YhUrh8ei*۾ס?`w_z أitcsT8-![)_b .g^})D^<ࠉ9lj'Ns\s۷9.d)WL^7mr!JaxwW^`•ٕuLbj.nU#)>5"4X/_z Tci%ܲ Pܥ[Igp8q/g 0* Av+ A~a-o]w٭|r]zw,P ĩ^x_3\`^qp:`+ 88b=Օ|J=ߎ:WչK첾^{vȱSvLǩAL9*倠{n{qnc*AL*U8.vDlo{DWǥ@ z4*qҞXBxi/f;Omh4?F ;AO_@?~z#Ιw PQ ElokVSpH=2H',RcLU MqC=aqKVM p~&vW/-pZyy_dɮgn鬲}+pU6 nq6 %1ӎ E+Z Gj[.]pp18vS#d=G?goz{{нO@@ߞzY χNG}_= KVT HN_PBKGC)TieX;71 i gno!"xIDxf4=0! 0q#/ % j$N|*$?5cG^< ]ak֮ ^`;=A{Gq@H(af0 `Cc3 Fw ăM}T P =&ipij y<75$O^>8Lmט.} 1"qMzjkiXI/RrT@E2}+KF`݅QtT)thMW`$o~. V 3ܿD[7) / XXoڊfM x!p硨-Q"-G o|ע(޹&p==]܊<.}n{K_WTkmtˈ5WԸ~84A:Uҿ-߽>*&"Y44h|aT(SEdTeݒ JZ2 _/Ԉ翾+*bôdwSNf/{voGAо  m8{GP8TЂG E;ںk_N?%dί#lH2<6Al D"vr|:zgMͱ@!sVJ~w"T.ݧUܹ286_,|9R^wq4m@6fNoo"ۯ+.ȞxWP3'9wւ,B>mmͶg6W! FI^N{}9dN\G ;t̴f+O{+ PW[5pAW5Q@P9ĉGN؞-] Zf/VYeCC#nq52ڶo䤋'^hmn@B(3J/d?Z)F8꣮[L:cب*%i[?[78 9Sp Q+Ůa,Zq>M6‘q~Y4罁} {^ V_^8' _IVeo 9&.fB6? +uq `>lQ랄@#,[6yl1Rѓ ҹ2dH>o?q#QJy£˩*cК/fA,d0_ ꟾW ]U-ʂN;zm z#eXy ^~UV<TW9Kj*9ѾmMQC?@֗v۷n1@  14ǚb882mMcl;g--kRq]>7temăמ?dhh̔Ej 0b)(QcG~m_rt{gu0-qY/s?#_g^'GQ0oOB>.Q]!ewRPؔk}NVw%Cc0~9v;bA|ꙃh AMiGx r <Hҏf=jq 'O6cLJaER1ś;m&/&X EdqQgedLc%(r#F@&p BY[cmIz9 I'lrv.ھgshm *fP)h5T[C{}skm5~GPanX 3]ksNmy{e4ǜ$a$rvؐC;JU >Q^8|2 QƯ͉.hsE?-Oٽ)s/1sQs$У^8~fzT}m"G8 1PC'Jbe% Pݗ_]mky(ѭ*ENOf轤 P8CSG;>?~<{j];Ԣ`J.xRta:oT\K8-@B/tã ,0~|'~ꨳe@bL?h MY!fjP@B7I|fv8nzʈ{Grtv8n}qܥoP2cmP6P615O≯>]LuU&ӛA?j!T ( { /"3;omB7d@F8=23Zr&ɚz5z=;2{ pqڅS dK_Zپ"!\_**+A@Q"2kD}S3;y \p[wM!D:,s2Ŋ@`rnxsY}5\Qsxյ@>aOw(g ן)>!uw#cӔ9rҪ3 5. tTA2&-q%[NOT)?-v;S^NZYs[XN?-vQ{UWn O8Y/tC) JHha 2AI-Xl#ԊBe 250'n}T*ZHEJvpD✧ tuk窛_|p~pP_v'ΰ^qw ,o-Ի~d{E+R `%=9eww@e4GqeG@L;)@X<d8KUexaB#F}"Sƀ2|WgЏxAiG` ۶-fI`T*mm_U29?A"<UTh$̺@A_m o# Rʄ .U/"AG [b Eܹn}?mjW`---lm~;, 3{UŁpgѲ߃_E ~oO'}jzK ~'6hhU3x~` rB+{mo^)Od u8Dnf?v}?vehh) IDAT_qY6_ܛAt[G쑧ddzmVS,H@b2edž.ygR ATl8U*Ai \tv0ٯ44x?42Z UiG_ _@zkjluAn7ۭ|]܅;oooY`?>)Z/ %8F`` [W8wy`)|uY5'Nuǯ‚ovcrp ؃SjoR?` F֓_7 3NQ~ˢZP.g8DS @:9;ȏ}/1r<D Bר(dT9~;8x SsF\ZFxN+!(jMm,*jߺAUs3#MοIX2B6n[?FU,PL}t9Oxj],OQ^m@EOk Ǹ`N:>d| ǫI{sħR 'P /)e'(sވ4.PQG߂2|g_|Dt5އl"OrѦvާiP#;=9j豵O!)ZR\K__%Ӱ ok}[[,W0k)4J/T@ԮWo[qsMX?N`&fiՔsihqk49D$qUTnΕE_+N2>>z1*oxH$dr!qe% yڜ' ";^&}AE bWwԹ1#Jl?ЦM @([+l */ڽ{HOu0Ԭ9D8r5X~a-[9 8"4X󯳶f9mG?D4^㝿7ooWRB^ׂ?U\1@kĹ[&B.QN3`&Ӗ'cVVA}?_"U@v?l*t8 z~% dabȱ{j}h~U^Y(Sv[]e;U(Zot6cO>wǒ8%kDPe!e+Wudh a^3*Z$7\ P[2 L'_3ڨPHgygqv~Kغu__H`?UV\!W;!gZ 9晜"G'_AW PVV* ivoj/Y/A9ǚG;`A[^!_`@@<%9UD+0o~[{izh0w.i-Gy?JHPZ[\%C>$ `K#8IG qyH!#~%2BZamrSPcօ.pZe/cr_8ktϰgx^qUz ?.d,N<Yx8uu/Y} ɑQϺLs,-n@Y?\~zQ,LSyU-WP(WL{"h8"IػA"vo Y<4(m b !E]j>Gkww+ Y^sbWTlM8VH2v vK#NWKY<4@7ho>/I* ! "X\?CP J.L?J-|j!cWz` i9 i`}zwF6$)XEy~}EZdxh3k 0U) ׿]*KPCz!'ԍ^@%-4]{/} >3;ooXñb ^}Y 3,ipŊ@ $@$^r }'O &?o->O~JWJBW-|MI27D>yN X0*!̧f9#aZõ#}{{isY}o&PƿaZ/ㅴn b@m Y!p i~F־ & jM9fkׯ 7<}9h 7\}Y*mK T?6|0}\*&Zt1Gml_ 0 q{.>?wR6?VbP6BJ^}MY0~z`wV\KE[I9"Ι6N/9' ޼u16fvrΙ-ɘE#t ˑ`0jRp]/@ym* c}GPHb|jx˨DA_g͠Ƨ> ljtUHXb@ m29a=~}Ӕx<|m(V م]k/Q~/g46˝[kXl,n+pUD_We鯇(S8a)ϠD@Gop߼.!R'Guh^xP\EcP@uL+3RAAQ膣.Џ5͓bwr"iǬEX'.g kzY* z?@gZBh\Oa!ukmԔ-?S%ٹYk'e QE_W-p[?x|k4;3 fm6Ri5jAptK!e9M|/ǟ!:OR ^y67D?e8Qad rv|Ȇ9K%[;&?ʑ5YB+'ZlZG'_ɘ6PhQVTjdTEqFWæѢ̰Z%lhm@[28\u{/[[,-ͫ;˵h)Z3Glґ+~@ŗB<Y"tBuإ첇|~~#`pAx|^\?Qa1Jr/@@0!  ɟH0a/m{Z/)~Ly'^kJPǀ$@>QF>t+)7/ C π wj>{ ujDrޝ[ Y5\7Gyo ":*sZ 3 !s7/*)W&t?#MƹٯJ.W a<?L=0㋅r+^:`=:gW㶄؏0j>u,Y;dSsdYOQ0PEf#%R9xGւ%W]}m۶;\B2O0Kw<ᣚA`kz *1T&4jxI`F@0ΤB.ĿyF *B_w;-$@$~Z l}gwoo@jWO9S,/Ô~uqiY&gH(걎V۩#4ה'O@(t%ry{N!̴w`$LqGt!I6& -\y\uL[1TkQTYU?%)XVmtp *v<[}8BKL'GC((@&t=A2BN @-VӮ5,\E~կ a8Ų("BL(7 5d`9vod9h| /'բ\` ӓi}TO"4P_g`7OC|su?Jvoo$ Msϑ  hY>^ 4`X@m!-sEKS \~<7(FksNs [yie!%cVW. v=Zʊ2Bq**TP[%iF9T*X,/bqQ 5J}==Jqr2s9vj25L_@mz ~9w1D[ׯ~*,s=xӝqSȕ1,(ksP&44ypԈv:i6D} S0 mb'<-h/ g2~tp㚾>~RBp TDkf6 H@h|[n y>P--pN-y Ӟ4g[/-0Ø$n~~Y|@%.S-NQ5rΐ}!gϾ!pyFKP`m5@@U)(8qzN.& DiIE6bMlr.cmdP]kMOپGSTUs}uh7=5KrSe#~zuƅ(P< 믵6(k69zWvz x *@IK~.d {\S)|sSn؍|K}d_Cfe+=M>L0} &p=x/&QK̂ L;zZ"?Iax ѥ:>:KG.<>ιcF;x "G ?i -ohlXюx -U a $$u7պGPow}V>EOoo_  fW:V\c1AMzU%9nU~H^{^k1sdb%@i ONXb[QP?ՅD`cz򐵷[SSt][\@{⢝ݹ4а6ztk]q`v\xr,B5i,(Źf1 o~+8?{x% +9|N`T3W\$2Z&ˍ6-hz^5zS1Rkkc/U0>Vh#on!#kDplx##>NB()R:P$au`6b+>~{ۻ>&`Ca_w-- P_5/MrFB/,?OJcmZЊ6|1w(^Nm8͖%Ȭk~}G-Ǯ>F]2;Uw='= G$H(#*t~k-@㻈REٌ٩cK⹂k{]N;B lrjiM4T[h~$3uw`D{DOG(CRkj\"-nH""ʁM {x{S&ڝws릝U=9PT.I6_eܯT ,|w[tn5x[/O9:2 kl"u|N@u@2i_oG}SrJӚ䗱X5)pbqG7H}oooog]x}?>^k:ѐM؉#^ 3@V̀$?>X P{*_ӎc_ryC}RV9M%3s0oy[@G}g9My6{Aҗ $Lh-rijWUH_h}cv[n{ x x x 9⡿/¯?3 ~M$jdS5( P_%TFl]S'gl ~gG;hy׾2 8ub# DxSE@ޱs=EƷ~尌٘2< іpgUUUF?ߵ]6@Зɗş[[[[U9*~ꆛb͚*|cl|e*đC7BY:C )6[kԭ=۝@l{Tהp8Jڥ^b#(BL_Pܹ:EU0 ]>oa9[[[[°_-w}8 ݷZTry hw"8koycw܏4q@&e<,/N?ZCן!F>o=>vyhsw Z @{Ɨz{,Mi6 C ^Yn >uLbIN_M=dV-^̥m!]yO%A-(64P Z+Vfl=-T ӽy x x x x \`X@.-_}!_'yĦp kmu:NNYU>j˭? asăn_zđp-10P96.+콷~Ҫ_O<?[[[[[Bl޶Fb¬x;19(x*5-nfYǬ @8`8o `5T *? !{$/[@7W   "@a9 pN ʣ1kn밝{.^ٶK; -----lUFw_x%?R]#6| 8dNt20RypmIM? ! OeV\pV@ry HTŭjQ謱Mm]Vlg*jjww~-⟅ۻ|Ċ;A}}ZbP*X9 ĢV 8^TU3 0/L1_DTދQ/1-XjJ~ȃK-----pN-P,"_+@:y  Kۊ;3AnB,n^~c1[_3bϏ DLgx>mb:^5­{ x x x x x N8:^,v^Li?DŽ}XyXovm9==>{6T,G^bIENDB`icnV Ctqsl-2.0/apps/tqslhelp.h0000664000076400007640000000106312231073120015305 0ustar rmurphyrmurphy// Derived from wxWidgets fs_inet.h #ifndef _TQSL_INET_H_ #define _TQSL_INET_H_ #include "wx/defs.h" #include "wx/filesys.h" // ---------------------------------------------------------------------------- // tqslInternetFSHandler // ---------------------------------------------------------------------------- class WXDLLIMPEXP_NET tqslInternetFSHandler : public wxFileSystemHandler { public: virtual bool CanOpen(const wxString& location); virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location); }; #endif // _TQSL_INET_H_ tqsl-2.0/apps/tqslhelp.cpp0000664000076400007640000000536112231073120015645 0ustar rmurphyrmurphy//Derived from wxWidgets fs_inet.cpp #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #if !wxUSE_SOCKETS #undef wxUSE_FS_INET #define wxUSE_FS_INET 0 #endif #if wxUSE_FILESYSTEM && wxUSE_FS_INET #ifndef WXPRECOMP #include "wx/module.h" #endif #include "wx/wfstream.h" #include "wx/url.h" #include "wx/filesys.h" #include "wx/utils.h" #include "wx/mstream.h" #include "tqslhelp.h" #include "tqsltrace.h" // ---------------------------------------------------------------------------- // tqslInternetFSHandler // ---------------------------------------------------------------------------- static wxString StripProtocolAnchor(const wxString& location) { tqslTrace("StripProtocolAnchor", "location=%s", _S(location)); wxString myloc(location.BeforeLast(wxT('#'))); if (myloc.empty()) myloc = location.AfterFirst(wxT(':')); else myloc = myloc.AfterFirst(wxT(':')); // fix malformed url: if (!myloc.Left(2).IsSameAs(wxT("//"))) { if (myloc.GetChar(0) != wxT('/')) myloc = wxT("//") + myloc; else myloc = wxT("/") + myloc; } if (myloc.Mid(2).Find(wxT('/')) == wxNOT_FOUND) myloc << wxT('/'); return myloc; } // // Simple filesystem "handler" that notices full URLs and // opens them in the user's default browser. // // Always returns an error indication so that the help widget doesn't // think it's actually been handled. // bool tqslInternetFSHandler::CanOpen(const wxString& location) { tqslTrace("tqslInternetFSHandler::CanOpen", "location=%s", _S(location)); static wxString lastLocation; #if wxUSE_URL wxString p = GetProtocol(location); if ((p == wxT("http")) || (p == wxT("ftp"))) { // Keep track of the last location as we get // repeated attempts to open - only open // the page once. if (location != lastLocation) { wxString right = GetProtocol(location) + wxT(":") + StripProtocolAnchor(location); wxLaunchDefaultBrowser(right); } lastLocation = location; } #endif return false; } wxFSFile* tqslInternetFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location) { return (wxFSFile*) NULL; // We never actually return anything } class tqslFileSystemInternetModule : public wxModule { DECLARE_DYNAMIC_CLASS(tqslFileSystemInternetModule) public: tqslFileSystemInternetModule() : wxModule(), m_handler(NULL) { } virtual bool OnInit() { m_handler = new tqslInternetFSHandler; wxFileSystem::AddHandler(m_handler); return true; } virtual void OnExit() { delete wxFileSystem::RemoveHandler(m_handler); } private: wxFileSystemHandler* m_handler; }; IMPLEMENT_DYNAMIC_CLASS(tqslFileSystemInternetModule, wxModule) #endif // wxUSE_FILESYSTEM && wxUSE_FS_INET tqsl-2.0/apps/tqslexcept.h0000664000076400007640000000162712231073120015653 0ustar rmurphyrmurphy/*************************************************************************** tqslexcept.h - description ------------------- begin : Fri Nov 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslexcept_h #define __tqslexcept_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include #include class TQSLException : public std::exception { public: TQSLException(const char *msg); ~TQSLException() throw () {} virtual const char *what() throw () { return _msg.c_str(); } private: std::string _msg; }; inline TQSLException::TQSLException(const char *msg) : exception() { _msg = msg; } #endif // __tqslexcept_h tqsl-2.0/apps/tqslctrls.h0000664000076400007640000000316712231073120015513 0ustar rmurphyrmurphy/*************************************************************************** tqslctrls.h - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslctrls_h #define __tqslctrls_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif enum { // Menu items tc_c_Properties, tc_c_Sign, tc_c_Renew, tc_c_Import, tc_c_Load, tc_c_Export, tc_c_Delete, tc_c_New, tc_f_Delete, tc_h_Contents, tc_h_About, tl_c_Properties, tm_s_Properties, tl_c_Edit, tl_c_Delete, }; enum { // Window IDs tc_CertTree = (wxID_HIGHEST+1), tc_CRQWizard, tc_Load, tc_CertPropDial, tc_CertPropDialButton, tl_LocPropDial, tl_LocPropDialButton, tc_LocTree, tc_LogGrid, tl_Upload, tl_Login, tl_Save, tl_Edit, tl_AddLoc, tl_EditLoc, tl_DeleteLoc, tl_PropLoc, tc_CertSave, tc_CertRenew, tc_CertDelete, tc_CertProp, ID_CRQ_PROVIDER, ID_CRQ_PROVIDER_INFO, ID_CRQ_COUNTRY, ID_CRQ_ZIP, ID_CRQ_NAME, ID_CRQ_CITY, ID_CRQ_ADDR1, ID_CRQ_ADDR2, ID_CRQ_EMAIL, ID_CRQ_STATE, ID_CRQ_CALL, ID_CRQ_QBYEAR, ID_CRQ_QBMONTH, ID_CRQ_QBDAY, ID_CRQ_QEYEAR, ID_CRQ_QEMONTH, ID_CRQ_QEDAY, ID_CRQ_DXCC, ID_CRQ_SIGN, ID_CRQ_CERT, ID_CRQ_PW1, ID_CRQ_PW2, ID_LCW_P12, ID_LCW_TQ6, ID_PREF_ROOT_CB, ID_PREF_CA_CB, ID_PREF_USER_CB, ID_PREF_ALLCERT_CB, ID_CERT_OK_BUT, ID_CERT_CAN_BUT, ID_CERT_HELP_BUT }; #endif // __tqslctrls_h tqsl-2.0/apps/tqslbuild.h.in0000664000076400007640000000012712231073120016061 0ustar rmurphyrmurphy// Define the build of TQSL #define VERSION "@TQSLVERSION@" #define BUILD "[@BUILD@]" tqsl-2.0/apps/tqslapp.h0000664000076400007640000001310312231073120015133 0ustar rmurphyrmurphy/*************************************************************************** tqslapp.h - description ------------------- begin : Sun Jun 16 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __tqslapp_h #define __tqslapp_h #define TQSL_CRQ_FILE_EXT "tq5" #define TQSL_CERT_FILE_EXT "tq6" #ifdef __WXMSW__ #define ALLFILESWILD "*.*" #else #define ALLFILESWILD "*" #endif #define MAIN_WINDOW_MIN_HEIGHT 400 #define MAIN_WINDOW_MIN_WIDTH 575 #include "tqslconvert.h" #include "qsodatadialog.h" #include "certtree.h" #include "loctree.h" #include "wxutil.h" enum { tm_f_import = 7000, tm_f_import_compress, tm_f_upload, tm_f_compress, tm_f_uncompress, tm_f_preferences, tm_f_loadconfig, tm_f_saveconfig, tm_f_new, tm_f_edit, tm_f_diag, tm_f_exit, tm_s_add, tm_s_edit, tm_h_contents, tm_h_about, tm_h_update, tm_f_autoupdate }; // Action values enum { TQSL_ACTION_ASK = 0, TQSL_ACTION_ABORT = 1, TQSL_ACTION_NEW = 2, TQSL_ACTION_ALL = 3, TQSL_ACTION_UNSPEC = 4 }; #define TQSL_CD_MSG TQSL_ID_LOW #define TQSL_CD_CANBUT TQSL_ID_LOW+1 #define CERTLIST_FLAGS TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_SUPERCEDED | TQSL_SELECT_CERT_EXPIRED // Exit codes enum { TQSL_EXIT_SUCCESS = 0, TQSL_EXIT_CANCEL = 1, TQSL_EXIT_REJECTED = 2, TQSL_EXIT_UNEXP_RESP = 3, TQSL_EXIT_TQSL_ERROR = 4, TQSL_EXIT_LIB_ERROR = 5, TQSL_EXIT_ERR_OPEN_INPUT = 6, TQSL_EXIT_ERR_OPEN_OUTPUT = 7, TQSL_EXIT_NO_QSOS = 8, TQSL_EXIT_QSOS_SUPPRESSED = 9, TQSL_EXIT_COMMAND_ERROR = 10, TQSL_EXIT_CONNECTION_FAILED = 11, TQSL_EXIT_UNKNOWN = 12 }; class MyFrame : public wxFrame { public: MyFrame(const wxString& title, int x, int y, int w, int h, bool checkUpdates, bool quiet); bool IsQuiet(void) { return _quiet; }; void AddStationLocation(wxCommandEvent& event); void EditStationLocation(wxCommandEvent& event); void EnterQSOData(wxCommandEvent& event); void EditQSOData(wxCommandEvent& event); void ImportQSODataFile(wxCommandEvent& event); void UploadQSODataFile(wxCommandEvent& event); void OnExit(TQ_WXCLOSEEVENT& event); void DoExit(wxCommandEvent& event); void DoUpdateCheck(wxTimerEvent& event); void OnHelpAbout(wxCommandEvent& event); void OnHelpContents(wxCommandEvent& event); void OnHelpDiagnose(wxCommandEvent& event); #ifdef ALLOW_UNCOMPRESSED void OnFileCompress(wxCommandEvent& event); #endif void OnPreferences(wxCommandEvent& event); void OnSaveConfig(wxCommandEvent& event); void OnLoadConfig(wxCommandEvent& event); int ConvertLogFile(tQSL_Location loc, wxString& infile, wxString& outfile, bool compress = false, bool suppressdate = false, tQSL_Date* startdate = NULL, tQSL_Date* enddate = NULL, int action = TQSL_ACTION_ASK, const char *password = NULL); tQSL_Location SelectStationLocation(const wxString& title = wxT(""), const wxString& okLabel = wxT("Ok"), bool editonly = false); int ConvertLogToString(tQSL_Location loc, wxString& infile, wxString& output, int& n, tQSL_Converter& converter, bool suppressdate=false, tQSL_Date* startdate = NULL, tQSL_Date* enddate = NULL, int action = TQSL_ACTION_ASK, const char* password=NULL); int UploadLogFile(tQSL_Location loc, wxString& infile, bool compress=false, bool suppressdate=false, tQSL_Date* startdate = NULL, tQSL_Date* enddate = NULL, int action = TQSL_ACTION_ASK, const char* password=NULL); int UploadFile(wxString& infile, const char* filename, int numrecs, void *content, size_t clen, wxString& fileType); void WriteQSOFile(QSORecordList& recs, const char *fname = 0, bool force = false); void CheckForUpdates(wxCommandEvent&); void DoCheckForUpdates(bool quiet, bool noGUI=false); void DoCheckExpiringCerts(bool noGUI=false); void UpdateConfigFile(void); void OnQuit(wxCommandEvent& event); void CRQWizard(wxCommandEvent& event); void CRQWizardRenew(wxCommandEvent& event); void OnCertTreeSel(wxTreeEvent& event); void CertTreeReset(void); void OnCertProperties(wxCommandEvent& event); void OnCertExport(wxCommandEvent& event); void OnCertDelete(wxCommandEvent& event); // void OnCertImport(wxCommandEvent& event); void OnSign(wxCommandEvent& event); void OnLoadCertificateFile(wxCommandEvent& event); void OnLocProperties(wxCommandEvent& event); void OnLocDelete(wxCommandEvent& event); void OnLocEdit(wxCommandEvent& event); void OnLocTreeSel(wxTreeEvent& event); void OnLoginToLogbook(wxCommandEvent& event); void LocTreeReset(void); void DisplayHelp(const char *file = "main.htm") { help->Display(wxString(file, wxConvLocal)); } void FirstTime(void); void BackupConfig(wxString& event, bool quiet); CertTree *cert_tree; LocTree *loc_tree; wxTextCtrl *logwin; wxHtmlHelpController *help; wxMenu* file_menu; wxMenu *cert_menu; wxMenu* help_menu; DECLARE_EVENT_TABLE() private: wxBitmapButton* loc_add_button; wxStaticText* loc_add_label; wxBitmapButton* loc_edit_button; wxStaticText* loc_edit_label; wxBitmapButton* loc_delete_button; wxStaticText* loc_delete_label; wxBitmapButton* cert_load_button; wxStaticText* cert_load_label; wxBitmapButton* cert_save_button; wxStaticText* cert_save_label; wxBitmapButton* cert_renew_button; wxStaticText* cert_renew_label; wxStaticText* loc_select_label; wxStaticText* cert_select_label; wxBitmapButton* cert_prop_button; wxStaticText* cert_prop_label; wxBitmapButton* loc_prop_button; wxStaticText* loc_prop_label; int renew; TQSL_CERT_REQ *req; bool _quiet; wxTimer* _timer; }; #endif // __tqslapp_h tqsl-2.0/apps/tqsl_prefs.h0000664000076400007640000001334112231073120015635 0ustar rmurphyrmurphy/*************************************************************************** tqsl_prefs.h - description ------------------- begin : Sun Jan 05 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __TQSL_PREFS_H #define __TQSL_PREFS_H #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #include "wx/object.h" #include "wx/config.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/dialog.h" #include "wx/notebook.h" #include "wx/checkbox.h" #include "wx/grid.h" #include "wx/wxhtml.h" #include "wx/filepicker.h" #include "tqslctrls.h" #include #define DEFAULT_CABRILLO_FILES wxT("log cbr") #define DEFAULT_ADIF_FILES wxT("adi") #define DEFAULT_AUTO_BACKUP true #define DEFAULT_CERT_WARNING 60 //online //#define ENABLE_ONLINE_PREFS #define DEFAULT_UPL_URL wxT("https://lotw.arrl.org/lotw/upload") #define DEFAULT_UPL_FIELD wxT("upfile") #define DEFAULT_UPL_STATUSRE wxT("") #define DEFAULT_UPL_STATUSOK wxT("accepted") #define DEFAULT_UPL_MESSAGERE wxT("") #define DEFAULT_UPL_VERIFYCA true #define DEFAULT_UPD_URL wxT("https://lotw.arrl.org/lotw/tqslupdate") #define DEFAULT_UPD_CONFIG_URL wxT("https://lotw.arrl.org/lotw/config_xml_version") #define DEFAULT_CONFIG_FILE_URL wxT("https://lotw.arrl.org/lotw/config.tq6") #define DEFAULT_LOTW_LOGIN_URL wxT("https://lotw.arrl.org/lotwuser/default") enum { // Window IDs ID_OK_BUT, ID_CAN_BUT, ID_HELP_BUT, ID_PREF_FILE_CABRILLO = (wxID_HIGHEST+1), ID_PREF_FILE_ADIF, ID_PREF_FILE_AUTO_BACKUP, ID_PREF_FILE_BACKUP, ID_PREF_FILE_BADCALLS, ID_PREF_FILE_DATERANGE, ID_PREF_MODE_MAP, ID_PREF_MODE_ADIF, ID_PREF_MODE_DELETE, ID_PREF_MODE_ADD, ID_PREF_ADD_ADIF, ID_PREF_ADD_MODES, ID_PREF_CAB_DELETE, ID_PREF_CAB_ADD, ID_PREF_CAB_EDIT, ID_PREF_ONLINE_DEFAULT, ID_PREF_ONLINE_URL, ID_PREF_ONLINE_FIELD, ID_PREF_ONLINE_STATUSRE, ID_PREF_ONLINE_STATUSOK, ID_PREF_ONLINE_MESSAGERE, ID_PREF_ONLINE_VERIFYCA, ID_PREF_ONLINE_UPD_CONFIGURL, ID_PREF_ONLINE_UPD_CONFIGFILE, ID_PREF_PROXY_ENABLED, ID_PREF_PROXY_HOST, ID_PREF_PROXY_PORT, ID_PREF_PROXY_TYPE }; class PrefsPanel : public wxPanel { public: PrefsPanel(wxWindow *parent, const wxString& helpfile = wxT("prefs.htm")) : wxPanel(parent), _helpfile(helpfile) {} wxString HelpFile() { return _helpfile; } private: wxString _helpfile; }; class FilePrefs : public PrefsPanel { public: FilePrefs(wxWindow *parent); virtual bool TransferDataFromWindow(); void OnShowHide(wxCommandEvent&) { ShowHide(); } void ShowHide(); private: wxTextCtrl *cabrillo, *adif; wxCheckBox *autobackup, *badcalls, *daterange; wxDirPickerCtrl *dirPick; DECLARE_EVENT_TABLE() }; #if defined(ENABLE_ONLINE_PREFS) class OnlinePrefs : public PrefsPanel { public: OnlinePrefs(wxWindow *parent); virtual bool TransferDataFromWindow(); void ShowHide(); void OnShowHide(wxCommandEvent&) { ShowHide(); } DECLARE_EVENT_TABLE() private: wxTextCtrl *uploadURL, *postField, *statusRegex, *statusSuccess, *messageRegex; wxTextCtrl *updConfigURL, *configFileURL; wxCheckBox *verifyCA, *useDefaults; bool defaults; }; #endif typedef std::map ModeSet; class ModeMap : public PrefsPanel { public: ModeMap(wxWindow *parent); virtual bool TransferDataFromWindow(); private: void SetModeList(); void OnDelete(wxCommandEvent &); void OnAdd(wxCommandEvent &); wxButton *delete_but; wxListBox *map; ModeSet modemap; DECLARE_EVENT_TABLE() }; typedef std::map > ContestSet; class ContestMap : public PrefsPanel { public: ContestMap(wxWindow *parent); virtual bool TransferDataFromWindow(); private: void SetContestList(); void OnDelete(wxCommandEvent &); void OnAdd(wxCommandEvent &); void OnEdit(wxCommandEvent &); void Buttons(); wxButton *delete_but, *edit_but; wxGrid *grid; ContestSet contestmap; DECLARE_EVENT_TABLE() }; class ProxyPrefs : public PrefsPanel { public: ProxyPrefs(wxWindow *parent); virtual bool TransferDataFromWindow(); void ShowHide(); void OnShowHide(wxCommandEvent&) { ShowHide(); } DECLARE_EVENT_TABLE() private: wxCheckBox *proxyEnabled; wxTextCtrl *proxyHost, *proxyPort; wxChoice *proxyType; bool enabled; }; typedef std::map ModeSet; class Preferences : public wxFrame { public: Preferences(wxWindow *parent, wxHtmlHelpController *help = 0); void OnOK(wxCommandEvent &); void OnCancel(wxCommandEvent &); void OnHelp(wxCommandEvent &); void OnClose(wxCloseEvent&); DECLARE_EVENT_TABLE() private: wxNotebook *notebook; FilePrefs *fileprefs; ModeMap *modemap; ContestMap *contestmap; ProxyPrefs *proxyPrefs; #if defined(ENABLE_ONLINE_PREFS) OnlinePrefs *onlinePrefs; #endif wxHtmlHelpController *_help; }; class AddMode : public wxDialog { public: AddMode(wxWindow *parent); virtual bool TransferDataFromWindow(); void OnOK(wxCommandEvent &); void OnCancel(wxCommandEvent &) { Close(true); } wxString key, value; DECLARE_EVENT_TABLE() private: wxTextCtrl *adif; wxListBox *modelist; }; class EditContest : public wxDialog { public: EditContest(wxWindow *parent, wxString ctype = wxT("Edit"), wxString _contest = wxT(""), int _contest_type = 0, int _callsign_field = 5); void OnOK(wxCommandEvent&); void OnCancel(wxCommandEvent &) { Close(true); } virtual bool TransferDataFromWindow(); wxString contest; int contest_type, callsign_field; private: wxTextCtrl *name; wxRadioBox *type; wxTextCtrl *fieldnum; DECLARE_EVENT_TABLE() }; #endif // __TQSL_PREFS_H tqsl-2.0/apps/tqsl_prefs.cpp0000664000076400007640000007232312231073120016175 0ustar rmurphyrmurphy/*************************************************************************** tqsl_prefs.cpp - description ------------------- begin : Mon Jul 1 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include "tqsl_prefs.h" #include "wx/sizer.h" #include "wx/button.h" #include "wx/stattext.h" #include "wx/statbox.h" #include "wx/config.h" #include "tqsllib.h" #include "tqsltrace.h" #include "tqslapp.h" #include #include #include using namespace std; #if defined(__APPLE__) #define HEIGHT_ADJ(x) ((x)*4/2) #else #define HEIGHT_ADJ(x) ((x)*3/2) #endif BEGIN_EVENT_TABLE(Preferences, wxFrame) EVT_BUTTON(ID_OK_BUT, Preferences::OnOK) EVT_BUTTON(ID_CAN_BUT, Preferences::OnCancel) EVT_BUTTON(ID_HELP_BUT, Preferences::OnHelp) EVT_MENU(wxID_EXIT, Preferences::OnOK) EVT_CLOSE(Preferences::OnClose) END_EVENT_TABLE() Preferences::Preferences(wxWindow *parent, wxHtmlHelpController *help) : wxFrame(parent, -1, wxString(wxT("Preferences"))), _help(help) { tqslTrace("Preferences::Preferences", "parent=0x%lx", (void *)parent); wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); notebook = new wxNotebook(this, -1); // topsizer->Add(notebook, 1, wxGROW); topsizer->Add(notebook, 1, wxEXPAND | wxLEFT | wxRIGHT, 20); fileprefs = new FilePrefs(notebook); wxBoxSizer *butsizer = new wxBoxSizer(wxHORIZONTAL); wxButton *button = new wxButton(this, ID_HELP_BUT, wxT("Help") ); butsizer->Add(button, 0, wxALIGN_RIGHT | wxALL, 10); button = new wxButton(this, ID_OK_BUT, wxT("OK") ); butsizer->Add(button, 0, wxALIGN_RIGHT | wxALL, 10); button = new wxButton(this, ID_CAN_BUT, wxT("Cancel") ); butsizer->Add(button, 0, wxALIGN_LEFT | wxALL, 10); topsizer->Add(butsizer, 0, wxALIGN_CENTER); notebook->AddPage(fileprefs, wxT("Options")); modemap = new ModeMap(notebook); notebook->AddPage(modemap, wxT("ADIF Modes")); contestmap = new ContestMap(notebook); notebook->AddPage(contestmap, wxT("Cabrillo Specs")); proxyPrefs=new ProxyPrefs(notebook); notebook->AddPage(proxyPrefs, wxT("Network Proxy")); //don't let the user play with these #if defined(ENABLE_ONLINE_PREFS) onlinePrefs=new OnlinePrefs(notebook); notebook->AddPage(onlinePrefs, wxT("Server Setup")); #endif #ifdef __WXMAC__ // You can't have a toplevel window without a menubar. wxMenu *file_menu = new wxMenu; file_menu->Append(wxID_EXIT, wxT("Close")); // Main menu wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, wxT("&File")); SetMenuBar(menu_bar); #endif SetSizer(topsizer); topsizer->Fit(this); topsizer->SetSizeHints(this); SetWindowStyle(GetWindowStyle() | wxWS_EX_VALIDATE_RECURSIVELY); CenterOnParent(); } void Preferences::OnOK(wxCommandEvent& WXUNUSED(event)) { tqslTrace("Preferences::OnOK"); #if defined(ENABLE_ONLINE_PREFS) if (!onlinePrefs->TransferDataFromWindow()) return; #endif if (!proxyPrefs->TransferDataFromWindow()) return; if (!fileprefs->TransferDataFromWindow()) return; ((MyFrame *) GetParent())->file_menu->Enable(tm_f_preferences, true); Destroy(); } void Preferences::OnCancel(wxCommandEvent& WXUNUSED(event)) { tqslTrace("Preferences::OnOK"); ((MyFrame *) GetParent())->file_menu->Enable(tm_f_preferences, true); Destroy(); } void Preferences::OnClose(wxCloseEvent& WXUNUSED(event)) { tqslTrace("Preferences::OnClose"); ((MyFrame *) GetParent())->file_menu->Enable(tm_f_preferences, true); Destroy(); } void Preferences::OnHelp(wxCommandEvent& WXUNUSED(event)) { tqslTrace("Preferences::OnHelp"); if (_help) { wxString file(wxT("pref.htm")); int idx = notebook->GetSelection(); if (idx >= 0) file = ((PrefsPanel *)(notebook->GetPage(idx)))->HelpFile(); _help->Display(file); } } BEGIN_EVENT_TABLE(ModeMap, PrefsPanel) EVT_BUTTON(ID_PREF_MODE_DELETE, ModeMap::OnDelete) EVT_BUTTON(ID_PREF_MODE_ADD, ModeMap::OnAdd) END_EVENT_TABLE() #define MODE_TEXT_WIDTH 15 ModeMap::ModeMap(wxWindow *parent) : PrefsPanel(parent, wxT("pref-adi.htm")) { tqslTrace("ModeMap::ModeMap", "parent=0x%lx", (void *)parent); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT('M'), MODE_TEXT_WIDTH), &char_width, &char_height); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("Custom ADIF mode mappings:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); map = new wxListBox(this, ID_PREF_MODE_MAP, wxDefaultPosition, wxSize(char_width,(char_height*10))); hsizer->Add(map, 1, wxEXPAND, 0); wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); vsizer->Add(new wxButton(this, ID_PREF_MODE_ADD, wxT("Add...")), 0, wxBOTTOM, 10); delete_but = new wxButton(this, ID_PREF_MODE_DELETE, wxT("Delete")); vsizer->Add(delete_but, 0); hsizer->Add(vsizer, 0, wxLEFT, 10); sizer->Add(hsizer, 1, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 10); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); SetModeList(); } void ModeMap::SetModeList() { tqslTrace("ModeMap::SetModeList"); wxConfig *config = (wxConfig *)wxConfig::Get(); wxString key, value; long cookie; modemap.clear(); map->Clear(); config->SetPath(wxT("/modeMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); modemap.insert(make_pair(key, value)); stat = config->GetNextEntry(key, cookie); } config->SetPath(wxT("/")); for (ModeSet::iterator it = modemap.begin(); it != modemap.end(); it++) { map->Append(it->first + wxT(" -> ") + it->second, (void *) &it->first); } if (map->GetCount() > 0) map->SetSelection(0); delete_but->Enable(map->GetSelection() >= 0); } void ModeMap::OnDelete(wxCommandEvent &) { tqslTrace("ModeMap::OnDelete"); int sel = map->GetSelection(); if (sel >= 0) { wxString* keystr = (wxString*) map->GetClientData(sel); if (!keystr->IsEmpty()) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/modeMap")); config->DeleteEntry(*keystr, true); config->Flush(false); SetModeList(); } } } void ModeMap::OnAdd(wxCommandEvent &) { tqslTrace("ModeMap::OnAdd"); AddMode add_dial(this); int val = add_dial.ShowModal(); if (val == ID_OK_BUT && add_dial.key != wxT("") && add_dial.value != wxT("")) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/modeMap")); config->Write(add_dial.key, add_dial.value); config->Flush(false); SetModeList(); } } bool ModeMap::TransferDataFromWindow() { tqslTrace("ModeMap::TransferDataFromWindow"); return true; } BEGIN_EVENT_TABLE(AddMode, wxDialog) EVT_BUTTON(ID_OK_BUT, AddMode::OnOK) EVT_BUTTON(ID_CAN_BUT, AddMode::OnCancel) END_EVENT_TABLE() AddMode::AddMode(wxWindow *parent) : wxDialog(parent, -1, wxString(wxT("Add ADIF mode"))) { tqslTrace("AddMode::AddMode", "parent=0x%lx", (void *)parent); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT('M'), MODE_TEXT_WIDTH), &char_width, &char_height); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("Add ADIF mode mapping:")), 0, wxALL, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("ADIF Mode:")), 0); adif = new wxTextCtrl(this, ID_PREF_ADD_ADIF, wxT(""), wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); hsizer->Add(adif, 0, wxLEFT, 5); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Resulting TQSL mode:")), 0, wxLEFT|wxRIGHT, 10); modelist = new wxListBox(this, ID_PREF_ADD_MODES, wxDefaultPosition, wxSize(char_width,(char_height*10))); sizer->Add(modelist, 0, wxLEFT|wxRIGHT, 10); wxBoxSizer *butsizer = new wxBoxSizer(wxHORIZONTAL); wxButton *button = new wxButton(this, ID_OK_BUT, wxT("OK") ); butsizer->Add(button, 0, wxALIGN_RIGHT | wxALL, 10); button = new wxButton(this, ID_CAN_BUT, wxT("Cancel") ); butsizer->Add(button, 0, wxALIGN_LEFT | wxALL, 10); sizer->Add(butsizer, 0, wxALIGN_CENTER); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); int n; if (tqsl_getNumMode(&n) == 0) { for (int i = 0; i < n; i++) { const char *modestr; if (tqsl_getMode(i, &modestr, 0) == 0) { modelist->Append(wxString(modestr, wxConvLocal)); } } } } void AddMode::OnOK(wxCommandEvent& WXUNUSED(event)) { tqslTrace("AddMode::OnOK"); if (!TransferDataFromWindow()) return; key = adif->GetValue().Trim(true).Trim(false).MakeUpper(); int sel = modelist->GetSelection(); if (sel >= 0) value = modelist->GetString(sel); EndModal(ID_OK_BUT); } bool AddMode::TransferDataFromWindow() { tqslTrace("AddMode::TransferDataFromWindow"); key = adif->GetValue().Trim(true).Trim(false).MakeUpper(); if (key.IsEmpty()) return true; if (modelist->FindString(key) != wxNOT_FOUND) { // This duplicates an existing mode wxMessageBox(wxString::Format(wxT("This mode definition conflicts with a standard mode definition for %s"), key.c_str()), wxT("Mode Conflict"), wxOK, this); return false; } return true; } #define FILE_TEXT_WIDTH 30 BEGIN_EVENT_TABLE(FilePrefs, PrefsPanel) EVT_CHECKBOX(ID_PREF_FILE_AUTO_BACKUP, FilePrefs::OnShowHide) END_EVENT_TABLE() FilePrefs::FilePrefs(wxWindow *parent) : PrefsPanel(parent, wxT("pref-opt.htm")) { tqslTrace("FilePrefs::FilePrefs", "parent=0x%lx", (void *)parent); wxConfig *config = (wxConfig *)wxConfig::Get(); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT('M'), FILE_TEXT_WIDTH), &char_width, &char_height); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("Cabrillo file extensions:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); wxString cab = config->Read(wxT("CabrilloFiles"), DEFAULT_CABRILLO_FILES); cabrillo = new wxTextCtrl(this, ID_PREF_FILE_CABRILLO, cab, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(cabrillo, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("ADIF file extensions:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); wxString adi = config->Read(wxT("ADIFFiles"), DEFAULT_ADIF_FILES); adif = new wxTextCtrl(this, ID_PREF_FILE_ADIF, adi, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(adif, 0, wxLEFT|wxRIGHT, 10); bool ab; config->Read(wxT("AutoBackup"), &ab, DEFAULT_AUTO_BACKUP); autobackup = new wxCheckBox(this, ID_PREF_FILE_AUTO_BACKUP, wxT("Allow automatic configuration backup")); autobackup->SetValue(ab); sizer->Add(autobackup, 0, wxLEFT|wxRIGHT|wxTOP, 10); sizer->Add(new wxStaticText(this, -1, wxT("Backup File Folder:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); wxString bdir = config->Read(wxT("BackupFolder"), wxString(tQSL_BaseDir, wxConvLocal)); dirPick = new wxDirPickerCtrl(this, ID_PREF_FILE_BACKUP, bdir, wxT("Select a Folder"), wxDefaultPosition, wxSize(char_width, HEIGHT_ADJ(char_height)), wxDIRP_USE_TEXTCTRL); dirPick->Enable(ab); sizer->Add(dirPick, 0, wxEXPAND|wxLEFT|wxRIGHT, 10); badcalls = new wxCheckBox(this, ID_PREF_FILE_BADCALLS, wxT("Allow nonamateur call signs")); bool allow = false; config->Read(wxT("BadCalls"), &allow); badcalls->SetValue(allow); sizer->Add(badcalls, 0, wxLEFT|wxRIGHT|wxTOP, 10); daterange = new wxCheckBox(this, ID_PREF_FILE_BADCALLS, wxT("Prompt for QSO Date range when signing")); allow = true; config->Read(wxT("DateRange"), &allow); daterange->SetValue(allow); sizer->Add(daterange, 0, wxLEFT|wxRIGHT|wxTOP, 10); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); } void FilePrefs::ShowHide () { dirPick->Enable(autobackup->GetValue()); } static wxString fix_ext_str(const wxString& oldexts) { static const char *delims = ".,;: "; char *str = new char[oldexts.Length() + 1]; strcpy(str, oldexts.mb_str()); wxString exts; char *tok = strtok(str, delims); while (tok) { if (exts != wxT("")) exts += wxT(" "); exts += wxString(tok, wxConvLocal); tok = strtok(NULL, delims); } return exts; } bool FilePrefs::TransferDataFromWindow() { tqslTrace("FilePrefs::TransferDataFromWindow"); wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/")); config->Write(wxT("CabrilloFiles"), fix_ext_str(cabrillo->GetValue())); config->Write(wxT("ADIFFiles"), fix_ext_str(adif->GetValue())); config->Write(wxT("BadCalls"), badcalls->GetValue()); config->Write(wxT("DateRange"), daterange->GetValue()); config->Write(wxT("AutoBackup"), autobackup->GetValue()); config->Write(wxT("BackupFolder"), dirPick->GetPath()); return true; } #if defined(ENABLE_ONLINE_PREFS) BEGIN_EVENT_TABLE(OnlinePrefs, PrefsPanel) EVT_CHECKBOX(ID_PREF_ONLINE_DEFAULT, OnlinePrefs::OnShowHide) END_EVENT_TABLE() OnlinePrefs::OnlinePrefs(wxWindow *parent) : PrefsPanel(parent, wxT("pref-opt.htm")) { tqslTrace("OnlinePrefs::OnlinePrefs", "parent=0x%lx", (void *)parent); wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/LogUpload")); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT('M'), FILE_TEXT_WIDTH), &char_width, &char_height); wxString uplURL = config->Read(wxT("UploadURL"), DEFAULT_UPL_URL); wxString uplPOST = config->Read(wxT("PostField"), DEFAULT_UPL_FIELD); wxString uplStatusRE = config->Read(wxT("StatusRegex"), DEFAULT_UPL_STATUSRE); wxString uplStatOK = config->Read(wxT("StatusSuccess"), DEFAULT_UPL_STATUSOK); wxString uplMsgRE = config->Read(wxT("MessageRegex"), DEFAULT_UPL_MESSAGERE); wxString cfgUpdURL = config->Read(wxT("ConfigFileVerURL"), DEFAULT_UPD_CONFIG_URL); wxString cfgFileUpdURL = config->Read(wxT("NewConfigURL"), DEFAULT_CONFIG_FILE_URL); bool uplVerifyCA; config->Read(wxT("VerifyCA"), &uplVerifyCA, DEFAULT_UPL_VERIFYCA); defaults=( (uplURL==DEFAULT_UPL_URL) && (uplPOST==DEFAULT_UPL_FIELD) && (uplStatusRE==DEFAULT_UPL_STATUSRE) && (uplStatOK==DEFAULT_UPL_STATUSOK) && (uplMsgRE==DEFAULT_UPL_MESSAGERE) && (uplVerifyCA==DEFAULT_UPL_VERIFYCA) && (cfgUpdURL==DEFAULT_UPD_CONFIG_URL) && (cfgFileUpdURL==DEFAULT_CONFIG_FILE_URL)); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); useDefaults=new wxCheckBox(this, ID_PREF_ONLINE_DEFAULT, wxT("Use Defaults")); useDefaults->SetValue(defaults); sizer->Add(useDefaults, 0, wxTop|wxCENTER|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Upload URL:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); uploadURL = new wxTextCtrl(this, ID_PREF_ONLINE_URL, uplURL, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(uploadURL, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("HTTP POST Field:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); postField = new wxTextCtrl(this, ID_PREF_ONLINE_FIELD, uplPOST, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(postField, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Status RegEx:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); statusRegex = new wxTextCtrl(this, ID_PREF_ONLINE_STATUSRE, uplStatusRE, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(statusRegex, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Successful Status Message:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); statusSuccess = new wxTextCtrl(this, ID_PREF_ONLINE_STATUSOK, uplStatOK, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(statusSuccess, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Message RegEx:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); messageRegex= new wxTextCtrl(this, ID_PREF_ONLINE_MESSAGERE, uplMsgRE, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(messageRegex, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Config File Version URL:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); updConfigURL = new wxTextCtrl(this, ID_PREF_ONLINE_UPD_CONFIGURL, cfgUpdURL, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(updConfigURL, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("New Config File URL:")), 0, wxTOP|wxLEFT|wxRIGHT|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); configFileURL = new wxTextCtrl(this, ID_PREF_ONLINE_UPD_CONFIGFILE, cfgFileUpdURL, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(configFileURL, 0, wxLEFT|wxRIGHT, 10); verifyCA = new wxCheckBox(this, ID_PREF_ONLINE_VERIFYCA, wxT("Verify server certificate")); verifyCA->SetValue(uplVerifyCA); sizer->Add(verifyCA, 0, wxLEFT|wxRIGHT|wxTOP|wxRESERVE_SPACE_EVEN_IF_HIDDEN, 10); config->SetPath(wxT("/")); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); ShowHide(); } void OnlinePrefs::ShowHide() { tqslTrace("OnlinePrefs::ShowHide"); defaults=useDefaults->GetValue(); for (int i=1; i<16; i++) GetSizer()->Show(i, !defaults); //16 items in sizer; hide all but checkbox Layout(); //wxNotebook caches best size GetParent()->InvalidateBestSize(); GetParent()->Fit(); GetGrandParent()->Fit(); } bool OnlinePrefs::TransferDataFromWindow() { tqslTrace("OnlinePrefs::TransferDataFromWindow"); wxConfig *config = (wxConfig *)wxConfig::Get(); if (defaults) { config->DeleteGroup(wxT("/LogUpload")); } else { config->SetPath(wxT("/LogUpload")); config->Write(wxT("UploadURL"), uploadURL->GetValue()); config->Write(wxT("PostField"), postField->GetValue()); config->Write(wxT("StatusRegex"), statusRegex->GetValue()); config->Write(wxT("StatusSuccess"), statusSuccess->GetValue()); config->Write(wxT("MessageRegex"), messageRegex->GetValue()); config->Write(wxT("VerifyCA"), verifyCA->GetValue()); config->Write(wxT("ConfigFileVerURL"), updConfigURL->GetValue()); config->Write(wxT("NewCOnfigURL"), updConfigURL->GetValue()); config->SetPath(wxT("/")); } return true; } #endif // ENABLE_ONLINE_PREFS BEGIN_EVENT_TABLE(ProxyPrefs, PrefsPanel) EVT_CHECKBOX(ID_PREF_PROXY_ENABLED, ProxyPrefs::OnShowHide) END_EVENT_TABLE() ProxyPrefs::ProxyPrefs(wxWindow *parent) : PrefsPanel(parent, wxT("pref-opt.htm")) { tqslTrace("ProxyPrefs::ProxyPrefs", "parent=0x%lx", (void *)parent); wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/Proxy")); SetAutoLayout(true); wxArrayString ptypes; ptypes.Add(wxT("HTTP")); ptypes.Add(wxT("Socks4")); ptypes.Add(wxT("Socks5")); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT('M'), FILE_TEXT_WIDTH), &char_width, &char_height); config->Read(wxT("proxyEnabled"), &enabled, false); wxString pHost = config->Read(wxT("proxyHost")); wxString pPort = config->Read(wxT("proxyPort")); wxString pType = config->Read(wxT("proxyType")); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("\nUse these settings to configure a network proxy\n") wxT("for Internet uploads and downloads. You should only\n") wxT("enable a proxy if directed by your network administrator.\n") wxT("Incorrect settings can cause TQSL to be unable to upload\n") wxT("logs or check for updates.\n"))); proxyEnabled =new wxCheckBox(this, ID_PREF_PROXY_ENABLED, wxT("Enable a Network Proxy")); proxyEnabled->SetValue(enabled); sizer->Add(proxyEnabled, 0, wxTop|wxCENTER|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Proxy Address:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); proxyHost = new wxTextCtrl(this, ID_PREF_PROXY_HOST, pHost, wxPoint(0, 0), wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(proxyHost, 0, wxLEFT|wxRIGHT, 10); proxyHost->Enable(enabled); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("Port Number:")), 0, wxTOP|wxALIGN_LEFT, 4); proxyPort = new wxTextCtrl(this, ID_PREF_PROXY_PORT, pPort, wxPoint(0, 0), wxSize(char_width/6, HEIGHT_ADJ(char_height))); hsizer->Add(proxyPort, 0, wxLEFT|wxRIGHT|wxALIGN_BOTTOM, 0); proxyPort->Enable(enabled); hsizer->Add(new wxStaticText(this, -1, wxT(" Proxy Type:")), 0, wxTOP|wxALIGN_LEFT, 4); proxyType = new wxChoice(this, ID_PREF_PROXY_TYPE, wxPoint(0, 0), wxSize(char_width/4, HEIGHT_ADJ(char_height)), ptypes, 0, wxDefaultValidator, wxT("ProxyType")); hsizer->Add(proxyType, 0, wxALIGN_BOTTOM, 0); proxyType->Enable(enabled); proxyType->SetStringSelection(pType); sizer->Add(hsizer, 0, wxALL|wxALIGN_LEFT, 10); config->SetPath(wxT("/")); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); ShowHide(); } void ProxyPrefs::ShowHide() { tqslTrace("ProxyPrefs::ShowHide"); enabled=proxyEnabled->GetValue(); proxyHost->Enable(enabled); proxyPort->Enable(enabled); proxyType->Enable(enabled); for (int i=2; i<5; i++) GetSizer()->Show(i, enabled); // 5 items in sizer; hide all but warning and checkbox Layout(); //wxNotebook caches best size GetParent()->InvalidateBestSize(); GetParent()->Fit(); GetGrandParent()->Fit(); } bool ProxyPrefs::TransferDataFromWindow() { tqslTrace("ProxyPrefs::TransferDataFromWindow"); wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/Proxy")); config->Write(wxT("ProxyEnabled"), enabled); config->Write(wxT("ProxyHost"), proxyHost->GetValue()); config->Write(wxT("ProxyPort"), proxyPort->GetValue()); config->Write(wxT("ProxyType"), proxyType->GetStringSelection()); config->SetPath(wxT("/")); return true; } BEGIN_EVENT_TABLE(ContestMap, PrefsPanel) EVT_BUTTON(ID_PREF_CAB_DELETE, ContestMap::OnDelete) EVT_BUTTON(ID_PREF_CAB_ADD, ContestMap::OnAdd) EVT_BUTTON(ID_PREF_CAB_EDIT, ContestMap::OnEdit) END_EVENT_TABLE() ContestMap::ContestMap(wxWindow *parent) : PrefsPanel(parent, wxT("pref-cab.htm")) { tqslTrace("ContestMap::ContestMap", "parent=0x%lx", parent); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT("M")), &char_width, &char_height); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("Cabrillo CONTEST definitions:")), 0, wxTOP|wxLEFT|wxRIGHT, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); grid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize); grid->CreateGrid(10, 3); grid->SetLabelSize(wxHORIZONTAL, HEIGHT_ADJ(char_height)); grid->SetLabelSize(wxVERTICAL, 0); grid->SetColumnWidth(0, char_width*15); grid->SetColumnWidth(1, char_width*4); grid->SetColumnWidth(2, char_width*5); grid->SetLabelValue(wxHORIZONTAL, wxT("CONTEST"), 0); grid->SetLabelValue(wxHORIZONTAL, wxT("Type"), 1); grid->SetLabelValue(wxHORIZONTAL, wxT("Field"), 2); grid->SetEditable(false); grid->SetDividerPen(wxNullPen); grid->SetSize(1, grid->GetRowHeight(0) * grid->GetRows()); hsizer->Add(grid, 1, wxLEFT|wxRIGHT|wxEXPAND, 10); wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); vsizer->Add(new wxButton(this, ID_PREF_CAB_ADD, wxT("Add...")), 0, wxBOTTOM, 10); edit_but = new wxButton(this, ID_PREF_CAB_EDIT, wxT("Edit...")); vsizer->Add(edit_but, 0, wxBOTTOM, 10); delete_but = new wxButton(this, ID_PREF_CAB_DELETE, wxT("Delete")); vsizer->Add(delete_but, 0); hsizer->Add(vsizer, 0, wxRIGHT, 10); sizer->Add(hsizer, 1, wxBOTTOM|wxEXPAND, 10); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); SetContestList(); } void ContestMap::Buttons() { bool editable = grid->GetCursorRow() >= 0; delete_but->Enable(editable); edit_but->Enable(editable); } void ContestMap::SetContestList() { tqslTrace("ContestMap::SetContestList"); wxConfig *config = (wxConfig *)wxConfig::Get(); wxString key, value; long cookie; contestmap.clear(); if (grid->GetRows() > 0) grid->DeleteRows(0, grid->GetRows()); config->SetPath(wxT("/cabrilloMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); int contest_type = strtol(value.mb_str(), NULL, 10); int fieldnum = strtol(value.AfterFirst(wxT(';')).mb_str(), NULL, 10); contestmap.insert(make_pair(key, make_pair(contest_type, fieldnum))); stat = config->GetNextEntry(key, cookie); } config->SetPath(wxT("/")); int vsize = contestmap.size(); // if (vsize < 10) // vsize = 10; if (vsize) grid->AppendRows(vsize); int idx = 0; for (ContestSet::iterator it = contestmap.begin(); it != contestmap.end(); it++) { grid->SetCellValue(it->first, idx, 0); grid->SetCellValue(it->second.first == 1 ? wxT("VHF") : wxT("HF"), idx, 1); grid->SetCellValue(wxString::Format(wxT("%d"), it->second.second), idx, 2); ++idx; } config->SetPath(wxT("/")); Buttons(); } bool ContestMap::TransferDataFromWindow() { tqslTrace("ContestMap::TransferDataFromWindow"); return true; } void ContestMap::OnDelete(wxCommandEvent &) { tqslTrace("ContestMap::OnDelete"); int row = grid->GetCursorRow(); if (row >= 0) { wxString contest = grid->GetCellValue(row, 0); if (contest != wxT("")) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/cabrilloMap")); config->DeleteEntry(contest, true); config->Flush(false); SetContestList(); } } } void ContestMap::OnAdd(wxCommandEvent &) { tqslTrace("ContestMap::OnAdd"); EditContest dial(this, wxT("Add"), wxT(""), 0, TQSL_DEF_CABRILLO_MAP_FIELD); if (dial.ShowModal() == ID_OK_BUT) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/cabrilloMap")); config->Write(dial.contest, wxString::Format(wxT("%d;%d"), dial.contest_type, dial.callsign_field)); config->Flush(false); SetContestList(); } } void ContestMap::OnEdit(wxCommandEvent &) { tqslTrace("ContestMap::OnEdit"); wxString contest; int contest_type = 0, callsign_field = TQSL_DEF_CABRILLO_MAP_FIELD; int row = grid->GetCursorRow(); if (row >= 0) { contest = grid->GetCellValue(row, 0); if (contest != wxT("")) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/cabrilloMap")); wxString val; if (config->Read(contest, &val)) { contest_type = strtol(val.mb_str(), NULL, 10); callsign_field = strtol(val.AfterFirst(wxT(';')).mb_str(), NULL, 10); } config->SetPath(wxT("/")); } } EditContest dial(this, wxT("Edit"), contest, contest_type, callsign_field); if (dial.ShowModal() == ID_OK_BUT) { wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/cabrilloMap")); wxString val = wxString::Format(wxT("%d;%d"), dial.contest_type, dial.callsign_field); config->Write(dial.contest, val); config->Flush(false); if (dial.contest != contest && contest != wxT("")) { config->SetPath(wxT("/cabrilloMap")); config->DeleteEntry(contest, true); config->Flush(false); } SetContestList(); } } BEGIN_EVENT_TABLE(EditContest, wxDialog) EVT_BUTTON(ID_OK_BUT, EditContest::OnOK) EVT_BUTTON(ID_CAN_BUT, EditContest::OnCancel) END_EVENT_TABLE() EditContest::EditContest(wxWindow *parent, wxString ctype, wxString _contest, int _contest_type, int _callsign_field) : wxDialog(parent, -1, ctype + wxT(" Contest")), contest(_contest), contest_type(_contest_type), callsign_field(_callsign_field) { tqslTrace("EditContest::EditContest", "parent=0x%lx, ctype=%s, _contest=%s, _contest_type=%d, _callsign_field=%d", (void *)parent, _S(ctype), _S(_contest), _contest_type, _callsign_field); SetAutoLayout(true); wxClientDC dc(this); wxCoord char_width, char_height; dc.GetTextExtent(wxString(wxT("M")), &char_width, &char_height); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, ctype + wxT(" Cabrillo CONTEST")), 0, wxALL, 10); sizer->Add(new wxStaticText(this, -1, wxT("CONTEST Name:")), 0, wxLEFT|wxRIGHT, 10); name = new wxTextCtrl(this, -1, contest, wxDefaultPosition, wxSize(char_width, HEIGHT_ADJ(char_height))); sizer->Add(name, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); static wxString choices[] = { wxT("HF"), wxT("VHF") }; type = new wxRadioBox(this, -1, wxT("Contest type"), wxDefaultPosition, wxDefaultSize, 2, choices, 2, wxRA_SPECIFY_COLS); sizer->Add(type, 0, wxALL|wxEXPAND, 10); type->SetSelection(contest_type); sizer->Add(new wxStaticText(this, -1, wxT("Call-Worked Field Number:")), 0, wxLEFT|wxRIGHT, 10); fieldnum = new wxTextCtrl(this, -1, wxString::Format(wxT("%d"), callsign_field), wxDefaultPosition, wxSize(char_width * 3, HEIGHT_ADJ(char_height))); sizer->Add(fieldnum, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); wxBoxSizer *butsizer = new wxBoxSizer(wxHORIZONTAL); wxButton *button = new wxButton(this, ID_OK_BUT, wxT("OK") ); butsizer->Add(button, 0, wxALIGN_RIGHT | wxALL, 10); button = new wxButton(this, ID_CAN_BUT, wxT("Cancel") ); butsizer->Add(button, 0, wxALIGN_LEFT | wxALL, 10); sizer->Add(butsizer, 0, wxALIGN_CENTER); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } void EditContest::OnOK(wxCommandEvent& WXUNUSED(event)) { tqslTrace("EditContest::OnOK"); if (TransferDataFromWindow()) EndModal(ID_OK_BUT); } bool EditContest::TransferDataFromWindow() { tqslTrace("EditContest::TransferDataFromWindow"); contest = name->GetValue(); contest.Trim(false); contest.Trim(true); contest.MakeUpper(); if (contest == wxT("")) { wxMessageBox(wxT("Contest name cannot be blank"), wxT("Error"), wxOK, this); return false; } contest_type = type->GetSelection(); callsign_field = strtol(fieldnum->GetValue().mb_str(), NULL, 10); if (callsign_field < TQSL_MIN_CABRILLO_MAP_FIELD) { wxMessageBox(wxString::Format(wxT("Call-worked field must be %d or greater"), TQSL_MIN_CABRILLO_MAP_FIELD), wxT("Error"), wxOK, this); return false; } return true; } tqsl-2.0/apps/tqsl.rc.in0000664000076400007640000000226112231073120015217 0ustar rmurphyrmurphyTQSL_ICON1 ICON "@srcdir@/key.ico" TQSL_ICON2 ICON "@srcdir@/tqsl-new.ico" TQSL_ICON3 ICON "@srcdir@/tqsl-key1.ico" TQSL_ICON4 ICON "@srcdir@/tqsl.ico" #include "wx/msw/wx.rc" 1 VERSIONINFO FILEVERSION @TQSL_VERSION_MAJOR@, @TQSL_VERSION_MINOR@, 0, 0 PRODUCTVERSION @TQSL_VERSION_MAJOR@, @TQSL_VERSION_MINOR@, 0, 0 FILEFLAGSMASK 0 FILEFLAGS VS_FFI_FILEFLAGSMASK FILEOS VOS__WINDOWS32 FILETYPE VFT_APP BEGIN BLOCK "StringFileInfo" BEGIN // Language type = U.S. English(0x0409) and Character Set = Windows, Multilingual(0x04e4) BLOCK "040904E4" // Matches VarFileInfo Translation hex value. BEGIN VALUE "CompanyName", "American Radio Relay League, Inc.\000" VALUE "FileDescription", "TrustedQSL\000" VALUE "FileVersion", "@TQSLVERSION@\000" VALUE "InternalName", "TQSL\000" VALUE "LegalCopyright", "Copyright 2005 American Radio Relay League.\000" VALUE "OriginalFilename", "tqsl.exe\000" VALUE "ProductName", "TQSL\000" VALUE "ProductVersion", "@TQSLVERSION@\000" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 0x04e4 // U.S. English(0x0409) & Windows Multilingual(0x04e4) 1252 END END tqsl-2.0/apps/tqsl.ico0000664000076400007640000000706612231073120014770 0ustar rmurphyrmurphy &h( @ʦԙԙ0"""DUw"DUw"DUw3f333f3333f3ffffff3f̙3f3f333f333333;33f33333333f33n3ff3f3f3f3333f33̙33333f3333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffffff3ffff̙fff3fffffff3ffffff3f333f3333f3ffffff3f̙̙3̙f̙̙̙̙3f3f333f3333f3ffffff3f̙3f3f3f333f3333f3ffffff̙f33f3f333@ 1;????( @ʦ @ ` @@ @@@`@@@@`` `@`````` @` @` @` @`@@ @@@`@@@@@ @ @ @@ `@ @ @ @ @@@@ @@@@@`@@@@@@@@@`@` @`@@``@`@`@`@`@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@@@ @@@`@@@@ @` @ ` @@ @@@`@@@@`` `@`````` @` @` @` @` @` @ ` @@ @@@`@@@@`` `@`````` @` @` @`VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVcqtqsl-2.0/apps/tqsl.desktop0000664000076400007640000000030512231073120015654 0ustar rmurphyrmurphy[Desktop Entry] Name=TQSL Encoding=UTF-8 Comment=Sign Amateur Radio log files Exec=tqsl %F TryExec=tqsl Terminal=false Type=Application Categories=Application;HamRadio;Utility; Icon=TrustedQSL.png tqsl-2.0/apps/tqsl.cpp0000664000076400007640000051076412231073120015004 0ustar rmurphyrmurphy/*************************************************************************** tqsl.cpp - description ------------------- begin : Mon Nov 4 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: tqsl.cpp,v 1.13 2010/03/19 21:31:02 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include // has to be before something else in this list #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tqslhelp.h" #include "tqsltrace.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include #include #include "wxutil.h" #include #include #include #include "crqwiz.h" #include "getpassword.h" #include "loadcertwiz.h" #include "tqsllib.h" #include #include "util.h" #ifdef _MSC_VER //could probably do a more generic check here... // stdint exists on vs2012 and (I think) 2010, but not 2008 or its platform #define uint8_t unsigned char #else #include //for uint8_t; should be cstdint but this is C++11 and not universally supported #endif #ifdef _WIN32 #include #endif #include #include // only for version info! #include //only for version info! #include "tqslwiz.h" #include "qsodatadialog.h" #include "tqslerrno.h" #include "tqslexcept.h" #include "tqslpaths.h" #include "stationdial.h" #include "tqslconvert.h" #include "dxcc.h" #include "tqsl_prefs.h" #include "tqslbuild.h" #include "tqslapp.h" #include "winstrdefs.h" #ifdef _WIN32 #include "key.xpm" #else #include "key-new.xpm" #endif #include "save.xpm" #include "upload.xpm" #include "upload_dis.xpm" #include "file_edit.xpm" #include "file_edit_dis.xpm" #include "loc_add.xpm" #include "loc_add_dis.xpm" #include "delete.xpm" #include "delete_dis.xpm" #include "edit.xpm" #include "edit_dis.xpm" #include "download.xpm" #include "download_dis.xpm" #include "properties.xpm" #include "properties_dis.xpm" #include "import.xpm" #include "lotw.xpm" using namespace std; /// GEOMETRY #define LABEL_HEIGHT 20 #define LABEL_WIDTH 100 #define CERTLIST_FLAGS TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_SUPERCEDED | TQSL_SELECT_CERT_EXPIRED static wxMenu *stn_menu; static wxString flattenCallSign(const wxString& call); static wxString ErrorTitle(wxT("TQSL Error")); FILE *diagFile = NULL; static wxString origCommandLine = wxT(""); static MyFrame *frame = 0; static void exitNow(int status, bool quiet) { const char *errors[] = { "Success", "User Cancelled", "Upload Rejected", "Unexpected LoTW Response", "TQSL Error", "TQSLLib Error", "Error opening input file", "Error opening output file", "No QSOs written", "Some QSOs suppressed", "Commmand Syntax Error", "LoTW Connection Failed", "Unknown" }; int stat = status; if (stat > TQSL_EXIT_UNKNOWN || stat < 0) stat = TQSL_EXIT_UNKNOWN; if (quiet) wxLogMessage(wxT("Final Status: %hs (%d)"), errors[stat], status); else cerr << "Final Status: " << errors[stat] << "(" << status << ")" << endl; exit(status); } /////////// Application ////////////// class QSLApp : public wxApp { public: QSLApp(); virtual ~QSLApp(); class MyFrame *GUIinit(bool checkUpdates, bool quiet=false); bool OnInit(); virtual int OnRun(); // virtual wxLog *CreateLogTarget(); }; QSLApp::~QSLApp() { wxConfigBase *c = wxConfigBase::Set(0); if (c) delete c; if (diagFile) fclose(diagFile); } IMPLEMENT_APP(QSLApp) static int getCertPassword(char *buf, int bufsiz, tQSL_Cert cert) { tqslTrace("getCertPassword", "buf = %lx, bufsiz=%d, cert=%lx", buf, bufsiz, cert); char call[TQSL_CALLSIGN_MAX+1] = ""; int dxcc = 0; tqsl_getCertificateCallSign(cert, call, sizeof call); tqsl_getCertificateDXCCEntity(cert, &dxcc); DXCC dx; dx.getByEntity(dxcc); wxString message = wxString::Format(wxT("Enter the password to unlock the callsign certificate for\n" wxT("%hs -- %hs\n(This is the password you made up when you\ninstalled the callsign certificate.)")), call, dx.name()); wxWindow* top = wxGetApp().GetTopWindow(); if (frame->IsQuiet()) { frame->Show(true); } top->SetFocus(); top->Raise(); wxString pwd = wxGetPasswordFromUser(message, wxT("Enter password"), wxT(""), top); if (frame->IsQuiet()) { frame->Show(false); wxSafeYield(frame); } if (pwd.IsEmpty()) return 1; strncpy(buf, pwd.mb_str(), bufsiz); return 0; } class ConvertingDialog : public wxDialog { public: ConvertingDialog(wxWindow *parent, const char *filename = ""); void OnCancel(wxCommandEvent&); bool running; wxStaticText *msg; private: wxButton *canbut; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(ConvertingDialog, wxDialog) EVT_BUTTON(TQSL_CD_CANBUT, ConvertingDialog::OnCancel) END_EVENT_TABLE() void ConvertingDialog::OnCancel(wxCommandEvent&) { running = false; canbut->Enable(FALSE); } ConvertingDialog::ConvertingDialog(wxWindow *parent, const char *filename) : wxDialog(parent, -1, wxString(wxT("Signing QSO Data"))), running(true) { wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxString label = wxString(wxT("Converting ")) + wxString(filename, wxConvLocal) + wxT(" to TQSL format"); sizer->Add(new wxStaticText(this, -1, label), 0, wxALL|wxALIGN_CENTER, 10); msg = new wxStaticText(this, TQSL_CD_MSG, wxT(" ")); sizer->Add(msg, 0, wxALL|wxALIGN_LEFT, 10); canbut = new wxButton(this, TQSL_CD_CANBUT, wxT("Cancel")); sizer->Add(canbut, 0, wxALL|wxEXPAND, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } #define TQSL_PROG_CANBUT TQSL_ID_LOW+30 DECLARE_EVENT_TYPE(wxEVT_LOGUPLOAD_DONE, -1) DEFINE_EVENT_TYPE(wxEVT_LOGUPLOAD_DONE) class UploadDialog : public wxDialog { public: UploadDialog(wxWindow *parent); void OnCancel(wxCommandEvent&); void OnDone(wxCommandEvent&); int doUpdateProgress(double dltotal, double dlnow, double ultotal, double ulnow); static int UpdateProgress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { return ((UploadDialog*)clientp)->doUpdateProgress(dltotal, dlnow, ultotal, ulnow); } private: wxButton *canbut; wxGauge* progress; bool cancelled; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(UploadDialog, wxDialog) EVT_BUTTON(TQSL_PROG_CANBUT, UploadDialog::OnCancel) EVT_COMMAND(wxID_ANY, wxEVT_LOGUPLOAD_DONE, UploadDialog::OnDone) END_EVENT_TABLE() void UploadDialog::OnCancel(wxCommandEvent&) { cancelled=true; canbut->Enable(false); } UploadDialog::UploadDialog(wxWindow *parent) : wxDialog(parent, -1, wxString(wxT("Uploading Signed Data"))), cancelled(false) { tqslTrace("UploadDialog::UploadDialog", "parent = %lx", parent); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxString label = wxString(wxT("Uploading signed log data...")); sizer->Add(new wxStaticText(this, -1, label), 0, wxALL|wxALIGN_CENTER, 10); progress=new wxGauge(this, -1, 100); progress->SetValue(0); sizer->Add(progress, 0, wxALL|wxEXPAND); canbut = new wxButton(this, TQSL_PROG_CANBUT, wxT("Cancel")); sizer->Add(canbut, 0, wxALL|wxEXPAND, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } void UploadDialog::OnDone(wxCommandEvent&) { tqslTrace("UploadDialog::OnDone"); EndModal(1); } int UploadDialog::doUpdateProgress(double dltotal, double dlnow, double ultotal, double ulnow) { tqslTrace("UploadDialog::doUpdaeProgresss", "dltotal=%f, dlnow=%f, ultotal=%f, ulnow=%f", dltotal, dlnow, ultotal, ulnow); if (cancelled) return 1; if (ultotal>0.0000001) progress->SetValue((int)(100*(ulnow/ultotal))); return 0; } #define TQSL_DR_START TQSL_ID_LOW+10 #define TQSL_DR_END TQSL_ID_LOW+11 #define TQSL_DR_OK TQSL_ID_LOW+12 #define TQSL_DR_CAN TQSL_ID_LOW+13 #define TQSL_DR_MSG TQSL_ID_LOW+14 class DateRangeDialog : public wxDialog { public: DateRangeDialog(wxWindow *parent = 0); tQSL_Date start, end; private: void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); virtual bool TransferDataFromWindow(); wxTextCtrl *start_tc, *end_tc; wxStaticText *msg; DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(DateRangeDialog, wxDialog) EVT_BUTTON(TQSL_DR_OK, DateRangeDialog::OnOk) EVT_BUTTON(TQSL_DR_CAN, DateRangeDialog::OnCancel) END_EVENT_TABLE() DateRangeDialog::DateRangeDialog(wxWindow *parent) : wxDialog(parent, -1, wxString(wxT("QSO Date Range"))) { tqslTrace("DateRangeDialog::DateRangeDialog"); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("You may set the starting and/or ending QSO dates\n") wxT("in order to select QSOs from the input file.\n\n") wxT("QSOs prior to the starting date or after the ending\n") wxT("date will not be signed or included in the output file.\n\n") wxT("You may leave either date (or both dates) blank.") ), 0, wxALL|wxALIGN_CENTER, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("Start Date (YYYY-MM-DD)")), 0, wxRIGHT, 5); start_tc = new wxTextCtrl(this, TQSL_DR_START); hsizer->Add(start_tc, 0, 0, 0); sizer->Add(hsizer, 0, wxALL|wxALIGN_CENTER, 10); hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("End Date (YYYY-MM-DD)")), 0, wxRIGHT, 5); end_tc = new wxTextCtrl(this, TQSL_DR_END); hsizer->Add(end_tc, 0, 0, 0); sizer->Add(hsizer, 0, wxALL|wxALIGN_CENTER, 10); msg = new wxStaticText(this, TQSL_DR_MSG, wxT("")); sizer->Add(msg, 0, wxALL, 5); hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxButton(this, TQSL_DR_OK, wxT("Ok")), 0, wxRIGHT, 5); hsizer->Add(new wxButton(this, TQSL_DR_CAN, wxT("Cancel")), 0, wxLEFT, 10); sizer->Add(hsizer, 0, wxALIGN_CENTER|wxALL, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } bool DateRangeDialog::TransferDataFromWindow() { tqslTrace("DateRangeDialog::TransferDataFromWindow"); wxString text = start_tc->GetValue(); tqslTrace("DateRangeDialog::TransferDataFromWindow: start=%s",_S(text)); if (text.Trim() == wxT("")) start.year = start.month = start.day = 0; else if (tqsl_initDate(&start, text.mb_str()) || !tqsl_isDateValid(&start)) { msg->SetLabel(wxT("Start date is invalid")); return false; } text = end_tc->GetValue(); tqslTrace("DateRangeDialog::TransferDataFromWindow: end=%s",_S(text)); if (text.Trim() == wxT("")) end.year = end.month = end.day = 0; else if (tqsl_initDate(&end, text.mb_str()) || !tqsl_isDateValid(&end)) { msg->SetLabel(wxT("End date is invalid")); return false; } return true; } void DateRangeDialog::OnOk(wxCommandEvent&) { tqslTrace("DateRangeDialog::OnOk"); if (TransferDataFromWindow()) EndModal(wxOK); } void DateRangeDialog::OnCancel(wxCommandEvent&) { tqslTrace("DateRangeDialog::OnCancel"); EndModal(wxCANCEL); } #define TQSL_DP_OK TQSL_ID_LOW+20 #define TQSL_DP_CAN TQSL_ID_LOW+21 #define TQSL_DP_ALLOW TQSL_ID_LOW+22 class DupesDialog : public wxDialog { public: DupesDialog(wxWindow *parent = 0, int qso_count=0, int dupes=0, int action=TQSL_ACTION_ASK); private: void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); void OnAllow(wxCommandEvent&); DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(DupesDialog, wxDialog) EVT_BUTTON(TQSL_DP_OK, DupesDialog::OnOk) EVT_BUTTON(TQSL_DP_CAN, DupesDialog::OnCancel) EVT_BUTTON(TQSL_DP_ALLOW, DupesDialog::OnAllow) END_EVENT_TABLE() DupesDialog::DupesDialog(wxWindow *parent, int qso_count, int dupes, int action) : wxDialog(parent, -1, wxString(wxT("Duplicate QSOs Detected")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { tqslTrace("DupesDialog::DupesDialog", "qso_count = %d, dupes =%d, action= =%d",qso_count, dupes, action); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxString message; if (qso_count == dupes) { message = wxString::Format(wxT("This log contains %d QSO(s) which appear ") wxT("to have already been signed for upload to LoTW, and no new QSOs.\n\n") wxT("Click 'Cancel' to abandon processing this log file (Recommended).\n") wxT("Click 'Allow Duplicates' to re-process this ") wxT("log while allowing duplicate QSOs."), qso_count); } else { int newq = qso_count - dupes; message = wxString::Format(wxT("This log contains %d QSO(s) which appear ") wxT("to have already been signed for upload to LoTW, and ") wxT("%d QSO%hs new.\n\n") wxT("Click 'Exclude duplicates' to sign normally, without the duplicate QSOs (Recommended).\n") wxT("Click 'Cancel' to abandon processing this log file.\n") wxT("Click 'Allow duplicates' to re-process this log ") wxT("while allowing duplicate QSOs."), dupes, newq, (newq == 1) ? " which is" : "s which are"); } if (action==TQSL_ACTION_UNSPEC) { if (qso_count==dupes) { message+= wxT("\n\nThe log file you are uploading using your QSO Logging system consists entirely of previously uploaded\n") wxT("QSOs (duplicates) that create unnecessary work for LoTW. There may be a more recent version of your QSO\n") wxT("Logging system that would prevent this. Please check with your QSO Logging system's vendor for an updated version.\n") wxT("In the meantime, please note that some loggers may exhibit strange behavior if an option other than 'Allow duplicates'\n") wxT("is clicked. Choosing 'Cancel' is usually safe, but a defective logger not checking the status messages reported by TrustedQSL may produce\n") wxT("strange (but harmless) behavior such as attempting to upload an empty file or marking all chosen QSOs as 'sent'"); } else { message+= wxT("\n\nThe log file you are uploading using your QSO Logging system includes some previously uploaded\n") wxT("QSOs (duplicates) that create unnecessary work for LoTW. There may be a more recent version of your\n") wxT("QSO Logging system that would prevent this. Please check with your QSO Logging system's vendor for an updated version.\n") wxT("In the meantime, please note that some loggers may exhibit strange behavior if an option other than 'Allow duplicates'\n") wxT("is clicked. 'Exclude duplicates' is recommended, but a logger that does its own duplicate tracking may incorrectly\n") wxT("set the status in this case. A logger that doesn't track duplicates should be unaffected by choosing 'Exclude duplicates'\n") wxT("and if it tracks 'QSO sent' status, will correctly mark all selected QSOs as sent - they are in your account even though\n") wxT("they would not be in this specific batch\n") wxT("Choosing 'Cancel' is usually safe, but a defective logger not checking the status messages reported by TrustedQSL may produce\n") wxT("strange (but harmless) behavior such as attempting to upload an empty file or marking all chosen QSOs as 'sent'"); } } sizer->Add(new wxStaticText(this, -1, message), 0, wxALL|wxALIGN_CENTER, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); if (qso_count!=dupes) hsizer->Add(new wxButton(this, TQSL_DP_OK, wxT("Exclude duplicates")), 0, wxRIGHT, 5); hsizer->Add(new wxButton(this, TQSL_DP_CAN, wxT("Cancel")), 0, wxLEFT, 10); hsizer->Add(new wxButton(this, TQSL_DP_ALLOW, wxT("Allow duplicates")), 0, wxLEFT, 20); sizer->Add(hsizer, 0, wxALIGN_CENTER|wxALL, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } void DupesDialog::OnOk(wxCommandEvent&) { tqslTrace("DupesDialog::OnOk"); EndModal(TQSL_DP_OK); } void DupesDialog::OnCancel(wxCommandEvent&) { tqslTrace("DupesDialog::OnCancel"); EndModal(TQSL_DP_CAN); } void DupesDialog::OnAllow(wxCommandEvent&) { tqslTrace("DupesDialog::OnAllow"); if (wxMessageBox(wxT("The only reason to re-sign duplicate QSOs is if a previous upload") wxT(" went unprocessed by LoTW, either because it was never uploaded, or there was a server failure\n\n") wxT("Are you sure you want to proceed? Click 'No' to review the choices"), wxT("Are you sure?"), wxYES_NO|wxICON_EXCLAMATION, this)==wxYES) { EndModal(TQSL_DP_ALLOW); } } #define TQSL_AE_OK TQSL_ID_LOW+40 #define TQSL_AE_CAN TQSL_ID_LOW+41 class ErrorsDialog : public wxDialog { public: ErrorsDialog(wxWindow *parent = 0, wxString msg = wxT("")); private: void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(ErrorsDialog, wxDialog) EVT_BUTTON(TQSL_AE_OK, ErrorsDialog::OnOk) EVT_BUTTON(TQSL_AE_CAN, ErrorsDialog::OnCancel) END_EVENT_TABLE() ErrorsDialog::ErrorsDialog(wxWindow *parent, wxString msg) : wxDialog(parent, -1, wxString(wxT("Errors Detected")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { tqslTrace("ErrorsDialog::ErrorsDialog", "msg=%s", _S(msg)); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, msg), 0, wxALL|wxALIGN_CENTER, 10); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxButton(this, TQSL_AE_OK, wxT("Ignore")), 0, wxRIGHT, 5); hsizer->Add(new wxButton(this, TQSL_AE_CAN, wxT("Cancel")), 0, wxLEFT, 10); sizer->Add(hsizer, 0, wxALIGN_CENTER|wxALL, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CenterOnParent(); } void ErrorsDialog::OnOk(wxCommandEvent&) { tqslTrace("ErrorsDialog::OnOk"); EndModal(TQSL_AE_OK); } void ErrorsDialog::OnCancel(wxCommandEvent&) { tqslTrace("ErrorsDialog::OnCancel"); EndModal(TQSL_AE_CAN); } static void init_modes() { tqslTrace("init_modes"); tqsl_clearADIFModes(); wxConfig *config = (wxConfig *)wxConfig::Get(); long cookie; wxString key, value; vector badModes; config->SetPath(wxT("/modeMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); bool newMode = true; int numModes; if (tqsl_getNumMode(&numModes) == 0) { for (int i = 0; i < numModes; i++) { const char *modestr; if (tqsl_getMode(i, &modestr, NULL) == 0) { if (strcasecmp(key.mb_str(), modestr) == 0) { wxLogWarning(wxT("Your custom mode map %s conflicts with the standard mode definition for %hs and was deleted."), key.c_str(), modestr); newMode = false; badModes.push_back(key); break; } } } } if (newMode) tqsl_setADIFMode(key.mb_str(), value.mb_str()); stat = config->GetNextEntry(key, cookie); } // Delete the conflicting entries for (int i = 0; i < (int)badModes.size(); i++) { config->DeleteEntry(badModes[i]); } config->SetPath(wxT("/")); } static void init_contests() { tqslTrace("init_contests"); tqsl_clearCabrilloMap(); wxConfig *config = (wxConfig *)wxConfig::Get(); long cookie; wxString key, value; config->SetPath(wxT("/cabrilloMap")); bool stat = config->GetFirstEntry(key, cookie); while (stat) { value = config->Read(key, wxT("")); int contest_type = strtol(value.mb_str(), NULL, 10); int callsign_field = strtol(value.AfterFirst(';').mb_str(), NULL, 10); tqsl_setCabrilloMapEntry(key.mb_str(), callsign_field, contest_type); stat = config->GetNextEntry(key, cookie); } config->SetPath(wxT("/")); } static void check_tqsl_error(int rval) { if (rval == 0) return; tqslTrace("check_tqsl_error", "rval=%d", rval); const char *msg = tqsl_getErrorString(); tqslTrace("check_tqsl_error", "msg=%s", msg); throw TQSLException(msg); } static tQSL_Cert *certlist = 0; static int ncerts; static void free_certlist() { tqslTrace("free_certlist"); if (certlist) { for (int i = 0; i < ncerts; i++) tqsl_freeCertificate(certlist[i]); certlist = 0; } } static void get_certlist(string callsign, int dxcc, bool expired, bool superceded) { tqslTrace("get_certlist", "callsign=%s, dxcc=%d, expired=%d, superceded=%d",callsign.c_str(), dxcc, expired, superceded); free_certlist(); int select = TQSL_SELECT_CERT_WITHKEYS; if (expired) select |= TQSL_SELECT_CERT_EXPIRED; if (superceded) select |= TQSL_SELECT_CERT_SUPERCEDED; tqsl_selectCertificates(&certlist, &ncerts, (callsign == "") ? 0 : callsign.c_str(), dxcc, 0, 0, select); } class LogList : public wxLog { public: LogList(MyFrame *frame) : wxLog(), _frame(frame) {} virtual void DoLogString(const wxChar *szString, time_t t); private: MyFrame *_frame; }; void LogList::DoLogString(const wxChar *szString, time_t) { wxTextCtrl *_logwin = 0; if (diagFile) { #ifdef _WIN32 fprintf(diagFile, "%hs\n", szString); #else // const char *cstr = wxString(szString).mb_str(); // fprintf(diagFile, "%s\n", cstr); fprintf(diagFile, "%ls\n", szString); #endif } if (wxString(szString).StartsWith(wxT("Debug:"))) return; if (wxString(szString).StartsWith(wxT("Error: Unable to open requested HTML document:"))) return; if (_frame != 0) _logwin = _frame->logwin; if (_logwin == 0) { #ifdef _WIN32 cerr << szString << endl; #else fprintf(stderr, "%ls\n", szString); #endif return; } _logwin->AppendText(szString); _logwin->AppendText(wxT("\n")); } class LogStderr : public wxLog { public: LogStderr(void) : wxLog() {} virtual void DoLogString(const wxChar *szString, time_t t); }; void LogStderr::DoLogString(const wxChar *szString, time_t) { if (diagFile) { #ifdef _WIN32 fprintf(diagFile, "%hs\n", szString); #else fprintf(diagFile, "%ls\n", szString); // const char *cstr = wxString(szString).mb_str(); // fprintf(diagFile, "%s\n", cstr); #endif } if (wxString(szString).StartsWith(wxT("Debug:"))) return; #ifdef _WIN32 cerr << szString << endl; #else fprintf(stderr, "%ls\n", szString); #endif return; } BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(tm_s_add, MyFrame::AddStationLocation) EVT_BUTTON(tl_AddLoc, MyFrame::AddStationLocation) EVT_MENU(tm_s_edit, MyFrame::EditStationLocation) EVT_BUTTON(tl_EditLoc, MyFrame::EditStationLocation) EVT_MENU(tm_f_new, MyFrame::EnterQSOData) EVT_BUTTON(tl_Edit, MyFrame::EnterQSOData) EVT_MENU(tm_f_edit, MyFrame::EditQSOData) EVT_MENU(tm_f_import_compress, MyFrame::ImportQSODataFile) EVT_BUTTON(tl_Save, MyFrame::ImportQSODataFile) EVT_MENU(tm_f_upload, MyFrame::UploadQSODataFile) EVT_BUTTON(tl_Upload, MyFrame::UploadQSODataFile) EVT_MENU(tm_f_exit, MyFrame::DoExit) EVT_MENU(tm_f_preferences, MyFrame::OnPreferences) EVT_MENU(tm_f_loadconfig, MyFrame::OnLoadConfig) EVT_MENU(tm_f_saveconfig, MyFrame::OnSaveConfig) EVT_MENU(tm_h_contents, MyFrame::OnHelpContents) EVT_MENU(tm_h_about, MyFrame::OnHelpAbout) EVT_MENU(tm_f_diag, MyFrame::OnHelpDiagnose) EVT_MENU(tm_h_update, MyFrame::CheckForUpdates) EVT_CLOSE(MyFrame::OnExit) EVT_MENU(tc_CRQWizard, MyFrame::CRQWizard) EVT_MENU(tc_c_New, MyFrame::CRQWizard) EVT_MENU(tc_c_Load, MyFrame::OnLoadCertificateFile) EVT_BUTTON(tc_Load, MyFrame::OnLoadCertificateFile) EVT_MENU(tc_c_Properties, MyFrame::OnCertProperties) EVT_BUTTON(tc_CertProp, MyFrame::OnCertProperties) EVT_MENU(tc_c_Export, MyFrame::OnCertExport) EVT_BUTTON(tc_CertSave, MyFrame::OnCertExport) EVT_MENU(tc_c_Delete, MyFrame::OnCertDelete) // EVT_MENU(tc_c_Import, MyFrame::OnCertImport) // EVT_MENU(tc_c_Sign, MyFrame::OnSign) EVT_MENU(tc_c_Renew, MyFrame::CRQWizardRenew) EVT_BUTTON(tc_CertRenew, MyFrame::CRQWizardRenew) EVT_MENU(tc_h_Contents, MyFrame::OnHelpContents) EVT_MENU(tc_h_About, MyFrame::OnHelpAbout) EVT_MENU(tl_c_Properties, MyFrame::OnLocProperties) EVT_MENU(tm_s_Properties, MyFrame::OnLocProperties) EVT_BUTTON(tl_PropLoc, MyFrame::OnLocProperties) EVT_MENU(tl_c_Delete, MyFrame::OnLocDelete) EVT_BUTTON(tl_DeleteLoc, MyFrame::OnLocDelete) EVT_MENU(tl_c_Edit, MyFrame::OnLocEdit) EVT_BUTTON(tl_Login, MyFrame::OnLoginToLogbook) EVT_TREE_SEL_CHANGED(tc_CertTree, MyFrame::OnCertTreeSel) EVT_TREE_SEL_CHANGED(tc_LocTree, MyFrame::OnLocTreeSel) EVT_TIMER(tm_f_autoupdate, MyFrame::DoUpdateCheck) END_EVENT_TABLE() void MyFrame::OnExit(TQ_WXCLOSEEVENT& WXUNUSED(event)) { int x, y, w, h; // Don't save window size/position if minimized or too small wxConfig *config = (wxConfig *)wxConfig::Get(); if (!IsIconized()) { GetPosition(&x, &y); GetSize(&w, &h); if (w >= MAIN_WINDOW_MIN_WIDTH && h >= MAIN_WINDOW_MIN_HEIGHT) { config->Write(wxT("MainWindowX"), x); config->Write(wxT("MainWindowY"), y); config->Write(wxT("MainWindowWidth"), w); config->Write(wxT("MainWindowHeight"), h); config->Flush(false); } } Destroy(); // close the window bool ab; config->Read(wxT("AutoBackup"), &ab, DEFAULT_AUTO_BACKUP); if (ab) { wxString bdir = config->Read(wxT("BackupFolder"), wxString(tQSL_BaseDir, wxConvLocal)); #ifdef _WIN32 bdir += wxT("\\tqslconfig.tbk"); #else bdir += wxT("/tqslconfig.tbk"); #endif BackupConfig(bdir, true); } } void MyFrame::DoExit(wxCommandEvent& WXUNUSED(event)) { Close(); Destroy(); } void MyFrame::DoUpdateCheck(wxTimerEvent& WXUNUSED(event)) { //check for updates wxConfig *config = (wxConfig *)wxConfig::Get(); if (config->Read(wxT("AutoUpdateCheck"), true)) { wxLogMessage(wxT("Checking for TQSL updates...")); wxSafeYield(); wxBusyCursor wait; wxSafeYield(); DoCheckForUpdates(true); logwin->SetValue(wxT("")); // Clear the checking message } } MyFrame::MyFrame(const wxString& title, int x, int y, int w, int h, bool checkUpdates, bool quiet) : wxFrame(0, -1, title, wxPoint(x, y), wxSize(w, h)) { _quiet = quiet; DocPaths docpaths(wxT("tqslapp")); wxBitmap savebm(save_xpm); wxBitmap uploadbm(upload_xpm); wxBitmap upload_disbm(upload_dis_xpm); wxBitmap file_editbm(file_edit_xpm); wxBitmap file_edit_disbm(file_edit_dis_xpm); wxBitmap locaddbm(loc_add_xpm); wxBitmap locadd_disbm(loc_add_dis_xpm); wxBitmap editbm(edit_xpm); wxBitmap edit_disbm(edit_dis_xpm); wxBitmap deletebm(delete_xpm); wxBitmap delete_disbm(delete_dis_xpm); wxBitmap downloadbm(download_xpm); wxBitmap download_disbm(download_dis_xpm); wxBitmap propertiesbm(properties_xpm); wxBitmap properties_disbm(properties_dis_xpm); wxBitmap importbm(import_xpm); wxBitmap lotwbm(lotw_xpm); loc_edit_button = NULL; cert_save_label = NULL; req = NULL; // File menu file_menu = new wxMenu; file_menu->Append(tm_f_upload, wxT("Sign and &upload ADIF or Cabrillo File...")); file_menu->Append(tm_f_import_compress, wxT("&Sign and save ADIF or Cabrillo file...")); file_menu->AppendSeparator(); file_menu->Append(tm_f_saveconfig, wxT("&Backup Station Locations, Certificates, and Preferences...")); file_menu->Append(tm_f_loadconfig, wxT("&Restore Station Locations, Certificates, and Preferences...")); file_menu->AppendSeparator(); file_menu->Append(tm_f_new, wxT("Create &New ADIF file...")); file_menu->Append(tm_f_edit, wxT("&Edit existing ADIF file...")); file_menu->AppendSeparator(); #ifdef __WXMAC__ // On Mac, Preferences not on File menu file_menu->Append(tm_f_preferences, wxT("&Preferences...")); #else file_menu->Append(tm_f_preferences, wxT("Display or Modify &Preferences...")); #endif file_menu->AppendSeparator(); file_menu->AppendCheckItem(tm_f_diag, wxT("Dia&gnostic Mode")); file_menu->Check(tm_f_diag, false); #ifndef __WXMAC__ // On Mac, Exit not on File menu file_menu->AppendSeparator(); #endif file_menu->Append(tm_f_exit, wxT("E&xit TQSL\tAlt-X")); cert_menu = makeCertificateMenu(false); // Station menu stn_menu = new wxMenu; stn_menu->Append(tm_s_Properties, wxT("&Display Station Location Properties")); stn_menu->Enable(tm_s_Properties, false); stn_menu->Append(tm_s_edit, wxT("&Edit Station Location")); stn_menu->Append(tm_s_add, wxT("&Add Station Location")); // Help menu help = new wxHtmlHelpController(wxHF_DEFAULT_STYLE | wxHF_OPEN_FILES); help_menu = new wxMenu; help->UseConfig(wxConfig::Get()); wxString hhp = docpaths.FindAbsoluteValidPath(wxT("tqslapp.hhp")); if (wxFileNameFromPath(hhp) != wxT("")) { if (help->AddBook(hhp)) #ifdef __WXMAC__ help_menu->Append(tm_h_contents, wxT("&Contents")); #else help_menu->Append(tm_h_contents, wxT("Display &Documentation")); help_menu->AppendSeparator(); #endif } help_menu->Append(tm_h_update, wxT("Check for &Updates...")); help_menu->Append(tm_h_about, wxT("&About")); // Main menu wxMenuBar *menu_bar = new wxMenuBar; menu_bar->Append(file_menu, wxT("&File")); menu_bar->Append(stn_menu, wxT("&Station Location")); menu_bar->Append(cert_menu, wxT("Callsign &Certificate")); menu_bar->Append(help_menu, wxT("&Help")); SetMenuBar(menu_bar); wxPanel* topPanel = new wxPanel(this); wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL); topPanel->SetSizer(topSizer); // Log operations //topSizer->Add(new wxStaticText(topPanel, -1, wxT("")), 0, wxEXPAND | wxALL, 1); topSizer->AddSpacer(10); wxNotebook* notebook = new wxNotebook(topPanel, -1, wxDefaultPosition, wxDefaultSize, wxNB_TOP /* | wxNB_FIXEDWIDTH*/, wxT("Log Operations")); topSizer->Add(notebook, 0, wxEXPAND | wxALL, 1); topSizer->Add(new wxStaticText(topPanel, -1, wxT("Status Log")), 0, wxEXPAND | wxALL, 1); logwin = new wxTextCtrl(topPanel, -1, wxT(""), wxDefaultPosition, wxSize(400, 200), wxTE_MULTILINE|wxTE_READONLY); topSizer->Add(logwin, 50, wxEXPAND | wxALL, 1); wxPanel* buttons = new wxPanel(notebook, -1); buttons->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* bsizer = new wxBoxSizer(wxVERTICAL); buttons->SetSizer(bsizer); wxPanel* b1Panel = new wxPanel(buttons); b1Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* b1sizer = new wxBoxSizer(wxHORIZONTAL); b1Panel->SetSizer(b1sizer); wxBitmapButton *up = new wxBitmapButton(b1Panel, tl_Upload, uploadbm); up->SetBitmapDisabled(upload_disbm); b1sizer->Add(up, 0, wxALL, 1); b1sizer->Add(new wxStaticText(b1Panel, -1, wxT("\nSign a log and upload it automatically to LoTW")), 1, wxALL, 1); bsizer->Add(b1Panel, 0, wxALL, 1); wxPanel* b2Panel = new wxPanel(buttons); wxBoxSizer* b2sizer = new wxBoxSizer(wxHORIZONTAL); b2Panel->SetBackgroundColour(wxColour(255, 255, 255)); b2Panel->SetSizer(b2sizer); b2sizer->Add(new wxBitmapButton(b2Panel, tl_Save, savebm), 0, wxALL, 1); b2sizer->Add(new wxStaticText(b2Panel, -1, wxT("\nSign a log and save it for uploading later")), 1, wxALL, 1); bsizer->Add(b2Panel, 0, wxALL, 1); wxPanel* b3Panel = new wxPanel(buttons); wxBoxSizer* b3sizer = new wxBoxSizer(wxHORIZONTAL); b3Panel->SetBackgroundColour(wxColour(255, 255, 255)); b3Panel->SetSizer(b3sizer); wxBitmapButton *fed = new wxBitmapButton(b3Panel, tl_Edit, file_editbm); fed->SetBitmapDisabled(file_edit_disbm); b3sizer->Add(fed, 0, wxALL, 1); b3sizer->Add(new wxStaticText(b3Panel, -1, wxT("\nCreate an ADIF file for signing and uploading")), 1, wxALL, 1); bsizer->Add(b3Panel, 0, wxALL, 1); wxPanel* b4Panel = new wxPanel(buttons); wxBoxSizer* b4sizer = new wxBoxSizer(wxHORIZONTAL); b4Panel->SetBackgroundColour(wxColour(255, 255, 255)); b4Panel->SetSizer(b4sizer); b4sizer->Add(new wxBitmapButton(b4Panel, tl_Login, lotwbm), 0, wxALL, 1); b4sizer->Add(new wxStaticText(b4Panel, -1, wxT("\nLog in to the Logbook of the World Site")), 1, wxALL, 1); bsizer->Add(b4Panel, 0, wxALL, 1); notebook->AddPage(buttons, wxT("Log Operations")); // notebook->InvalidateBestSize(); // logwin->FitInside(); // Location tab wxPanel* loctab = new wxPanel(notebook, -1); wxBoxSizer* locsizer = new wxBoxSizer(wxHORIZONTAL); loctab->SetSizer(locsizer); wxPanel* locgrid = new wxPanel(loctab, -1); locgrid->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* lgsizer = new wxBoxSizer(wxVERTICAL); locgrid->SetSizer(lgsizer); loc_tree = new LocTree(locgrid, tc_LocTree, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE | wxBORDER_NONE); loc_tree->SetBackgroundColour(wxColour(255, 255, 255)); loc_tree->Build(); LocTreeReset(); lgsizer->Add(loc_tree, 1, wxEXPAND); loc_select_label = new wxStaticText(locgrid, -1, wxT("\nSelect a Station Location to process ")); lgsizer->Add(loc_select_label, 0, wxALL, 1); locsizer->Add(locgrid, 50, wxEXPAND); wxStaticLine *locsep =new wxStaticLine(loctab, -1, wxDefaultPosition, wxSize(2, -1), wxLI_VERTICAL); locsizer->Add(locsep, 0, wxEXPAND); wxPanel* lbuttons = new wxPanel(loctab, -1); lbuttons->SetBackgroundColour(wxColour(255, 255, 255)); locsizer->Add(lbuttons, 50, wxEXPAND); wxBoxSizer* lbsizer = new wxBoxSizer(wxVERTICAL); lbuttons->SetSizer(lbsizer); wxPanel* lb1Panel = new wxPanel(lbuttons); lb1Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* lb1sizer = new wxBoxSizer(wxHORIZONTAL); lb1Panel->SetSizer(lb1sizer); loc_add_button = new wxBitmapButton(lb1Panel, tl_AddLoc, locaddbm); loc_add_button->SetBitmapDisabled(locadd_disbm); lb1sizer->Add(loc_add_button, 0, wxALL, 1); // Note - the doubling below is to size the label to allow the control to stretch later loc_add_label = new wxStaticText(lb1Panel, -1, wxT("\nCreate a new Station LocationCreate a new Station\n")); lb1sizer->Add(loc_add_label, 1, wxFIXED_MINSIZE | wxALL, 1); lbsizer->Add(lb1Panel, 1, wxALL, 1); int tw, th; loc_add_label->GetSize(&tw, &th); loc_add_label->SetLabel(wxT("\nCreate a new Station Location")); wxPanel* lb2Panel = new wxPanel(lbuttons); lb2Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* lb2sizer = new wxBoxSizer(wxHORIZONTAL); lb2Panel->SetSizer(lb2sizer); loc_edit_button = new wxBitmapButton(lb2Panel, tl_EditLoc, editbm); loc_edit_button->SetBitmapDisabled(edit_disbm); loc_edit_button->Enable(false); lb2sizer->Add(loc_edit_button, 0, wxALL, 1); loc_edit_label = new wxStaticText(lb2Panel, -1, wxT("\nEdit a Station Location"), wxDefaultPosition, wxSize(tw, th)); lb2sizer->Add(loc_edit_label, 1, wxFIXED_MINSIZE | wxALL, 1); lbsizer->Add(lb2Panel, 1, wxALL, 1); wxPanel* lb3Panel = new wxPanel(lbuttons); lb3Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* lb3sizer = new wxBoxSizer(wxHORIZONTAL); lb3Panel->SetSizer(lb3sizer); loc_delete_button = new wxBitmapButton(lb3Panel, tl_DeleteLoc, deletebm); loc_delete_button->SetBitmapDisabled(delete_disbm); loc_delete_button->Enable(false); lb3sizer->Add(loc_delete_button, 0, wxALL, 1); loc_delete_label = new wxStaticText(lb3Panel, -1, wxT("\nDelete a Station Location"), wxDefaultPosition, wxSize(tw, th)); lb3sizer->Add(loc_delete_label, 1, wxFIXED_MINSIZE | wxALL, 1); lbsizer->Add(lb3Panel, 1, wxALL, 1); wxPanel* lb4Panel = new wxPanel(lbuttons); lb4Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* lb4sizer = new wxBoxSizer(wxHORIZONTAL); lb4Panel->SetSizer(lb4sizer); loc_prop_button = new wxBitmapButton(lb4Panel, tl_PropLoc, propertiesbm); loc_prop_button->SetBitmapDisabled(properties_disbm); loc_prop_button->Enable(false); lb4sizer->Add(loc_prop_button, 0, wxALL, 1); loc_prop_label = new wxStaticText(lb4Panel, -1, wxT("\nDisplay Station Location Properties"), wxDefaultPosition, wxSize(tw, th)); lb4sizer->Add(loc_prop_label, 1, wxFIXED_MINSIZE | wxALL, 1); lbsizer->Add(lb4Panel, 1, wxALL, 1); notebook->AddPage(loctab, wxT("Station Locations")); // Certificates tab wxPanel* certtab = new wxPanel(notebook, -1); wxBoxSizer* certsizer = new wxBoxSizer(wxHORIZONTAL); certtab->SetSizer(certsizer); wxPanel* certgrid = new wxPanel(certtab, -1); certgrid->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* cgsizer = new wxBoxSizer(wxVERTICAL); certgrid->SetSizer(cgsizer); cert_tree = new CertTree(certgrid, tc_CertTree, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE | wxBORDER_NONE); //wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); cert_tree->SetBackgroundColour(wxColour(255, 255, 255)); cert_tree->Build(CERTLIST_FLAGS); CertTreeReset(); cgsizer->Add(cert_tree, 1, wxEXPAND); cert_select_label = new wxStaticText(certgrid, -1, wxT("\nSelect a Callsign Certificate to process")); cgsizer->Add(cert_select_label, 0, wxALL, 1); certsizer->Add(certgrid, 50, wxEXPAND); wxStaticLine *certsep =new wxStaticLine(certtab, -1, wxDefaultPosition, wxSize(2, -1), wxLI_VERTICAL); certsizer->Add(certsep, 0, wxEXPAND); wxPanel* cbuttons = new wxPanel(certtab, -1); cbuttons->SetBackgroundColour(wxColour(255, 255, 255)); certsizer->Add(cbuttons, 50, wxEXPAND, 0); wxBoxSizer* cbsizer = new wxBoxSizer(wxVERTICAL); cbuttons->SetSizer(cbsizer); wxPanel* cb1Panel = new wxPanel(cbuttons); cb1Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* cb1sizer = new wxBoxSizer(wxHORIZONTAL); cb1Panel->SetSizer(cb1sizer); cert_load_button = new wxBitmapButton(cb1Panel, tc_Load, importbm); cert_load_button->SetBitmapDisabled(delete_disbm); cb1sizer->Add(cert_load_button, 0, wxALL, 1); cert_load_label = new wxStaticText(cb1Panel, -1, wxT("\nLoad a Callsign Certificate"), wxDefaultPosition, wxSize(tw, th)); cb1sizer->Add(cert_load_label, 1, wxFIXED_MINSIZE | wxALL, 1); cbsizer->Add(cb1Panel, 1, wxALL, 1); wxPanel* cb2Panel = new wxPanel(cbuttons); cb2Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* cb2sizer = new wxBoxSizer(wxHORIZONTAL); cb2Panel->SetSizer(cb2sizer); cert_save_button = new wxBitmapButton(cb2Panel, tc_CertSave, downloadbm); cert_save_button->SetBitmapDisabled(download_disbm); cert_save_button->Enable(false); cb2sizer->Add(cert_save_button, 0, wxALL, 1); cert_save_label = new wxStaticText(cb2Panel, -1, wxT("\nSave a Callsign Certificate"), wxDefaultPosition, wxSize(tw, th)); cb2sizer->Add(cert_save_label, 1, wxFIXED_MINSIZE | wxALL, 1); cbsizer->Add(cb2Panel, 1, wxALL, 1); wxPanel* cb3Panel = new wxPanel(cbuttons); cb3Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* cb3sizer = new wxBoxSizer(wxHORIZONTAL); cb3Panel->SetSizer(cb3sizer); cert_renew_button = new wxBitmapButton(cb3Panel, tc_CertRenew, uploadbm); cert_renew_button->SetBitmapDisabled(upload_disbm); cert_renew_button->Enable(false); cb3sizer->Add(cert_renew_button, 0, wxALL, 1); cert_renew_label = new wxStaticText(cb3Panel, -1, wxT("\nRenew a Callsign Certificate"), wxDefaultPosition, wxSize(tw, th)); cb3sizer->Add(cert_renew_label, 1, wxFIXED_MINSIZE | wxALL, 1); cbsizer->Add(cb3Panel, 1, wxALL, 1); wxPanel* cb4Panel = new wxPanel(cbuttons); cb4Panel->SetBackgroundColour(wxColour(255, 255, 255)); wxBoxSizer* cb4sizer = new wxBoxSizer(wxHORIZONTAL); cb4Panel->SetSizer(cb4sizer); cert_prop_button = new wxBitmapButton(cb4Panel, tc_CertProp, propertiesbm); cert_prop_button->SetBitmapDisabled(properties_disbm); cert_prop_button->Enable(false); cb4sizer->Add(cert_prop_button, 0, wxALL, 1); cert_prop_label = new wxStaticText(cb4Panel, -1, wxT("\nDisplay a Callsign Certificate's Properties"), wxDefaultPosition, wxSize(tw, th)); cb4sizer->Add(cert_prop_label, 1, wxFIXED_MINSIZE | wxALL, 1); cbsizer->Add(cb4Panel, 1, wxALL, 1); notebook->AddPage(certtab, wxT("Callsign Certificates")); //app icon SetIcon(wxIcon(key_xpm)); if (checkUpdates) { LogList *log = new LogList(this); wxLog::SetActiveTarget(log); // Start the autoupdate check 2 seconds after the page shows up _timer = new wxTimer(this, tm_f_autoupdate); _timer->Start(2000, true); } } static wxString run_station_wizard(wxWindow *parent, tQSL_Location loc, wxHtmlHelpController *help = 0, bool expired = false, wxString title = wxT("Add Station Location"), wxString dataname = wxT(""), wxString callsign = wxT("")) { tqslTrace("run_station_wizard", "loc=%lx, expired=%d, title=%s, dataname=%s, callsign=%s", loc, expired, _S(title), _S(dataname), _S(callsign)); wxString rval(wxT("")); get_certlist("", 0, expired, false); if (ncerts == 0) throw TQSLException("No certificates available"); TQSLWizard *wiz = new TQSLWizard(loc, parent, help, title, expired); wiz->SetDefaultCallsign(callsign); wiz->GetPage(true); TQSLWizCertPage *cpage = (TQSLWizCertPage*) wiz->GetPage(); if (cpage && !callsign.IsEmpty()) cpage->UpdateFields(0); TQSLWizPage *page = wiz->GetPage(); if (page == 0) throw TQSLException("Error getting first wizard page"); wiz->AdjustSize(); // Note: If dynamically created pages are larger than the pages already // created (the initial page and the final page), the wizard will need to // be resized, but we don't presently have that happening. (The final // page is larger than all expected dynamic pages.) bool okay = wiz->RunWizard(page); rval = wiz->GetLocationName(); wiz->Destroy(); if (!okay) return rval; check_tqsl_error(tqsl_setStationLocationCaptureName(loc, rval.mb_str())); check_tqsl_error(tqsl_saveStationLocationCapture(loc, 1)); return rval; } void MyFrame::OnHelpContents(wxCommandEvent& WXUNUSED(event)) { help->Display(wxT("main.htm")); } // Return the "About" string // static wxString getAbout() { wxString msg = wxT("TQSL V") wxT(VERSION) wxT(" build ") wxT(BUILD) wxT("\n(c) 2001-2013\nAmerican Radio Relay League\n\n"); int major, minor; if (tqsl_getVersion(&major, &minor)) wxLogError(wxT("%hs"), tqsl_getErrorString()); else msg += wxString::Format(wxT("TrustedQSL library V%d.%d\n"), major, minor); if (tqsl_getConfigVersion(&major, &minor)) wxLogError(wxT("%hs"), tqsl_getErrorString()); else msg += wxString::Format(wxT("\nConfiguration data V%d.%d\n\n"), major, minor); msg += wxVERSION_STRING; #ifdef wxUSE_UNICODE if (wxUSE_UNICODE) msg += wxT(" (Unicode)"); #endif msg+=wxString::Format(wxT("\nlibcurl V%hs\n"), LIBCURL_VERSION); msg+=wxString::Format(wxT("%hs\n"), OPENSSL_VERSION_TEXT); msg+=wxString::Format(wxT("zlib V%hs\n"), ZLIB_VERSION); msg+=wxString::Format(wxT("%hs"), DB_VERSION_STRING); return msg; } void MyFrame::OnHelpAbout(wxCommandEvent& WXUNUSED(event)) { wxMessageBox(getAbout(), wxT("About"), wxOK|wxCENTRE|wxICON_INFORMATION, this); } void MyFrame::OnHelpDiagnose(wxCommandEvent& event) { wxString s_fname; if (diagFile) { file_menu->Check(tm_f_diag, false); fclose(diagFile); diagFile = NULL; wxMessageBox(wxT("Diagnostic log closed"), wxT("Diagnostics"), wxOK|wxCENTRE|wxICON_INFORMATION, this); return; } s_fname = wxFileSelector(wxT("Log File"), wxT(""), wxT("tqsldiag.log"), wxT("log"), wxT("Log files (*.log)|*.log|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this); if (s_fname == wxT("")) { file_menu->Check(tm_f_diag, false); //would be better to not check at all, but no, apparently that's a crazy thing to want return; } diagFile = fopen(s_fname.mb_str(), "wb"); if (!diagFile) { wxString errmsg = wxString::Format(wxT("Error opening diagnostic log %s: %hs"), s_fname.c_str(), strerror(errno)); wxMessageBox(errmsg, wxT("Log File Error"), wxOK|wxICON_EXCLAMATION); return; } file_menu->Check(tm_f_diag, true); wxString about = getAbout(); fprintf(diagFile, "TQSL Diagnostics\n%s\n\n", (const char *)about.mb_str()); fprintf(diagFile, "Command Line: %s\n", (const char *)origCommandLine.mb_str()); fprintf(diagFile, "Working Directory:%s\n", tQSL_BaseDir); } static void AddEditStationLocation(tQSL_Location loc, bool expired = false, const wxString& title = wxT("Add Station Location"), const wxString& callsign = wxT("")) { tqslTrace("AddEditStationLocation", "loc=%lx, expired=%lx, title=%s, callsign=%s", loc, expired, _S(title), _S(callsign)); try { run_station_wizard(frame, loc, frame->help, expired, title, wxT(""), callsign); frame->loc_tree->Build(); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); } } void MyFrame::AddStationLocation(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::AddStationLocation"); wxTreeItemId root = loc_tree->GetRootItem(); wxTreeItemId id = loc_tree->GetSelection(); wxString call; if (id != root && id.IsOk()) { // If something selected LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(id); if (data) { call = data->getCallSign(); // Station location } else { call = loc_tree->GetItemText(id); // Callsign folder selected } tqslTrace("MyFrame::AddStationLocation", "Call selected is %s", _S(call)); } tQSL_Location loc; if (tqsl_initStationLocationCapture(&loc)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } AddEditStationLocation(loc, false, wxT("Add Station Location"), call); if (tqsl_endStationLocationCapture(&loc)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } loc_tree->Build(); LocTreeReset(); } void MyFrame::EditStationLocation(wxCommandEvent& event) { tqslTrace("MyFrame::EditStationLocation"); if (event.GetId() == tl_EditLoc) { LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(loc_tree->GetSelection()); tQSL_Location loc; wxString selname; char errbuf[512]; if (data == NULL) return; check_tqsl_error(tqsl_getStationLocation(&loc, data->getLocname().mb_str())); check_tqsl_error(tqsl_getStationLocationErrors(loc, errbuf, sizeof(errbuf))); if (strlen(errbuf) > 0) { wxMessageBox(wxString::Format(wxT("%hs\nThe invalid data was ignored."), errbuf), wxT("Location data error"), wxOK|wxICON_EXCLAMATION, this); } char loccall[512]; check_tqsl_error(tqsl_getLocationCallSign(loc, loccall, sizeof loccall)); selname = run_station_wizard(this, loc, help, true, wxString::Format(wxT("Edit Station Location : %hs - %s"), loccall, data->getLocname().c_str()), data->getLocname()); check_tqsl_error(tqsl_endStationLocationCapture(&loc)); loc_tree->Build(); LocTreeReset(); return; } try { SelectStationLocation(wxT("Edit Station Location"), wxT("Close"), true); loc_tree->Build(); LocTreeReset(); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); } } void MyFrame::WriteQSOFile(QSORecordList& recs, const char *fname, bool force) { tqslTrace("MyFrame::writeQSOFile", "fname=%s, force=%d", fname, force); if (recs.empty()) { wxLogWarning(wxT("No QSO records")); return; } wxString s_fname; if (fname) s_fname = wxString(fname, wxConvLocal); if (s_fname == wxT("") || !force) { wxString path, basename, type; wxSplitPath(s_fname, &path, &basename, &type); if (type != wxT("")) basename += wxT(".") + type; if (path == wxT("")) path = wxConfig::Get()->Read(wxT("QSODataPath"), wxT("")); s_fname = wxFileSelector(wxT("Save File"), path, basename, wxT("adi"), wxT("ADIF files (*.adi)|*.adi|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this); if (s_fname == wxT("")) return; wxConfig::Get()->Write(wxT("QSODataPath"), wxPathOnly(s_fname)); } ofstream out(s_fname.mb_str(), ios::out|ios::trunc|ios::binary); if (!out.is_open()) return; unsigned char buf[256]; QSORecordList::iterator it; for (it = recs.begin(); it != recs.end(); it++) { wxString dtstr; tqsl_adifMakeField("CALL", 0, (const unsigned char*)(const char *)it->_call.mb_str(), -1, buf, sizeof buf); out << buf << endl; tqsl_adifMakeField("BAND", 0, (const unsigned char*)(const char *)it->_band.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; tqsl_adifMakeField("MODE", 0, (const unsigned char*)(const char *)it->_mode.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; dtstr.Printf(wxT("%04d%02d%02d"), it->_date.year, it->_date.month, it->_date.day); tqsl_adifMakeField("QSO_DATE", 0, (const unsigned char*)(const char *)dtstr.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; dtstr.Printf(wxT("%02d%02d%02d"), it->_time.hour, it->_time.minute, it->_time.second); tqsl_adifMakeField("TIME_ON", 0, (const unsigned char*)(const char *)dtstr.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; if (it->_freq != wxT("")) { tqsl_adifMakeField("FREQ", 0, (const unsigned char*)(const char *)it->_freq.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; } if (it->_rxband != wxT("")) { tqsl_adifMakeField("BAND_RX", 0, (const unsigned char*)(const char *)it->_rxband.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; } if (it->_rxfreq != wxT("")) { tqsl_adifMakeField("FREQ_RX", 0, (const unsigned char*)(const char *)it->_rxfreq.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; } if (it->_propmode != wxT("")) { tqsl_adifMakeField("PROP_MODE", 0, (const unsigned char*)(const char *)it->_propmode.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; } if (it->_satellite != wxT("")) { tqsl_adifMakeField("SAT_NAME", 0, (const unsigned char*)(const char *)it->_satellite.mb_str(), -1, buf, sizeof buf); out << " " << buf << endl; } out << "" << endl; } out.close(); wxLogMessage(wxT("Wrote %d QSO records to %s"), (int)recs.size(), s_fname.c_str()); } static tqsl_adifFieldDefinitions fielddefs[] = { { "CALL", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_CALLSIGN_MAX, 0, 0, 0, 0 }, { "BAND", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_BAND_MAX, 0, 0, 0, 0 }, { "BAND_RX", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_BAND_MAX, 0, 0, 0, 0 }, { "MODE", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_MODE_MAX, 0, 0, 0, 0 }, { "FREQ", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_FREQ_MAX, 0, 0, 0, 0 }, { "FREQ_RX", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_FREQ_MAX, 0, 0, 0, 0 }, { "QSO_DATE", "", TQSL_ADIF_RANGE_TYPE_NONE, 8, 0, 0, 0, 0 }, { "TIME_ON", "", TQSL_ADIF_RANGE_TYPE_NONE, 6, 0, 0, 0, 0 }, { "SAT_NAME", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_SATNAME_MAX, 0, 0, 0, 0 }, { "PROP_MODE", "", TQSL_ADIF_RANGE_TYPE_NONE, TQSL_PROPMODE_MAX, 0, 0, 0, 0 }, { "EOR", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, 0, 0 }, { "", "", TQSL_ADIF_RANGE_TYPE_NONE, 0, 0, 0, 0, 0 }, }; static const char *defined_types[] = { "T", "D", "M", "C", "N", "6" }; static unsigned char * adif_alloc(size_t n) { return new unsigned char[n]; } void MyFrame::EditQSOData(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::EditQSOData"); QSORecordList recs; wxString file = wxFileSelector(wxT("Open File"), wxConfig::Get()->Read(wxT("QSODataPath"), wxT("")), wxT(""), wxT("adi"), wxT("ADIF files (*.adi)|*.adi|All files (*.*)|*.*"), wxOPEN|wxFILE_MUST_EXIST, this); if (file == wxT("")) return; init_modes(); tqsl_adifFieldResults field; TQSL_ADIF_GET_FIELD_ERROR stat; tQSL_ADIF adif; if (tqsl_beginADIF(&adif, file.mb_str())) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } QSORecord rec; do { if (tqsl_getADIFField(adif, &field, &stat, fielddefs, defined_types, adif_alloc)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } if (stat == TQSL_ADIF_GET_FIELD_SUCCESS) { if (!strcasecmp(field.name, "CALL")) rec._call = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "BAND")) rec._band = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "BAND_RX")) rec._rxband = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "MODE")) { rec._mode = wxString((const char *)field.data, wxConvLocal); char amode[40]; if (tqsl_getADIFMode(rec._mode.mb_str(), amode, sizeof amode) == 0 && amode[0] != '\0') rec._mode = wxString(amode, wxConvLocal); } else if (!strcasecmp(field.name, "FREQ")) rec._freq = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "FREQ_RX")) rec._rxfreq = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "PROP_MODE")) rec._propmode = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "SAT_NAME")) rec._satellite = wxString((const char *)field.data, wxConvLocal); else if (!strcasecmp(field.name, "QSO_DATE")) { char *cp = (char *)field.data; if (strlen(cp) == 8) { rec._date.day = strtol(cp+6, NULL, 10); *(cp+6) = '\0'; rec._date.month = strtol(cp+4, NULL, 10); *(cp+4) = '\0'; rec._date.year = strtol(cp, NULL, 10); } } else if (!strcasecmp(field.name, "TIME_ON")) { char *cp = (char *)field.data; if (strlen(cp) >= 4) { rec._time.second = (strlen(cp) > 4) ? strtol(cp+4, NULL, 10) : 0; *(cp+4) = 0; rec._time.minute = strtol(cp+2, NULL, 10); *(cp+2) = '\0'; rec._time.hour = strtol(cp, NULL, 10); } } else if (!strcasecmp(field.name, "EOR")) { recs.push_back(rec); rec = QSORecord(); } delete[] field.data; } } while (stat == TQSL_ADIF_GET_FIELD_SUCCESS || stat == TQSL_ADIF_GET_FIELD_NO_NAME_MATCH); tqsl_endADIF(&adif); try { QSODataDialog dial(this, help, &recs); if (dial.ShowModal() == wxID_OK) WriteQSOFile(recs, file.mb_str()); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); } } void MyFrame::EnterQSOData(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::EnterQSOData"); QSORecordList recs; try { QSODataDialog dial(this, help, &recs); if (dial.ShowModal() == wxID_OK) WriteQSOFile(recs); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); } } int MyFrame::ConvertLogToString(tQSL_Location loc, wxString& infile, wxString& output, int& n, tQSL_Converter& conv, bool suppressdate, tQSL_Date* startdate, tQSL_Date* enddate, int action, const char* password) { tqslTrace("MyFrame::ConvertLogToString", "loc = %lx, infile=%s, output=%s n=%d conv=%lx, suppressdate=%d, startdate=0x%lx, enddate=0x%lx, action=%d",(void*)loc, _S(infile), _S(output), (void *)conv, suppressdate, (void *)startdate, (void *)enddate, action); static const char *iam = "TQSL V" VERSION; const char *cp; char callsign[40]; int dxcc; wxString name, ext; bool allow_dupes = false; bool restarting = false; bool ignore_err = false; wxConfig *config = (wxConfig *)wxConfig::Get(); check_tqsl_error(tqsl_getLocationCallSign(loc, callsign, sizeof callsign)); check_tqsl_error(tqsl_getLocationDXCCEntity(loc, &dxcc)); DXCC dx; dx.getByEntity(dxcc); get_certlist(callsign, dxcc, false, false); if (ncerts == 0) { wxString msg = wxString::Format(wxT("There are no valid callsign certificates for callsign %hs in entity %hs.\nSigning aborted.\n"), callsign, dx.name()); throw TQSLException(msg.mb_str()); return TQSL_EXIT_TQSL_ERROR; } wxLogMessage(wxT("Signing using Callsign %hs, DXCC Entity %hs"), callsign, dx.name()); init_modes(); init_contests(); restart: ConvertingDialog *conv_dial = new ConvertingDialog(this, infile.mb_str()); n=0; bool cancelled = false; bool aborted = false; int lineno = 0; int out_of_range = 0; int duplicates = 0; int processed = 0; int errors = 0; try { if (tqsl_beginCabrilloConverter(&conv, infile.mb_str(), certlist, ncerts, loc)) { if (tQSL_Error != TQSL_CABRILLO_ERROR || tQSL_Cabrillo_Error != TQSL_CABRILLO_NO_START_RECORD) check_tqsl_error(1); // A bad error lineno = 0; check_tqsl_error(tqsl_beginADIFConverter(&conv, infile.mb_str(), certlist, ncerts, loc)); } bool range = true; config->Read(wxT("DateRange"), &range); if (range && !suppressdate && !restarting) { DateRangeDialog dial(this); if (dial.ShowModal() != wxOK) { wxLogMessage(wxT("Cancelled")); return TQSL_EXIT_CANCEL; } tqsl_setADIFConverterDateFilter(conv, &dial.start, &dial.end); if (this->IsQuiet()) { this->Show(false); wxSafeYield(this); } } if (startdate || enddate) { tqslTrace("MyFrame::ConvertLogToString", "startdate %d/%d/%d, enddate %d/%d/%d", startdate ? startdate->year : 0, startdate ? startdate->month : 0, startdate ? startdate->day : 0, enddate ? enddate->year : 0, enddate ? enddate->month : 0, enddate ? enddate->day : 0); tqsl_setADIFConverterDateFilter(conv, startdate, enddate); } bool allow = false; config->Read(wxT("BadCalls"), &allow); tqsl_setConverterAllowBadCall(conv, allow); tqsl_setConverterAllowDuplicates(conv, allow_dupes); tqsl_setConverterAppName(conv, iam); wxSplitPath(infile, 0, &name, &ext); if (ext != wxT("")) name += wxT(".") + ext; // Only display windows if notin batch mode -- KD6PAG if (!this->IsQuiet()) { conv_dial->Show(TRUE); } this->Enable(FALSE); output = wxT(""); do { while ((cp = tqsl_getConverterGABBI(conv)) != 0) { if (!this->IsQuiet()) wxSafeYield(conv_dial); if (!conv_dial->running) break; // Only count QSO records if (strstr(cp, "tCONTACT")) { ++n; ++processed; } if ((processed % 10) == 0) { wxString progress = wxString::Format(wxT("QSOs: %d"), processed); if (duplicates > 0) progress += wxString::Format(wxT(" Duplicates: %d"), duplicates); if (errors > 0 || out_of_range > 0) progress += wxString::Format(wxT(" Errors: %d"), errors + out_of_range); conv_dial->msg->SetLabel(progress); } output<<(wxString(cp, wxConvLocal)+wxT("\n")); } if ((processed % 10) == 0) { wxString progress = wxString::Format(wxT("QSOs: %d"), processed); if (duplicates > 0) progress += wxString::Format(wxT(" Duplicates: %d"), duplicates); if (errors > 0 || out_of_range > 0) progress += wxString::Format(wxT(" Errors: %d"), errors + out_of_range); conv_dial->msg->SetLabel(progress); } if (cp == 0) { if (!this->IsQuiet()) wxSafeYield(conv_dial); if (!conv_dial->running) break; } if (tQSL_Error == TQSL_SIGNINIT_ERROR) { tQSL_Cert cert; int rval; check_tqsl_error(tqsl_getConverterCert(conv, &cert)); do { if ((rval = tqsl_beginSigning(cert, (char *)password, getCertPassword, cert)) == 0) break; if (tQSL_Error == TQSL_PASSWORD_ERROR) { wxLogMessage(wxT("Password error")); if (password) free((void *)password); password = NULL; } } while (tQSL_Error == TQSL_PASSWORD_ERROR); check_tqsl_error(rval); if (this->IsQuiet()) { this->Show(false); wxSafeYield(this); } continue; } if (tQSL_Error == TQSL_DATE_OUT_OF_RANGE) { processed++; out_of_range++; continue; } if (tQSL_Error == TQSL_CERT_DATE_MISMATCH) { processed++; } if (tQSL_Error == TQSL_DUPLICATE_QSO) { processed++; duplicates++; continue; } bool has_error = (tQSL_Error != TQSL_NO_ERROR); if (has_error) { errors++; try { check_tqsl_error(1); } catch (TQSLException& x) { tqsl_getConverterLine(conv, &lineno); wxString msg = wxString(x.what(), wxConvLocal); if (lineno) msg += wxString::Format(wxT(" on line %d"), lineno); const char *bad_text = tqsl_getConverterRecordText(conv); if (bad_text) msg += wxString(wxT("\n")) + wxString(bad_text, wxConvLocal); wxLogError(wxT("%s"), msg.c_str()); if (frame->IsQuiet()) { switch (action) { case TQSL_ACTION_ABORT: aborted = true; ignore_err = true; goto abortSigning; case TQSL_ACTION_NEW: // For ALL or NEW, let the signing proceed case TQSL_ACTION_ALL: ignore_err = true; break; case TQSL_ACTION_ASK: case TQSL_ACTION_UNSPEC: break; // The error will show as a popup } } if (!ignore_err) { tqslTrace("MyFrame::ConvertLogToString", "Error: %s/asking for action", _S(msg)); ErrorsDialog dial(this, msg + wxT("\nClick 'Ignore' to continue signing this log while ignoring errors.\n") wxT("Click 'Cancel' to abandon signing this log.")); int choice = dial.ShowModal(); if (choice == TQSL_AE_CAN) { cancelled = true; goto abortSigning; } if (choice == TQSL_AE_OK) { ignore_err = true; if (this->IsQuiet()) { this->Show(false); wxSafeYield(this); } } } } } tqsl_getErrorString(); // Clear error if (has_error && ignore_err) continue; break; } while (1); cancelled = !conv_dial->running; abortSigning: this->Enable(TRUE); if (cancelled) { wxLogWarning(wxT("Signing cancelled")); n = 0; } else if (aborted) { wxLogWarning(wxT("Signing aborted")); n = 0; } else if (tQSL_Error != TQSL_NO_ERROR) { check_tqsl_error(1); } delete conv_dial; } catch (TQSLException& x) { this->Enable(TRUE); delete conv_dial; string msg = x.what(); tqsl_getConverterLine(conv, &lineno); tqsl_converterRollBack(conv); tqsl_endConverter(&conv); if (lineno) msg += wxString::Format(wxT(" on line %d"), lineno).mb_str(); wxLogError(wxT("Signing aborted due to errors")); throw TQSLException(msg.c_str()); } if (!cancelled && out_of_range > 0) wxLogMessage(wxT("%s: %d QSO records were outside the selected date range"), infile.c_str(), out_of_range); if (duplicates > 0) { if (cancelled) { tqsl_converterRollBack(conv); tqsl_endConverter(&conv); return TQSL_EXIT_CANCEL; } if (action == TQSL_ACTION_ASK || action==TQSL_ACTION_UNSPEC) { // want to ask the user DupesDialog dial(this, processed, duplicates, action); int choice = dial.ShowModal(); if (choice == TQSL_DP_CAN) { wxLogMessage(wxT("Cancelled")); tqsl_converterRollBack(conv); tqsl_endConverter(&conv); return TQSL_EXIT_CANCEL; } if (choice == TQSL_DP_ALLOW) { allow_dupes = true; tqsl_converterRollBack(conv); tqsl_endConverter(&conv); restarting = true; if (this->IsQuiet()) { this->Show(false); wxSafeYield(this); } goto restart; } } else if (action == TQSL_ACTION_ABORT) { if (processed==duplicates) { wxLogMessage(wxT("All QSOs are duplicates; aborted")); tqsl_converterRollBack(conv); tqsl_endConverter(&conv); n = 0; return TQSL_EXIT_NO_QSOS; } else { wxLogMessage(wxT("%d of %d QSOs are duplicates; aborted"), duplicates, processed); tqsl_converterRollBack(conv); tqsl_endConverter(&conv); n = 0; return TQSL_EXIT_NO_QSOS; } } else if (action == TQSL_ACTION_ALL) { allow_dupes = true; tqsl_converterRollBack(conv); tqsl_endConverter(&conv); restarting = true; goto restart; } // Otherwise it must be TQSL_ACTION_NEW, so fall through // and output the new records. wxLogMessage(wxT("%s: %d QSO records were duplicates"), infile.c_str(), duplicates); } //if (!cancelled) tqsl_converterCommit(conv); if (cancelled || processed == 0) { tqsl_converterRollBack(conv); tqsl_endConverter(&conv); } if (cancelled) return TQSL_EXIT_CANCEL; if (processed == 0) return TQSL_EXIT_NO_QSOS; if (aborted || duplicates > 0 || out_of_range > 0 || errors > 0) return TQSL_EXIT_QSOS_SUPPRESSED; return TQSL_EXIT_SUCCESS; } int MyFrame::ConvertLogFile(tQSL_Location loc, wxString& infile, wxString& outfile, bool compressed, bool suppressdate, tQSL_Date* startdate, tQSL_Date* enddate, int action, const char *password) { tqslTrace("MyFrame::ConvertLogFile", "loc=%lx, infile=%s, outfile=%s, compressed=%d, suppressdate=%d, startdate=0x%lx enddate=0x%lx action=%d", (void *)loc, _S(infile), _S(outfile), compressed, suppressdate, (void *)startdate, (void*) enddate, action); gzFile gout = 0; ofstream out; if (compressed) gout = gzopen(outfile.mb_str(), "wb9"); else out.open(outfile.mb_str(), ios::out|ios::trunc|ios::binary); if ((compressed && !gout) || (!compressed && !out)) { wxLogError(wxT("Unable to open %s for output"), outfile.c_str()); return TQSL_EXIT_ERR_OPEN_OUTPUT; } wxString output; int numrecs=0; tQSL_Converter conv=0; int status = this->ConvertLogToString(loc, infile, output, numrecs, conv, suppressdate, startdate, enddate, action, password); if (numrecs == 0) { wxLogMessage(wxT("No records output")); if (compressed) { gzclose(gout); } else { out.close(); } unlink(outfile.mb_str()); if (status == TQSL_EXIT_CANCEL || TQSL_EXIT_QSOS_SUPPRESSED) return status; else return TQSL_EXIT_NO_QSOS; } else { if(compressed) { if (0>=gzwrite(gout, output.mb_str(), output.size()) || Z_OK!=gzclose(gout)) { tqsl_converterRollBack(conv); tqsl_endConverter(&conv); return TQSL_EXIT_LIB_ERROR; } } else { out<internal_recv(ptr, size, nmemb); } }; class ConfigFileDownloadHandler { public: void *s; size_t allocated; size_t used; ConfigFileDownloadHandler(size_t _size): s() { allocated = _size; s = malloc(_size); used = 0; } ~ConfigFileDownloadHandler(void); size_t internal_recv( char *ptr, size_t size, size_t nmemb) { size_t newlen = used + (size * nmemb); if (newlen > allocated) { s = realloc(s, newlen + 2000); allocated += newlen + 2000; } memcpy((char *)s+used, ptr, size * nmemb); used += size*nmemb; return size*nmemb; } static size_t recv( char *ptr, size_t size, size_t nmemb, void *userdata) { return ((ConfigFileDownloadHandler*)userdata)->internal_recv(ptr, size, nmemb); } }; ConfigFileDownloadHandler::~ConfigFileDownloadHandler(void) { if (s) free(s); } long compressToBuf(string& buf, const char* input) { tqslTrace("compressToBuf"); const size_t TBUFSIZ=128*1024; uint8_t* tbuf=new uint8_t[TBUFSIZ]; //vector buf; z_stream stream; stream.zalloc=0; stream.zfree=0; stream.next_in=(Bytef*)input; stream.avail_in=strlen(input); stream.next_out=tbuf; stream.avail_out=TBUFSIZ; //deflateInit(&stream, Z_BEST_COMPRESSION); deflateInit2(&stream, Z_BEST_COMPRESSION, Z_DEFLATED, 16+15, 9, Z_DEFAULT_STRATEGY); //use gzip header while (stream.avail_in) { //while still some left int res=deflate(&stream, Z_NO_FLUSH); assert(res==Z_OK); if (!stream.avail_out) { buf.insert(buf.end(), tbuf, tbuf+TBUFSIZ); stream.next_out=tbuf; stream.avail_out=TBUFSIZ; } } do { if (stream.avail_out==0) { buf.insert(buf.end(), tbuf, tbuf+TBUFSIZ); stream.next_out=tbuf; stream.avail_out=TBUFSIZ; } } while (deflate(&stream, Z_FINISH)==Z_OK); buf.insert(buf.end(), tbuf, tbuf+TBUFSIZ-stream.avail_out); deflateEnd(&stream); delete tbuf; return buf.length(); } class UploadThread: public wxThread { public: UploadThread(CURL* handle_, wxDialog* dial_): wxThread(wxTHREAD_JOINABLE), handle(handle_), dial(dial_) { wxThread::Create(); } protected: CURL* handle; wxDialog* dial; virtual wxThread::ExitCode Entry() { int ret=curl_easy_perform(handle); wxCommandEvent evt(wxEVT_LOGUPLOAD_DONE, wxID_ANY); dial->AddPendingEvent(evt); return (wxThread::ExitCode)((intptr_t)ret); } }; int MyFrame::UploadLogFile(tQSL_Location loc, wxString& infile, bool compressed, bool suppressdate, tQSL_Date* startdate, tQSL_Date* enddate, int action, const char* password) { tqslTrace("MyFrame::UploadLogFile", "loc=%lx, infile=%s, compressed=%d, suppressdate=%d, startdate=0x%lx, enddate=0x%lx action=%d", (void *)loc, _S(infile), compressed, suppressdate, (void *)startdate, (void *)enddate, action); int numrecs=0; wxString signedOutput; tQSL_Converter conv=0; int status = this->ConvertLogToString(loc, infile, signedOutput, numrecs, conv, suppressdate, startdate, enddate, action, password); if (numrecs == 0) { wxLogMessage(wxT("No records to upload")); if (status == TQSL_EXIT_CANCEL || TQSL_EXIT_QSOS_SUPPRESSED) return status; else return TQSL_EXIT_NO_QSOS; } else { //compress the upload string compressed; size_t compressedSize=compressToBuf(compressed, (const char*)signedOutput.mb_str()); //ofstream f; f.open("testzip.tq8", ios::binary); f< %s"), now.Format(wxT("%Y%m%d")).c_str(), now.Format(wxT("%H%M")).c_str(), name.c_str()).mb_str(), sizeof filename); filename[sizeof filename - 1] = '\0'; wxString fileType(wxT("Log")); int retval = UploadFile(infile, filename, numrecs, (void *)compressed.c_str(), compressedSize, fileType); if (retval==0) tqsl_converterCommit(conv); else tqsl_converterRollBack(conv); tqsl_endConverter(&conv); return retval; } } static CURL* tqsl_curl_init(const char *logTitle, const char *url, FILE **logFile, bool newFile) { CURL* req=curl_easy_init(); if (!req) return NULL; if (diagFile) { curl_easy_setopt(req, CURLOPT_VERBOSE, 1); curl_easy_setopt(req, CURLOPT_STDERR, diagFile); fprintf(diagFile, "%s\n", logTitle); } else { if (logFile) { wxString filename; #ifdef _WIN32 filename.Printf(wxT("%hs\\curl.log"), tQSL_BaseDir); #else filename.Printf(wxT("%hs/curl.log"), tQSL_BaseDir); #endif *logFile = fopen(filename.mb_str(), newFile ? "wb" : "ab"); if (*logFile) { curl_easy_setopt(req, CURLOPT_VERBOSE, 1); curl_easy_setopt(req, CURLOPT_STDERR, *logFile); fprintf(*logFile, "%s:\n", logTitle); } } } //set up options curl_easy_setopt(req, CURLOPT_URL, url); // Get the proxy configuration and pass it to cURL wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/Proxy")); bool enabled; config->Read(wxT("proxyEnabled"), &enabled, false); wxString pHost = config->Read(wxT("proxyHost"), wxT("")); wxString pPort = config->Read(wxT("proxyPort"), wxT("")); wxString pType = config->Read(wxT("proxyType"), wxT("")); config->SetPath(wxT("/")); if (!enabled) return req; // No proxy defined long port = strtol(pPort.mb_str(), NULL, 10); if (port == 0 || pHost.IsEmpty()) return req; // Invalid proxy. Ignore it. curl_easy_setopt(req, CURLOPT_PROXY, (const char *)pHost.mb_str()); curl_easy_setopt(req, CURLOPT_PROXYPORT, port); if (pType == wxT("HTTP")) { curl_easy_setopt(req, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); // Default is HTTP } else if (pType == wxT("Socks4")) { curl_easy_setopt(req, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); } else if (pType == wxT("Socks5")) { curl_easy_setopt(req, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } return req; } int MyFrame::UploadFile(wxString& infile, const char* filename, int numrecs, void *content, size_t clen, wxString& fileType) { tqslTrace("MyFrame::UploadFile", "infile=%s, filename=%s, numrecs=%d, content=0x%lx, clen=%d fileType=%s", _S(infile), filename, numrecs, (void *)content, clen, _S(fileType)); FILE *logFile = NULL; //upload the file //get the url from the config, can be overridden by an installer //defaults are valid for LoTW as of 1/31/2013 wxConfig *config = (wxConfig *)wxConfig::Get(); config->SetPath(wxT("/LogUpload")); wxString uploadURL=config->Read(wxT("UploadURL"), DEFAULT_UPL_URL); wxString uploadField=config->Read(wxT("PostField"), DEFAULT_UPL_FIELD); wxString uplStatus=config->Read(wxT("StatusRegex"), DEFAULT_UPL_STATUSRE); wxString uplStatusSuccess=config->Read(wxT("StatusSuccess"), DEFAULT_UPL_STATUSOK).Lower(); wxString uplMessage=config->Read(wxT("MessageRegex"), DEFAULT_UPL_MESSAGERE); bool uplVerifyCA; config->Read(wxT("VerifyCA"), &uplVerifyCA, DEFAULT_UPL_VERIFYCA); config->SetPath(wxT("/")); // Copy the strings so they remain around char *urlstr = strdup(uploadURL.mb_str()); char *cpUF = strdup(uploadField.mb_str()); retry_upload: CURL* req=tqsl_curl_init("Upload Log", urlstr, &logFile, true); if (!req) { wxLogMessage(wxT("Error: Could not upload file (CURL Init error)")); free(urlstr); free(cpUF); return TQSL_EXIT_TQSL_ERROR; } //the following allow us to write our log and read the result FileUploadHandler handler; curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, &FileUploadHandler::recv); curl_easy_setopt(req, CURLOPT_WRITEDATA, &handler); curl_easy_setopt(req, CURLOPT_SSL_VERIFYPEER, uplVerifyCA); char errorbuf[CURL_ERROR_SIZE]; curl_easy_setopt(req, CURLOPT_ERRORBUFFER, errorbuf); struct curl_httppost* post=NULL, *lastitem=NULL; curl_formadd(&post, &lastitem, CURLFORM_PTRNAME, cpUF, CURLFORM_BUFFER, filename, CURLFORM_BUFFERPTR, content, CURLFORM_BUFFERLENGTH, clen, CURLFORM_END); curl_easy_setopt(req, CURLOPT_HTTPPOST, post); intptr_t retval; UploadDialog* upload; if (numrecs > 0) wxLogMessage(wxT("Attempting to upload %d QSO%hs"), numrecs, numrecs == 1 ? "" : "s"); else wxLogMessage(wxT("Attempting to upload %s"), fileType.c_str()); if(this) { upload=new UploadDialog(this); curl_easy_setopt(req, CURLOPT_PROGRESSFUNCTION, &UploadDialog::UpdateProgress); curl_easy_setopt(req, CURLOPT_PROGRESSDATA, upload); curl_easy_setopt(req, CURLOPT_NOPROGRESS, 0); UploadThread thread(req, upload); if (thread.Run() != wxTHREAD_NO_ERROR) { wxLogError(wxT("Could not spawn upload thread!")); upload->Destroy(); free(urlstr); free(cpUF); if (logFile) fclose(logFile); return TQSL_EXIT_TQSL_ERROR; } upload->ShowModal(); retval=((intptr_t)thread.Wait()); } else { retval=curl_easy_perform(req); } if (retval==0) { //success //check the result wxString uplresult=wxString::FromAscii(handler.s.c_str()); wxRegEx uplStatusRE(uplStatus); wxRegEx uplMessageRE(uplMessage); if (uplStatusRE.Matches(uplresult)) //we can make sense of the error { //sometimes has leading/trailing spaces if (uplStatusRE.GetMatch(uplresult, 1).Lower().Strip(wxString::both)==uplStatusSuccess) //success { if (uplMessageRE.Matches(uplresult)) { //and a message wxString lotwmessage = uplMessageRE.GetMatch(uplresult, 1).Trim(); if (fileType == wxT("Log")) { wxLogMessage(wxT("%s: Log uploaded successfully with result \"%s\"!\nAfter reading this message, you may close this program."), infile.c_str(), lotwmessage.c_str()); } else { wxLogMessage(wxT("%s uploaded with result \"%s\"!"), fileType.c_str(), lotwmessage.c_str()); } } else { // no message we could find if (fileType == wxT("Log")) { wxLogMessage(wxT("%s: Log uploaded successfully!\nAfter reading this message, you may close this program."), infile.c_str()); } else { wxLogMessage(wxT("%s uploaded successfully!"), fileType.c_str()); } } retval=TQSL_EXIT_SUCCESS; } else { // failure, but site is working if (uplMessageRE.Matches(uplresult)) { //and a message wxLogMessage(wxT("%s: %s upload was rejected with result \"%s\""), infile.c_str(), fileType.c_str(), uplMessageRE.GetMatch(uplresult, 1).c_str()); } else { // no message we could find wxLogMessage(wxT("%s: %s upload was rejected!"), infile.c_str(), fileType.c_str()); } retval=TQSL_EXIT_REJECTED; } } else { //site isn't working wxLogMessage(wxT("%s: Got an unexpected response on %s upload! Maybe the site is down?"), infile.c_str(), fileType.c_str()); retval=TQSL_EXIT_UNEXP_RESP; } } else { if (diagFile) { fprintf(diagFile, "cURL Error: %s (%s)\n", curl_easy_strerror((CURLcode)retval), errorbuf); } if (retval == CURLE_COULDNT_RESOLVE_HOST || retval == CURLE_COULDNT_CONNECT) { wxLogMessage(wxT("%s: Unable to upload - either your Internet connection is down or LoTW is unreachable.\nPlease try uploading the %s later."), infile.c_str(), fileType.c_str()); retval=TQSL_EXIT_CONNECTION_FAILED; } else if (retval == CURLE_WRITE_ERROR || retval == CURLE_SEND_ERROR || retval == CURLE_RECV_ERROR) { wxLogMessage(wxT("%s: Unable to upload. The nework is down or the LoTW site is too busy.\nPlease try uploading the %s later."), infile.c_str(), fileType.c_str()); retval=TQSL_EXIT_CONNECTION_FAILED; } else if (retval == CURLE_SSL_CONNECT_ERROR) { wxLogMessage(wxT("%s: Unable to connect to the upload site.\nPlease try uploading the %s later."), infile.c_str(), fileType.c_str()); retval=TQSL_EXIT_CONNECTION_FAILED; } else if (retval==CURLE_ABORTED_BY_CALLBACK) { //cancelled. wxLogMessage(wxT("%s: Upload cancelled"), infile.c_str()); retval=TQSL_EXIT_CANCEL; } else { //error //don't know why the conversion from char* -> wxString -> char* is necessary but it // was turned into garbage otherwise wxLogMessage(wxT("%s: Couldn't upload the file: CURL returned \"%hs\" (%hs)"), infile.c_str(), curl_easy_strerror((CURLcode)retval), errorbuf); retval=TQSL_EXIT_TQSL_ERROR; } } if (this) upload->Destroy(); curl_formfree(post); curl_easy_cleanup(req); // If there's a GUI and we didn't successfully upload and weren't cancelled, // ask the user if we should retry the upload. if (this && retval != TQSL_EXIT_CANCEL && retval != TQSL_EXIT_SUCCESS) { if (wxMessageBox(wxT("Your upload appears to have failed. Should TQSL try again?"), wxT("Retry?"), wxYES_NO, this) == wxYES) goto retry_upload; } if (urlstr) free(urlstr); if (cpUF) free (cpUF); if (logFile) fclose(logFile); return retval; } // Verify that a certificate exists for this station location // before allowing the location to be edited static bool verify_cert(tQSL_Location loc) { tqslTrace("verify_cert", "loc=%lx", (void *)loc); char call[128]; tQSL_Cert *certlist; int ncerts; // Get the callsign from the location check_tqsl_error(tqsl_getLocationCallSign(loc, call, sizeof(call))); // See if there is a certificate for that call tqsl_selectCertificates(&certlist, &ncerts, call, 0, 0, 0, TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED); if (ncerts == 0) { wxMessageBox(wxString::Format(wxT("There are no callsign certificates for callsign %hs. This station location cannot be edited."), call), wxT("No Certificate"), wxOK|wxICON_EXCLAMATION); return false; } for (int i = 0; i < ncerts; i++) tqsl_freeCertificate(certlist[i]); return true; } tQSL_Location MyFrame::SelectStationLocation(const wxString& title, const wxString& okLabel, bool editonly) { tqslTrace("MyFrame::SelectStationLocation", "title=%s, okLabel=%s, editonly=%d", _S(title), _S(okLabel), editonly); int rval; tQSL_Location loc; wxString selname; char errbuf[512]; do { TQSLGetStationNameDialog station_dial(this, help, wxDefaultPosition, false, title, okLabel, editonly); if (selname != wxT("")) station_dial.SelectName(selname); rval = station_dial.ShowModal(); switch (rval) { case wxID_CANCEL: // User hit Close return 0; case wxID_APPLY: // User hit New check_tqsl_error(tqsl_initStationLocationCapture(&loc)); selname = run_station_wizard(this, loc, help, false); check_tqsl_error(tqsl_endStationLocationCapture(&loc)); break; case wxID_MORE: // User hit Edit check_tqsl_error(tqsl_getStationLocation(&loc, station_dial.Selected().mb_str())); if (verify_cert(loc)) { // Check if there is a certificate before editing check_tqsl_error(tqsl_getStationLocationErrors(loc, errbuf, sizeof(errbuf))); if (strlen(errbuf) > 0) { wxMessageBox(wxString::Format(wxT("%hs\nThe invalid data was ignored."), errbuf), wxT("Station Location data error"), wxOK|wxICON_EXCLAMATION, this); } char loccall[512]; check_tqsl_error(tqsl_getLocationCallSign(loc, loccall, sizeof loccall)); selname = run_station_wizard(this, loc, help, true, wxString::Format(wxT("Edit Station Location : %hs - %s"), loccall, station_dial.Selected().c_str()), station_dial.Selected()); check_tqsl_error(tqsl_endStationLocationCapture(&loc)); } break; case wxID_OK: // User hit OK check_tqsl_error(tqsl_getStationLocation(&loc, station_dial.Selected().mb_str())); check_tqsl_error(tqsl_getStationLocationErrors(loc, errbuf, sizeof(errbuf))); if (strlen(errbuf) > 0) { wxMessageBox(wxString::Format(wxT("%hs\nThis should be corrected before signing a log file."), errbuf), wxT("Station Location data error"), wxOK|wxICON_EXCLAMATION, this); } break; } } while (rval != wxID_OK); return loc; } void MyFrame::CheckForUpdates(wxCommandEvent&) { tqslTrace("MyFrame::CheckForUpdates"); DoCheckForUpdates(false); } wxString GetUpdatePlatformString() { tqslTrace("GetUpdatePlatformString"); wxString ret; #if defined(_WIN32) #if defined(_WIN64) //this is 64 bit code already; if we are running we support 64 ret=wxT("win64 win32"); #else // this is not 64 bit code, but we are on windows // are we 64-bit compatible? if so prefer it BOOL val=false; typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"IsWow64Process"); if (fnIsWow64Process!=NULL) { fnIsWow64Process(GetCurrentProcess(), &val); } if(val) //32 bit running on 64 bit ret=wxT("win64 win32"); else //just 32-bit only ret=wxT("win32"); #endif #elif defined(__APPLE__) && defined(__MACH__) //osx has universal binaries ret=wxT("osx"); #elif defined(__gnu_linux__) #if defined(__amd64__) ret=wxT("linux64 linux32 source"); #elif defined(__i386__) ret=wxT("linux32 source"); #else ret=wxT("source"); //source distribution is kosher on linux #endif #else ret=wxT(""); //give them a homepage #endif return ret; } // Class for encapsulating version information class revLevel { public: revLevel(long _major = 0, long _minor = 0, long _patch = 0) { major = _major; minor = _minor; patch = _patch; } revLevel(const wxString& _value) { wxString str = _value; str.Trim(true); str.Trim(false); wxStringTokenizer vers(str, wxT(".")); wxString majorVer = vers.GetNextToken(); wxString minorVer = vers.GetNextToken(); wxString patchVer = vers.GetNextToken(); if (majorVer.IsNumber()) { majorVer.ToLong(&major); } else { major = -1; } if (minorVer.IsNumber()) { minorVer.ToLong(&minor); } else { minor = -1; } if (patchVer.IsNumber()) { patchVer.ToLong(&patch); } else { patch = 0; } } wxString Value(void) { if (patch > 0) return wxString::Format(wxT("%d.%d.%d"), major, minor, patch); else return wxString::Format(wxT("%d.%d"), major, minor); } long major; long minor; long patch; bool operator >(const revLevel& other) { if (major > other.major) return true; if (major == other.major) { if (minor > other.minor) return true; if (minor == other.minor) { if (patch > other.patch) return true; } } return false; } }; class UpdateDialogMsgBox: public wxDialog { public: UpdateDialogMsgBox(wxWindow* parent, bool newProg, bool newConfig, revLevel* currentProgRev, revLevel* newProgRev, revLevel* currentConfigRev, revLevel* newConfigRev, wxString platformURL, wxString homepage) : wxDialog(parent, (wxWindowID)wxID_ANY, wxT("TQSL Update Available"), wxDefaultPosition, wxDefaultSize) { tqslTrace("UpdateDialogMsgBox::UpdateDialogMsgBox", "parent=%lx, newProg=%d, newConfig=%d, currentProgRev %s, newProgRev %s, newConfigRev %s, currentConfigRev=%s, platformURL=%s, homepage=%s", (void*)parent, newProg, newConfig, _S(currentProgRev->Value()), _S(newProgRev->Value()), _S(currentConfigRev->Value()), _S(newConfigRev->Value()), _S(platformURL), _S(homepage)); wxSizer* overall=new wxBoxSizer(wxVERTICAL); long flags = wxOK; if (newConfig) flags |= wxCANCEL; wxSizer* buttons=CreateButtonSizer(flags); wxString notice; if (newProg) notice = wxString::Format(wxT("A new TQSL release (V%s) is available!"), newProgRev->Value().c_str()); else if (newConfig) notice = wxString::Format(wxT("A new TrustedQSL configuration file (V%s) is available!"), newConfigRev->Value().c_str()); overall->Add(new wxStaticText(this, wxID_ANY, notice), 0, wxALIGN_CENTER_HORIZONTAL); if (newProg) { if (!platformURL.IsEmpty()) { wxSizer* thisline=new wxBoxSizer(wxHORIZONTAL); thisline->Add(new wxStaticText(this, wxID_ANY, wxT("Download from:"))); thisline->Add(new wxHyperlinkCtrl(this, wxID_ANY, platformURL, platformURL)); overall->AddSpacer(10); overall->Add(thisline); } if (!homepage.IsEmpty()) { wxSizer* thisline=new wxBoxSizer(wxHORIZONTAL); thisline->Add(new wxStaticText(this, wxID_ANY, wxT("More details at:"))); thisline->Add(new wxHyperlinkCtrl(this, wxID_ANY, homepage, homepage)); overall->AddSpacer(10); overall->Add(thisline); } } if (newConfig) { overall->AddSpacer(10); overall->Add(new wxStaticText(this, wxID_ANY, wxT("Click 'OK' to install the new configuration file, or Cancel to ignore it."))); } if (buttons) { //should always be here but documentation says to check overall->AddSpacer(10); overall->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL); } wxSizer* padding=new wxBoxSizer(wxVERTICAL); padding->Add(overall, 0, wxALL, 10); SetSizer(padding); Fit(); } private: }; void MyFrame::UpdateConfigFile() { tqslTrace("MyFrame::UpdateConfigFile()"); wxConfig* config=(wxConfig*)wxConfig::Get(); wxString newConfigURL = config->Read(wxT("NewConfigURL"), DEFAULT_CONFIG_FILE_URL); FILE *logFile = NULL; CURL* req=tqsl_curl_init("Config File Download Log", (const char *)newConfigURL.mb_str(), &logFile, false); ConfigFileDownloadHandler handler(40000); curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, &ConfigFileDownloadHandler::recv); curl_easy_setopt(req, CURLOPT_WRITEDATA, &handler); curl_easy_setopt(req, CURLOPT_FAILONERROR, 1); //let us find out about a server issue char errorbuf[CURL_ERROR_SIZE]; curl_easy_setopt(req, CURLOPT_ERRORBUFFER, errorbuf); int retval = curl_easy_perform(req); if (retval == CURLE_OK) { char *newconfig = (char *)handler.s; wxString filename; #ifdef _WIN32 filename.Printf(wxT("%hs\\/config.tq6"), tQSL_BaseDir); #else filename.Printf(wxT("%hs/config.tq6"), tQSL_BaseDir); #endif FILE *configFile = fopen(filename.mb_str(), "wb"); if (!configFile) { wxMessageBox(wxString::Format(wxT("Can't open new configuration file %s: %hs"), filename.c_str(), strerror(errno))); curl_easy_cleanup(req); if (logFile) fclose(logFile); return; } size_t left = handler.used; while (left > 0) { size_t written = fwrite(newconfig, 1, left, configFile); if (written == 0) { wxMessageBox(wxString::Format(wxT("Can't write new configuration file %s: %hs"), filename.c_str(), strerror(errno))); curl_easy_cleanup(req); if (logFile) fclose(logFile); return; } left -= written; } if (fclose(configFile)) { wxMessageBox(wxString::Format(wxT("Error writing new configuration file %s: %hs"), filename.c_str(), strerror(errno))); curl_easy_cleanup(req); if (logFile) fclose(logFile); return; } notifyData nd; if (tqsl_importTQSLFile(filename.mb_str(), notifyImport, &nd)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } else { wxMessageBox(wxT("Configuration file successfully updated"), wxT("Update Completed"), wxOK|wxICON_INFORMATION, this); } } else { if (diagFile) { fprintf(diagFile, "cURL Error during config file download: %s (%s)\n", curl_easy_strerror((CURLcode)retval), errorbuf); } if (logFile) { fprintf(logFile, "cURL Error during config file download: %s (%s)\n", curl_easy_strerror((CURLcode)retval), errorbuf); } if (retval == CURLE_COULDNT_RESOLVE_HOST || retval == CURLE_COULDNT_CONNECT) { wxLogMessage(wxT("Unable to update - either your Internet connection is down or LoTW is unreachable.\nPlease try again later.")); } else if (retval == CURLE_WRITE_ERROR || retval == CURLE_SEND_ERROR || retval == CURLE_RECV_ERROR) { wxLogMessage(wxT("Unable to update. The nework is down or the LoTW site is too busy.\nPlease try again later.")); } else if (retval == CURLE_SSL_CONNECT_ERROR) { wxLogMessage(wxT("Unable to connect to the update site.\nPlease try again later.")); } else { // some other error wxMessageBox(wxString::Format(wxT("Error downloading new configuration file:\n%hs"), errorbuf), wxT("Update"), wxOK|wxICON_EXCLAMATION, this); } } curl_easy_cleanup(req); if (logFile) fclose(logFile); } // Check for certificates expiring in the next nn (default 60) days void MyFrame::DoCheckExpiringCerts(bool noGUI) { get_certlist("", 0, false, false); if (ncerts == 0) return; long expireDays = DEFAULT_CERT_WARNING; wxConfig::Get()->Read(wxT("CertWarnDays"), &expireDays); // Get today's date time_t t = time(0); struct tm *tm = gmtime(&t); tQSL_Date d; d.year = tm->tm_year + 1900; d.month = tm->tm_mon + 1; d.day = tm->tm_mday; tQSL_Date exp; for (int i = 0; i < ncerts; i ++) { if (0 == tqsl_getCertificateNotAfterDate(certlist[i], &exp)) { int days_left; tqsl_subtractDates(&d, &exp, &days_left); if (days_left < expireDays) { char callsign[64]; check_tqsl_error(tqsl_getCertificateCallSign(certlist[i], callsign, sizeof callsign)); if (noGUI) { wxLogMessage(wxT("The certificate for %hs expires in %d days."), callsign, days_left); } else { if (wxMessageBox( wxString::Format(wxT("The certificate for %hs expires in %d days\n") wxT("Do you want to renew it now?"), callsign, days_left), wxT("Certificate Expiring"), wxYES_NO|wxICON_QUESTION, this) == wxYES) { // Select the certificate in the tree cert_tree->SelectCert(certlist[i]); // Then start the renewal wxCommandEvent dummy; CRQWizardRenew(dummy); } } } } } free_certlist(); if (noGUI) { wxString pend = wxConfig::Get()->Read(wxT("RequestPending")); if (!pend.IsEmpty()){ if (pend.Find(wxT(",")) != wxNOT_FOUND) wxLogMessage(wxT("Callsign Certificate Requests are pending for %s."), pend.c_str()); else wxLogMessage(wxT("A Callsign Certificate Request for %s is pending."), pend.c_str()); } } return; } void MyFrame::DoCheckForUpdates(bool silent, bool noGUI) { tqslTrace("MyFrame::DoCheckForUpdates", "silent=%d, noGUI=%d", silent, noGUI); FILE *logFile = NULL; wxConfig* config=(wxConfig*)wxConfig::Get(); wxString lastUpdateTime=config->Read(wxT("UpdateCheckTime")); int numdays=config->Read(wxT("UpdateCheckInterval"), 1); // in days bool check=true; if (!lastUpdateTime.IsEmpty()) { wxDateTime lastcheck; lastcheck.ParseFormat(lastUpdateTime, wxT("%Y-%m-%d")); lastcheck+=wxDateSpan::Days(numdays); // x days from when we checked if (lastcheck>wxDateTime::Today()) //if we checked less than x days ago check=false; // don't check again } // else no stored value, means check if (!silent) check=true; //unless the user explicitly asked if (!check) return; //if we really weren't supposed to check, get out of here revLevel* programRev = new revLevel(wxT(VERSION)); int currentConfigMajor, currentConfigMinor; tqsl_getConfigVersion(¤tConfigMajor, ¤tConfigMinor); revLevel* configRev = new revLevel(currentConfigMajor, currentConfigMinor, 0); // config files don't have patch levels wxString updateURL=config->Read(wxT("UpdateURL"), DEFAULT_UPD_URL); CURL* req=tqsl_curl_init("Version Check Log", (const char*)updateURL.mb_str(), &logFile, true); //the following allow us to analyze our file FileUploadHandler handler; curl_easy_setopt(req, CURLOPT_WRITEFUNCTION, &FileUploadHandler::recv); curl_easy_setopt(req, CURLOPT_WRITEDATA, &handler); if(silent) { // if there's a problem, we don't want the program to hang while we're starting it curl_easy_setopt(req, CURLOPT_CONNECTTIMEOUT, 10); } curl_easy_setopt(req, CURLOPT_FAILONERROR, 1); //let us find out about a server issue char errorbuf[CURL_ERROR_SIZE]; curl_easy_setopt(req, CURLOPT_ERRORBUFFER, errorbuf); int retval = curl_easy_perform(req); if (retval == CURLE_OK) { tqslTrace("MyFrame::DoCheckForUpdates", "Program rev returns %d chars, %s", handler.s.size(), handler.s.c_str()); // Add the config.xml text to the result wxString configURL=config->Read(wxT("ConfigFileVerURL"), DEFAULT_UPD_CONFIG_URL); curl_easy_setopt(req, CURLOPT_URL, (const char*)configURL.mb_str()); retval = curl_easy_perform(req); if (retval == CURLE_OK) { tqslTrace("MyFrame::DoCheckForUpdates", "Prog + Config rev returns %d chars, %s", handler.s.size(), handler.s.c_str()); wxString result=wxString::FromAscii(handler.s.c_str()); wxString url; WX_DECLARE_STRING_HASH_MAP(wxString, URLHashMap); URLHashMap map; revLevel *newProgramRev = NULL; revLevel *newConfigRev = NULL; wxStringTokenizer urls(result, wxT("\n")); wxString onlinever; while(urls.HasMoreTokens()) { wxString header=urls.GetNextToken().Trim(); if (header.StartsWith(wxT("TQSLVERSION;"), &onlinever)) { newProgramRev = new revLevel(onlinever); } else if (header.IsEmpty()) continue; //blank line else if (header[0]=='#') continue; //comments else if (header.StartsWith(wxT("config.xml"), &onlinever)) { onlinever.Replace(wxT(":"), wxT("")); onlinever.Replace(wxT("Version"), wxT("")); onlinever.Trim(true); onlinever.Trim(false); newConfigRev = new revLevel(onlinever); } else { int sep=header.Find(';'); //; is invalid in URLs if (sep==wxNOT_FOUND) continue; //malformed string wxString plat=header.Left(sep); wxString url=header.Right(header.size()-sep-1); map[plat]=url; } } bool newProgram = newProgramRev ? (*newProgramRev > *programRev) : false; bool newConfig = newConfigRev ? (*newConfigRev > *configRev) : false; if (newProgram) { wxString ourPlatURL; //empty by default (we check against this later) wxStringTokenizer plats(GetUpdatePlatformString(), wxT(" ")); while(plats.HasMoreTokens()) { wxString tok=plats.GetNextToken(); //see if this token is here if (map.count(tok)) { ourPlatURL=map[tok]; break; } } if (noGUI) { wxLogMessage(wxT("A new TQSL release (V%s) is available."), newProgramRev->Value().c_str()); } else { //will create ("homepage"->"") if none there, which is what we'd be checking for anyway UpdateDialogMsgBox msg(this, true, false, programRev, newProgramRev, configRev, newConfigRev, ourPlatURL, map[wxT("homepage")]); msg.ShowModal(); } } if (newConfig) { if( noGUI) { wxLogMessage(wxT("A new TrustedQSL configuration file (V%s) is available."), newConfigRev->Value().c_str()); } else { UpdateDialogMsgBox msg(this, false, true, programRev, newProgramRev, configRev, newConfigRev, wxT(""), wxT("")); if (msg.ShowModal() == wxID_OK) { UpdateConfigFile(); } } } if (!newProgram && !newConfig) if (!silent && !noGUI) wxMessageBox(wxString::Format(wxT("Your system is up to date!\nTQSL Version %hs and Configuration Version %s\nare the newest available"), VERSION, configRev->Value().c_str()), wxT("No Updates"), wxOK|wxICON_INFORMATION, this); } else { if (diagFile) { fprintf(diagFile, "cURL Error during config file version check: %d : %s (%s)\n", retval, curl_easy_strerror((CURLcode)retval), errorbuf); } if (logFile) { fprintf(logFile, "cURL Error during config file version check: %s (%s)\n", curl_easy_strerror((CURLcode)retval), errorbuf); } if (retval == CURLE_COULDNT_RESOLVE_HOST || retval == CURLE_COULDNT_CONNECT) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to check for updates - either your Internet connection is down or LoTW is unreachable.\nPlease try again later.")); } else if (retval == CURLE_WRITE_ERROR || retval == CURLE_SEND_ERROR || retval == CURLE_RECV_ERROR) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to check for updates. The nework is down or the LoTW site is too busy.\nPlease try again later.")); } else if (retval == CURLE_SSL_CONNECT_ERROR) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to connect to the update site.\nPlease try again later.")); } else { // some other error if (!silent && !noGUI) wxMessageBox(wxString::Format(wxT("Error downloading new version information:\n%hs"), errorbuf), wxT("Update"), wxOK|wxICON_EXCLAMATION, this); } } } else { if (diagFile) { fprintf(diagFile, "cURL Error during program revision check: %d: %s (%s)\n", retval, curl_easy_strerror((CURLcode)retval), errorbuf); } if (logFile) { fprintf(logFile, "cURL Error during program revision check: %s (%s)\n", curl_easy_strerror((CURLcode)retval), errorbuf); } if (retval == CURLE_COULDNT_RESOLVE_HOST || retval == CURLE_COULDNT_CONNECT) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to check for updates - either your Internet connection is down or LoTW is unreachable.\nPlease try again later.")); } else if (retval == CURLE_WRITE_ERROR || retval == CURLE_SEND_ERROR || retval == CURLE_RECV_ERROR) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to check for updates. The nework is down or the LoTW site is too busy.\nPlease try again later.")); } else if (retval == CURLE_SSL_CONNECT_ERROR) { if (!silent && !noGUI) wxLogMessage(wxT("Unable to connect to the update site.\nPlease try again later.")); } else { // some other error if (!silent && !noGUI) wxMessageBox(wxString::Format(wxT("Error downloading update version information:\n%hs"), errorbuf), wxT("Update"), wxOK|wxICON_EXCLAMATION, this); } } // we checked today, and whatever the result, no need to (automatically) check again until the next interval config->Write(wxT("UpdateCheckTime"), wxDateTime::Today().FormatISODate()); curl_easy_cleanup(req); if (logFile) fclose(logFile); // After update check, validate user certificates DoCheckExpiringCerts(noGUI); return; } static void wx_tokens(const wxString& str, vector &toks) { size_t idx = 0; size_t newidx; wxString tok; do { newidx = str.find(wxT(" "), idx); if (newidx != wxString::npos) { toks.push_back(str.Mid(idx, newidx - idx)); idx = newidx + 1; } } while (newidx != wxString::npos); if (str.Mid(idx) != wxT("")) toks.push_back(str.Mid(idx)); } void MyFrame::ImportQSODataFile(wxCommandEvent& event) { tqslTrace("MyFrame::ImportQSODataFile"); wxString infile; // Does the user have any certificates? get_certlist("", 0, false, false); free_certlist(); if (ncerts == 0) { wxMessageBox(wxT("You have no callsign certificates to use to sign a log file.\n") wxT("Please install a callsign certificate then try again."), wxT("No Callsign Certificates"), wxOK|wxICON_EXCLAMATION, this); return; } try { bool compressed = (event.GetId() == tm_f_import_compress || event.GetId() == tl_Save); wxConfig *config = (wxConfig *)wxConfig::Get(); // Get input file wxString path = config->Read(wxT("ImportPath"), wxString(wxT(""))); wxString defext = config->Read(wxT("ImportExtension"), wxString(wxT("adi"))).Lower(); bool defFound = false; // Construct filter string for file-open dialog wxString filter = wxT("All files (*.*)|*.*"); vector exts; wxString file_exts = config->Read(wxT("ADIFFiles"), wxString(DEFAULT_ADIF_FILES)); wx_tokens(file_exts, exts); for (int i = 0; i < (int)exts.size(); i++) { filter += wxT("|ADIF files (*.") + exts[i] + wxT(")|*.") + exts[i]; if (exts[i] == defext) defFound = true; } exts.clear(); file_exts = config->Read(wxT("CabrilloFiles"), wxString(DEFAULT_CABRILLO_FILES)); wx_tokens(file_exts, exts); for (int i = 0; i < (int)exts.size(); i++) { filter += wxT("|Cabrillo files (*.") + exts[i] + wxT(")|*.") + exts[i]; if (exts[i] == defext) defFound = true; } if (defext.IsEmpty() || !defFound) defext = wxString(wxT("adi")); infile = wxFileSelector(wxT("Select file to Sign"), path, wxT(""), defext, filter, wxOPEN|wxFILE_MUST_EXIST, this); if (infile == wxT("")) return; wxString inPath; wxString inExt; wxSplitPath(infile.c_str(), &inPath, NULL, &inExt); inExt.Lower(); config->Write(wxT("ImportPath"), inPath); config->Write(wxT("ImportExtension"), inExt); // Get output file wxString basename; wxSplitPath(infile.c_str(), 0, &basename, 0); path = wxConfig::Get()->Read(wxT("ExportPath"), wxString(wxT(""))); wxString deftype = compressed ? wxT("tq8") : wxT("tq7"); filter = compressed ? wxT("TQSL compressed data files (*.tq8)|*.tq8") : wxT("TQSL data files (*.tq7)|*.tq7"); basename += wxT(".") + deftype; wxString outfile = wxFileSelector(wxT("Select file to write to"), path, basename, deftype, filter + wxT("|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this); if (outfile == wxT("")) return; config->Write(wxT("ExportPath"), wxPathOnly(outfile)); tQSL_Location loc = SelectStationLocation(wxT("Select Station Location for Signing")); if (loc == 0) return; char callsign[40]; char loc_name[256]; int dxccnum; check_tqsl_error(tqsl_getLocationCallSign(loc, callsign, sizeof callsign)); check_tqsl_error(tqsl_getLocationDXCCEntity(loc, &dxccnum)); check_tqsl_error(tqsl_getStationLocationCaptureName(loc, loc_name, sizeof loc_name)); DXCC dxcc; dxcc.getByEntity(dxccnum); if (wxMessageBox(wxString::Format(wxT("The file (%s) will be signed using:\n" wxT("Station Location: %hs\nCall sign: %hs\nDXCC: %hs\nIs this correct?")), infile.c_str(), loc_name, callsign, dxcc.name()), wxT("TQSL - Confirm signing"), wxYES_NO, this) == wxYES) ConvertLogFile(loc, infile, outfile, compressed); else wxLogMessage(wxT("Signing abandoned")); } catch (TQSLException& x) { wxString s; if (infile != wxT("")) s = infile + wxT(": "); s += wxString(x.what(), wxConvLocal); wxLogError(wxT("%s"), (const char *)s.c_str()); } free_certlist(); return; } void MyFrame::UploadQSODataFile(wxCommandEvent& event) { tqslTrace("MyFrame::UploadQSODataFile"); wxString infile; // Does the user have any certificates? get_certlist("", 0, false, false); free_certlist(); if (ncerts == 0) { wxMessageBox(wxT("You have no callsign certificates to use to sign a log file.\n") wxT("Please install a callsign certificate then try again."), wxT("No Callsign Certificates"), wxOK|wxICON_EXCLAMATION, this); return; } try { wxConfig *config = (wxConfig *)wxConfig::Get(); // Get input file wxString path = config->Read(wxT("ImportPath"), wxString(wxT(""))); wxString defext = config->Read(wxT("ImportExtension"), wxString(wxT("adi"))).Lower(); bool defFound = false; // Construct filter string for file-open dialog wxString filter = wxT("All files (*.*)|*.*"); vector exts; wxString file_exts = config->Read(wxT("ADIFFiles"), wxString(DEFAULT_ADIF_FILES)); wx_tokens(file_exts, exts); for (int i = 0; i < (int)exts.size(); i++) { filter += wxT("|ADIF files (*.") + exts[i] + wxT(")|*.") + exts[i]; if (exts[i] == defext) defFound = true; } exts.clear(); file_exts = config->Read(wxT("CabrilloFiles"), wxString(DEFAULT_CABRILLO_FILES)); wx_tokens(file_exts, exts); for (int i = 0; i < (int)exts.size(); i++) { filter += wxT("|Cabrillo files (*.") + exts[i] + wxT(")|*.") + exts[i]; if (exts[i] == defext) defFound = true; } if (defext.IsEmpty() || !defFound) defext = wxString(wxT("adi")); infile = wxFileSelector(wxT("Select file to Sign"), path, wxT(""), defext, filter, wxOPEN|wxFILE_MUST_EXIST, this); if (infile == wxT("")) return; wxString inPath; wxString inExt; wxSplitPath(infile.c_str(), &inPath, NULL, &inExt); inExt.Lower(); config->Write(wxT("ImportPath"), inPath); config->Write(wxT("ImportExtension"), inExt); // Get output file tQSL_Location loc = SelectStationLocation(wxT("Select Station Location for Signing")); if (loc == 0) return; char callsign[40]; char loc_name[256]; int dxccnum; check_tqsl_error(tqsl_getLocationCallSign(loc, callsign, sizeof callsign)); check_tqsl_error(tqsl_getLocationDXCCEntity(loc, &dxccnum)); check_tqsl_error(tqsl_getStationLocationCaptureName(loc, loc_name, sizeof loc_name)); DXCC dxcc; dxcc.getByEntity(dxccnum); if (wxMessageBox(wxString::Format(wxT("The file (%s) will be signed and uploaded using:\n" wxT("Station Location: %hs\nCall sign: %hs\nDXCC: %hs\nIs this correct?")), infile.c_str(), loc_name, callsign, dxcc.name()), wxT("TQSL - Confirm signing"), wxYES_NO, this) == wxYES) UploadLogFile(loc, infile); else wxLogMessage(wxT("Signing abandoned")); } catch (TQSLException& x) { wxString s; if (infile != wxT("")) s = infile + wxT(": "); s += wxString(x.what(), wxConvLocal); wxLogError(wxT("%s"), (const char *)s.c_str()); } free_certlist(); } void MyFrame::OnPreferences(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnPreferences"); Preferences* dial = new Preferences(this, help); dial->Show(true); file_menu->Enable(tm_f_preferences, false); } class TQSLConfig { public: TQSLConfig() { callSign = ""; serial = 0; dxcc = 0; elementBody = wxT(""); locstring = wxT(""); config = NULL; outstr = NULL; conv = NULL; } void SaveSettings (gzFile* out, wxString appname); void RestoreCert (void); void RestoreConfig (gzFile& in); void ParseLocations (gzFile* out, const tQSL_StationDataEnc loc); wxConfig *config; long serial; int dxcc; string callSign; wxString signedCert; wxString privateKey; wxString elementBody; wxString locstring; gzFile* outstr; tQSL_Converter conv; private: static void xml_restore_start(void *data, const XML_Char *name, const XML_Char **atts); static void xml_restore_end(void *data, const XML_Char *name); static void xml_text(void *data, const XML_Char *text, int len); static void xml_location_start(void *data, const XML_Char *name, const XML_Char **atts); static void xml_location_end(void *data, const XML_Char *name); }; // Save the user's configuration settings - appname is the // application name (tqslapp) void TQSLConfig::SaveSettings (gzFile* out, wxString appname) { tqslTrace("TQSLConfig::SaveSettings", "appname=%s", _S(appname)); config = new wxConfig(appname); wxString name, gname; long context; wxString svalue; long lvalue; bool bvalue; double dvalue; wxArrayString groupNames; tqslTrace("TQSLConfig::SaveSettings", "... init groups"); groupNames.Add(wxT("/")); bool more = config->GetFirstGroup(gname, context); while (more) { tqslTrace("TQSLConfig::SaveSettings", "... add group %s", _S(name)); groupNames.Add(wxT("/") + gname); more = config->GetNextGroup(gname, context); } tqslTrace("TQSLConfig::SaveSettings", "... groups done."); for (unsigned i = 0; i < groupNames.GetCount(); i++) { tqslTrace("TQSLConfig::SaveSettings", "Group %d setting path %s", i, _S(groupNames[i])); config->SetPath(groupNames[i]); more = config->GetFirstEntry(name, context); while (more) { tqslTrace("TQSLConfig::SaveSettings", "name=%s", _S(name)); if (name.IsEmpty()) { more = config->GetNextEntry(name, context); continue; } gzprintf(*out, "GetEntryType(name); switch (etype) { case wxConfigBase::Type_Unknown: case wxConfigBase::Type_String: config->Read(name, &svalue); svalue.Replace(wxT("&"), wxT("&"), true); svalue.Replace(wxT("<"), wxT("<"), true); svalue.Replace(wxT(">"), wxT(">"), true); gzprintf(*out, "Type=\"String\" Value=\"%s\"/>\n", (const char *)svalue.mb_str()); break; case wxConfigBase::Type_Boolean: config->Read(name, &bvalue); if (bvalue) gzprintf(*out, "Type=\"Bool\" Value=\"true\"/>\n"); else gzprintf(*out, "Type=\"Bool\" Value=\"false\"/>\n"); break; case wxConfigBase::Type_Integer: config->Read(name, &lvalue); gzprintf(*out, "Type=\"Int\" Value=\"%d\"/>\n", lvalue); break; case wxConfigBase::Type_Float: config->Read(name, &dvalue); gzprintf(*out, "Type=\"Float\" Value=\"%f\"/>\n", dvalue); break; } more = config->GetNextEntry(name, context); } } tqslTrace("TQSLConfig::SaveSettings", "Done."); config->SetPath(wxT("/")); return; } void MyFrame::BackupConfig(wxString& filename, bool quiet) { tqslTrace("MyFrame::BackupConfig", "filename=%s, quiet=%d", _S(filename), quiet); int i; try { gzFile out = 0; out = gzopen(filename.mb_str(), "wb9"); if (!out) { wxLogError(wxT("Error opening save file %s: %hs"), filename.c_str(), strerror(errno)); return; } TQSLConfig* conf = new TQSLConfig(); gzprintf(out, "\n\n"); gzprintf(out, "\n"); gzprintf(out, "\n"); if (!quiet) { wxLogMessage(wxT("Saving callsign certificates")); } else { tqslTrace("MyFrame::BackupConfig", "Saving callsign certificates"); } int ncerts; char buf[8192]; // Save root certificates check_tqsl_error(tqsl_selectCACertificates(&certlist, &ncerts, "root")); for (i = 0; i < ncerts; i++) { gzprintf(out, "\n"); check_tqsl_error(tqsl_getCertificateEncoded(certlist[i], buf, sizeof buf)); gzwrite(out, buf, strlen(buf)); gzprintf(out, "\n"); tqsl_freeCertificate(certlist[i]); } // Save CA certificates check_tqsl_error(tqsl_selectCACertificates(&certlist, &ncerts, "authorities")); for (i = 0; i < ncerts; i++) { gzprintf(out, "\n"); check_tqsl_error(tqsl_getCertificateEncoded(certlist[i], buf, sizeof buf)); gzwrite(out, buf, strlen(buf)); gzprintf(out, "\n"); tqsl_freeCertificate(certlist[i]); } tqsl_selectCertificates(&certlist, &ncerts, 0, 0, 0, 0, TQSL_SELECT_CERT_WITHKEYS | TQSL_SELECT_CERT_EXPIRED | TQSL_SELECT_CERT_SUPERCEDED); for (i = 0; i < ncerts; i++) { char callsign[64]; long serial = 0; int dxcc = 0; int keyonly; check_tqsl_error(tqsl_getCertificateKeyOnly(certlist[i], &keyonly)); check_tqsl_error(tqsl_getCertificateCallSign(certlist[i], callsign, sizeof callsign)); if (!keyonly) { check_tqsl_error(tqsl_getCertificateSerial(certlist[i], &serial)); } check_tqsl_error(tqsl_getCertificateDXCCEntity(certlist[i], &dxcc)); if (!quiet) { wxLogMessage(wxT("\tSaving callsign certificate for %hs"), callsign); } gzprintf(out, "\n", callsign, dxcc, serial); if (!keyonly) { gzprintf(out, "\n"); check_tqsl_error(tqsl_getCertificateEncoded(certlist[i], buf, sizeof buf)); gzwrite(out, buf, strlen(buf)); gzprintf(out, "\n"); } gzprintf(out, "\n"); check_tqsl_error(tqsl_getKeyEncoded(certlist[i], buf, sizeof buf)); gzwrite(out, buf, strlen(buf)); gzprintf(out, "\n\n"); tqsl_freeCertificate(certlist[i]); } gzprintf(out, "\n"); gzprintf(out, "\n"); if (!quiet) { wxLogMessage(wxT("Saving Station Locations")); } else { tqslTrace("MyFrame::BackupConfig", "Saving Station Locations"); } tQSL_StationDataEnc sdbuf = NULL; check_tqsl_error(tqsl_getStationDataEnc(&sdbuf)); TQSLConfig* parser = new TQSLConfig(); if (sdbuf) parser->ParseLocations(&out, sdbuf); check_tqsl_error(tqsl_freeStationDataEnc(sdbuf)); gzprintf(out, "\n"); if (!quiet) { wxLogMessage(wxT("Saving TQSL Preferences")); } else { tqslTrace("MyFrame::BackupConfig", "Saving TQSL Preferences - out=0x%lx", (void *)out); } gzprintf(out, "\n"); conf->SaveSettings(&out, wxT("tqslapp")); tqslTrace("MyFrame::BackupConfig", "Done with settings. out=0x%lx", (void *)out); gzprintf(out, "\n"); if (!quiet) { wxLogMessage(wxT("Saving QSOs")); } else { tqslTrace("MyFrame::BackupConfig", "Saving QSOs"); } tQSL_Converter conv = 0; check_tqsl_error(tqsl_beginConverter(&conv)); tqslTrace("MyFrame::BackupConfig", "beginConverter call success"); gzprintf(out, "\n"); while (true) { char dupekey[256]; char dupedata[10]; int status = tqsl_getDuplicateRecords(conv, dupekey, dupedata, sizeof(dupekey)); if (status == -1) // End of file break; check_tqsl_error(status); gzprintf(out, "\n", dupekey); } gzprintf(out, "\n"); tqslTrace("MyFrame::BackupConfig", "Dupes db saved OK"); gzprintf(out, "\n"); gzclose(out); if (!quiet) { wxLogMessage(wxT("Save operation complete.")); } else { tqslTrace("MyFrame::BackupConfig", "Save operation complete."); } } catch (TQSLException& x) { if (quiet) { wxString errmsg = wxString::Format(wxT("Error performing automatic backup: %hs"), x.what()); wxMessageBox(errmsg, wxT("Backup Error"), wxOK|wxICON_EXCLAMATION); } else { wxLogError(wxT("Backup operation failed: %hs"), x.what()); } } } void MyFrame::OnSaveConfig(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnSaveConfig"); try { wxString file_default = wxT("tqslconfig.tbk"); wxString filename = wxFileSelector(wxT("Enter file to save to"), wxT(""), file_default, wxT(".tbk"), wxT("Configuration files (*.tbk)|*.tbk|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this); if (filename == wxT("")) return; BackupConfig(filename, false); } catch (TQSLException& x) { wxLogError(wxT("Backup operation failed: %hs"), x.what()); } } void restore_user_cert(TQSLConfig* loader) { get_certlist(loader->callSign.c_str(), loader->dxcc, true, true); for (int i = 0; i < ncerts; i++) { long serial; int dxcc; int keyonly; check_tqsl_error(tqsl_getCertificateKeyOnly(certlist[i], &keyonly)); check_tqsl_error(tqsl_getCertificateDXCCEntity(certlist[i], &dxcc)); if (!keyonly) { check_tqsl_error(tqsl_getCertificateSerial(certlist[i], &serial)); } else { // There can be only one pending request for // a given callsign/entity serial = loader->serial; } if (serial == loader->serial && dxcc == loader->dxcc) return; // This certificate is already installed. } // There is no certificate matching this callsign/entity/serial. wxLogMessage(wxT("\tRestoring callsign certificate for %hs"), loader->callSign.c_str()); check_tqsl_error(tqsl_importKeyPairEncoded(loader->callSign.c_str(), "user", loader->privateKey.mb_str(), loader->signedCert.mb_str())); } void restore_root_cert(TQSLConfig* loader) { check_tqsl_error(tqsl_importKeyPairEncoded(NULL, "root", NULL, loader->signedCert.mb_str())); } void restore_ca_cert(TQSLConfig* loader) { check_tqsl_error(tqsl_importKeyPairEncoded(NULL, "authorities", NULL, loader->signedCert.mb_str())); } void TQSLConfig::xml_restore_start(void *data, const XML_Char *name, const XML_Char **atts) { TQSLConfig* loader = (TQSLConfig *) data; int i; loader->elementBody = wxT(""); if (strcmp(name, "UserCert") == 0) { for (int i = 0; atts[i]; i+=2) { if (strcmp(atts[i], "CallSign") == 0) { loader->callSign = atts[i + 1]; } else if (strcmp(atts[i], "serial") == 0) { if (strlen(atts[i+1]) == 0) { loader->serial = 0; } else { loader->serial = strtol(atts[i+1], NULL, 10); } } else if (strcmp(atts[i], "dxcc") == 0) { if (strlen(atts[i+1]) == 0) { loader->dxcc = 0; } else { loader->dxcc = strtol(atts[i+1], NULL, 10); } } } loader->privateKey = wxT(""); loader->signedCert = wxT(""); } else if (strcmp(name, "TQSLSettings") == 0) { wxLogMessage(wxT("Restoring Preferences")); loader->config = new wxConfig(wxT("tqslapp")); } else if (strcmp(name, "Setting") == 0) { wxString sname; wxString sgroup; wxString stype; wxString svalue; for (i = 0; atts[i]; i+=2) { if (strcmp(atts[i], "name") == 0) { sname = wxString(atts[i+1], wxConvLocal); } else if (strcmp(atts[i], "group") == 0) { sgroup = wxString(atts[i+1], wxConvLocal); } else if (strcmp(atts[i], "Type") == 0) { stype = wxString(atts[i+1], wxConvLocal); } else if (strcmp(atts[i], "Value") == 0) { svalue = wxString(atts[i+1], wxConvLocal); } } loader->config->SetPath(sgroup); if (stype == wxT("String")) { svalue.Replace(wxT("<"), wxT("<"), true); svalue.Replace(wxT(">"), wxT(">"), true); svalue.Replace(wxT("&"), wxT("&"), true); loader->config->Write(sname, svalue); } else if (stype == wxT("Bool")) { bool bsw = (svalue == wxT("true")); loader->config->Write(sname, bsw); } else if (stype == wxT("Int")) { long lval = strtol(svalue.mb_str(), NULL, 10); loader->config->Write(sname, lval); } else if (stype == wxT("Float")) { double dval = strtod(svalue.mb_str(), NULL); loader->config->Write(sname, dval); } } else if (strcmp(name, "Locations") == 0) { wxLogMessage(wxT("Restoring Station Locations")); loader->locstring = wxT("\n"); } else if (strcmp(name, "Location") == 0) { for (i = 0; atts[i]; i+=2) { if (strcmp(atts[i], "name") == 0) { loader->locstring += wxT("\n"); break; } } for (i = 0; atts[i]; i+=2) { if (strcmp(atts[i], "name") != 0) { loader->locstring += wxT("<") + wxString(atts[i], wxConvLocal) + wxT(">") + wxString(atts[i+1], wxConvLocal) + wxT("\n"); } } } else if (strcmp(name, "DupeDb") == 0) { wxLogMessage(wxT("Restoring QSO records")); check_tqsl_error(tqsl_beginConverter(&loader->conv)); } else if (strcmp(name, "Dupe") == 0) { for (i = 0; atts[i]; i+=2) { if (strcmp(atts[i], "key") == 0) { int status = tqsl_putDuplicateRecord(loader->conv, atts[i+1], "D", strlen(atts[i+1])); if (status >= 0) check_tqsl_error(status); } } } } void TQSLConfig::xml_restore_end(void *data, const XML_Char *name) { TQSLConfig* loader = (TQSLConfig *) data; if (strcmp(name, "SignedCert") == 0) { loader->signedCert = loader->elementBody.Trim(false); } else if (strcmp(name, "PrivateKey") == 0) { loader->privateKey = loader->elementBody.Trim(false); } else if (strcmp(name, "RootCert") == 0) { loader->signedCert = loader->elementBody.Trim(false); restore_root_cert(loader); } else if (strcmp(name, "CACert") == 0) { loader->signedCert = loader->elementBody.Trim(false); restore_ca_cert(loader); } else if (strcmp(name, "UserCert") == 0) { restore_user_cert(loader); } else if (strcmp(name, "Location") == 0) { loader->locstring += wxT("\n"); } else if (strcmp(name, "Locations") == 0) { loader->locstring += wxT("\n"); if (tqsl_mergeStationLocations(loader->locstring.mb_str()) != 0) { wxLogError(wxT("\tError importing station locations: %hs"), tqsl_getErrorString()); } } else if (strcmp(name, "TQSLSettings") == 0) { loader->config->Flush(false); } else if (strcmp(name, "DupeDb") == 0) { check_tqsl_error(tqsl_converterCommit(loader->conv)); check_tqsl_error(tqsl_endConverter(&loader->conv)); } loader->elementBody = wxT(""); } void TQSLConfig::xml_location_start(void *data, const XML_Char *name, const XML_Char **atts) { TQSLConfig* parser = (TQSLConfig *) data; if (strcmp(name, "StationDataFile") == 0) return; if (strcmp(name, "StationData") == 0) { gzprintf(*parser->outstr, "outstr ," />\n"); return; } // Anything else is a station attribute. Add it to the definition. parser->elementBody.Trim(false); parser->elementBody.Trim(true); gzprintf(*parser->outstr, " %s=\"%s\"", name, (const char *)parser->elementBody.mb_str()); parser->elementBody = wxT(""); } void TQSLConfig::xml_text(void *data, const XML_Char *text, int len) { TQSLConfig* loader = (TQSLConfig *) data; char buf[512]; memcpy(buf, text, len); buf[len] = '\0'; loader->elementBody += wxString(buf, wxConvLocal); } void TQSLConfig::RestoreConfig (gzFile& in) { tqslTrace("TQSLConfig::RestoreConfig"); XML_Parser xp = XML_ParserCreate(0); XML_SetUserData(xp, (void *) this); XML_SetStartElementHandler(xp, &TQSLConfig::xml_restore_start); XML_SetEndElementHandler(xp, &TQSLConfig::xml_restore_end); XML_SetCharacterDataHandler(xp, &TQSLConfig::xml_text); char buf[4096]; wxLogMessage(wxT("Restoring Callsign Certificates")); int rcount = 0; do { rcount = gzread(in, buf, sizeof(buf)); if (rcount > 0) { if (XML_Parse(xp, buf, rcount, 0) == 0) { wxLogError(wxT("Error parsing saved configuration file: %hs"), XML_ErrorString(XML_GetErrorCode(xp))); XML_ParserFree(xp); gzclose(in); return; } } } while (rcount > 0); if (!gzeof(in)) { int gerr; wxLogError(wxT("Error parsing saved configuration file: %hs"), gzerror(in, &gerr)); XML_ParserFree(xp); return; } if (XML_Parse(xp, "", 0, 1) == 0) { wxLogError(wxT("Error parsing saved configuration file: %hs"), XML_ErrorString(XML_GetErrorCode(xp))); XML_ParserFree(xp); return; } wxLogMessage(wxT("Restore Complete.")); } void TQSLConfig::ParseLocations (gzFile* out, const tQSL_StationDataEnc loc) { tqslTrace("TQSL::ParseLocations", "loc=%s", loc); XML_Parser xp = XML_ParserCreate(0); XML_SetUserData(xp, (void *) this); XML_SetStartElementHandler(xp, &TQSLConfig::xml_location_start); XML_SetEndElementHandler(xp, &TQSLConfig::xml_location_end); XML_SetCharacterDataHandler(xp, &TQSLConfig::xml_text); outstr = out; if (XML_Parse(xp, loc, strlen(loc), 1) == 0) { wxLogError(wxT("Error parsing station location file: %hs"), XML_ErrorString(XML_GetErrorCode(xp))); XML_ParserFree(xp); return; } } void MyFrame::OnLoadConfig(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLoadConfig"); wxString filename = wxFileSelector(wxT("Select saved configuration file"), wxT(""), wxT("tqslconfig.tbk"), wxT("tbk"), wxT("Saved configuration files (*.tbk)|*.tbk"), wxOPEN|wxFILE_MUST_EXIST); if (filename == wxT("")) return; gzFile in = 0; try { in = gzopen(filename.mb_str(), "rb"); if (!in) { wxLogError(wxT("Error opening save file %s: %hs"), filename.c_str(), strerror(errno)); return; } TQSLConfig* loader = new TQSLConfig(); loader->RestoreConfig(in); cert_tree->Build(CERTLIST_FLAGS); loc_tree->Build(); LocTreeReset(); CertTreeReset(); gzclose(in); } catch (TQSLException& x) { wxLogError(wxT("Restore operation failed: %hs"), x.what()); gzclose(in); } } QSLApp::QSLApp() : wxApp() { #ifdef __WXMAC__ // Tell wx to put these items on the proper menu wxApp::s_macAboutMenuItemId = long(tm_h_about); wxApp::s_macPreferencesMenuItemId = long(tm_f_preferences); wxApp::s_macExitMenuItemId = long(tm_f_exit); #endif wxConfigBase::Set(new wxConfig(wxT("tqslapp"))); } /* wxLog * QSLApp::CreateLogTarget() { cerr << "called" << endl; MyFrame *mf = (MyFrame *)GetTopWindow(); if (mf) return new LogList(mf); return 0; } */ MyFrame * QSLApp::GUIinit(bool checkUpdates, bool quiet) { tqslTrace("QSLApp::GUIinit", "checkUpdates=%d", checkUpdates); int x, y, w, h; wxConfig *config = (wxConfig *)wxConfig::Get(); config->Read(wxT("MainWindowX"), &x, 50); config->Read(wxT("MainWindowY"), &y, 50); config->Read(wxT("MainWindowWidth"), &w, 800); config->Read(wxT("MainWindowHeight"), &h, 600); if (w < MAIN_WINDOW_MIN_WIDTH) w = MAIN_WINDOW_MIN_WIDTH; if (h < MAIN_WINDOW_MIN_HEIGHT) w = MAIN_WINDOW_MIN_HEIGHT; frame = new MyFrame(wxT("TQSL"), x, y, w, h, checkUpdates, quiet); frame->SetMinSize(wxSize(MAIN_WINDOW_MIN_WIDTH, MAIN_WINDOW_MIN_HEIGHT)); if (checkUpdates) frame->FirstTime(); frame->Show(!quiet); SetTopWindow(frame); return frame; } // Override OnRun so we can have a last-chance exception handler // in case something doesn't handle an error. int QSLApp::OnRun() { tqslTrace("QSLApp::OnRun"); try { if (m_exitOnFrameDelete == Later) m_exitOnFrameDelete = Yes; return MainLoop(); } catch (TQSLException& x) { string msg = x.what(); tqslTrace("QSLApp::OnRun", "Last chance handler, string=%s", (const char *)msg.c_str()); cerr << "An exception has occurred! " << msg << endl; wxLogError(wxT("%hs"), x.what()); exitNow(TQSL_EXIT_TQSL_ERROR, false); } return 0; } bool QSLApp::OnInit() { frame = 0; bool quiet = false; int major, minor; if (tqsl_getConfigVersion(&major, &minor)) { wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), wxT("Error"), wxOK); exitNow (TQSL_EXIT_TQSL_ERROR, quiet); } wxFileSystem::AddHandler(new tqslInternetFSHandler()); //short circuit if no arguments if (argc<=1) { GUIinit(true, quiet); return true; } tQSL_Location loc = 0; wxString locname; bool suppressdate = false; int action = TQSL_ACTION_UNSPEC; bool upload=false; char *password = NULL; wxString infile(wxT("")); wxString outfile(wxT("")); wxString importfile(wxT("")); wxString diagfile(wxT("")); wxCmdLineParser parser; static const wxCmdLineEntryDesc cmdLineDesc[] = { { wxCMD_LINE_OPTION, wxT("a"), wxT("action"), wxT("Specify dialog action - abort, all, compliant or ask") }, { wxCMD_LINE_OPTION, wxT("b"), wxT("begindate"),wxT("Specify start date for QSOs to sign") }, { wxCMD_LINE_OPTION, wxT("e"), wxT("enddate"), wxT("Specify end date for QSOs to sign") }, { wxCMD_LINE_SWITCH, wxT("d"), wxT("nodate"), wxT("Suppress date range dialog") }, { wxCMD_LINE_OPTION, wxT("i"), wxT("import"), wxT("Import a certificate file (.p12 or .tq6)") }, { wxCMD_LINE_OPTION, wxT("l"), wxT("location"), wxT("Selects Station Location") }, { wxCMD_LINE_SWITCH, wxT("s"), wxT("editlocation"), wxT("Edit (if used with -l) or create Station Location") }, { wxCMD_LINE_OPTION, wxT("o"), wxT("output"), wxT("Output file name (defaults to input name minus extension plus .tq8") }, { wxCMD_LINE_SWITCH, wxT("u"), wxT("upload"), wxT("Upload after signing instead of saving") }, { wxCMD_LINE_SWITCH, wxT("x"), wxT("batch"), wxT("Exit after processing log (otherwise start normally)") }, { wxCMD_LINE_OPTION, wxT("p"), wxT("password"), wxT("Password for the signing key") }, { wxCMD_LINE_SWITCH, wxT("q"), wxT("quiet"), wxT("Quiet Mode - same behavior as -x") }, { wxCMD_LINE_OPTION, wxT("t"), wxT("diagnose"), wxT("File name for diagnostic tracking log") }, { wxCMD_LINE_SWITCH, wxT("v"), wxT("version"), wxT("Display the version information and exit") }, { wxCMD_LINE_SWITCH, wxT("n"), wxT("updates"), wxT("Check for updates to tqsl and the configuration file") }, { wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), wxT("Display command line help"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, { wxCMD_LINE_PARAM, NULL, NULL, wxT("Input ADIF or Cabrillo log file to sign"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, { wxCMD_LINE_NONE } }; // Lowercase command options origCommandLine = argv[0]; for (int i = 1; i < argc; i++) { origCommandLine += wxT(" "); origCommandLine += argv[i]; if (argv[i] && (argv[i][0] == wxT('-') || argv[i][0] == wxT('/'))) if (wxIsalpha(argv[i][1]) && wxIsupper(argv[i][1])) argv[i][1] = wxTolower(argv[i][1]); } parser.SetCmdLine(argc, argv); parser.SetDesc(cmdLineDesc); // only allow "-" for options, otherwise "/path/something.adif" // is parsed as "-path" //parser.SetSwitchChars(wxT("-")); //by default, this is '-' on Unix, or '-' or '/' on Windows. We should respect the Win32 conventions, but allow the cross-platform Unix one for cross-plat loggers int parseStatus = parser.Parse(true); if (parseStatus == -1) { // said "-h" return false; } // Always display TQSL version if ((!parser.Found(wxT("n"))) || parser.Found(wxT("v"))) { cerr << "TQSL Version " VERSION " " BUILD "\n"; } if (parseStatus != 0) { exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } // version already displayed - just exit if (parser.Found(wxT("v"))) { return false; } if (parser.Found(wxT("x")) || parser.Found(wxT("q"))) { quiet = true; wxLog::SetActiveTarget(new LogStderr()); } if (parser.Found(wxT("t"), &diagfile)) { diagFile = fopen(diagfile.mb_str(), "wb"); if (!diagFile) { cerr << "Error opening diagnostic log " << diagfile.mb_str() << ": " << strerror(errno) << endl; } else { wxString about = getAbout(); fprintf(diagFile, "TQSL Diagnostics\n%s\n\n", (const char *)about.mb_str()); fprintf(diagFile, "Command Line: %s\n", (const char *)origCommandLine.mb_str()); tqsl_init(); fprintf(diagFile, "Working Directory: %s\n", tQSL_BaseDir); } } tqsl_init(); // Init tqsllib // check for logical command switches if (parser.Found(wxT("o")) && parser.Found(wxT("u"))) { cerr << "Option -o cannot be combined with -u" << endl; exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } if ((parser.Found(wxT("o")) || parser.Found(wxT("u"))) && parser.Found(wxT("s"))) { cerr << "Option -s cannot be combined with -u or -o" << endl; exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } if (parser.Found(wxT("s")) && parser.GetParamCount() > 0) { cerr << "Option -s cannot be combined with an input file" << endl; exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } // Request to check for new versions of tqsl/config/certs if (parser.Found(wxT("n"))) { if (parser.Found(wxT("i")) || parser.Found(wxT("o")) || parser.Found(wxT("s")) || parser.Found(wxT("u"))) { cerr << "Option -n cannot be combined with any other options" << endl; exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } frame = GUIinit(false, true); frame->Show(false); // Check for updates then bail out. wxLog::SetActiveTarget(new LogStderr()); frame->DoCheckForUpdates(false, true); return(false); } frame =GUIinit(!quiet, quiet); if (quiet) { wxLog::SetActiveTarget(new LogStderr()); frame->Show(false); } if (parser.Found(wxT("i"), &importfile)) { importfile.Trim(true).Trim(false); notifyData nd; if (tqsl_importTQSLFile(importfile.mb_str(), notifyImport, &nd)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } else { wxLogMessage(nd.Message()); frame->cert_tree->Build(CERTLIST_FLAGS); wxString call = wxString(tQSL_ImportCall, wxConvLocal); wxString pending = wxConfig::Get()->Read(wxT("RequestPending")); pending.Replace(call, wxT(""), true); if (pending[0] == ',') pending.Replace(wxT(","), wxT("")); if (pending.Last() == ',') pending.Truncate(pending.Len()-1); wxConfig::Get()->Write(wxT("RequestPending"), pending); } return(true); } if (parser.Found(wxT("l"), &locname)) { locname.Trim(true); // clean up whitespace locname.Trim(false); tqsl_endStationLocationCapture(&loc); if (tqsl_getStationLocation(&loc, locname.mb_str())) { if (quiet) { wxLogError(wxT("%hs"), tqsl_getErrorString()); exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } else { wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), ErrorTitle, wxOK|wxCENTRE, frame); return false; } } } wxString pwd; if (parser.Found(wxT("p"), &pwd)) { password = strdup(pwd.mb_str()); } parser.Found(wxT("o"), &outfile); if (parser.Found(wxT("d"))) { suppressdate = true; } wxString start = wxT(""); wxString end = wxT(""); tQSL_Date* startdate = NULL; tQSL_Date* enddate = NULL; tQSL_Date s, e; if (parser.Found(wxT("b"), &start)) { if (start.Trim() == wxT("")) startdate = NULL; else if (tqsl_initDate(&s, start.mb_str()) || !tqsl_isDateValid(&s)) { if (quiet) { wxLogError(wxT("Start date of %s is invalid"), start.c_str()); exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } else { wxMessageBox(wxString::Format(wxT("Start date of %s is invalid"), start.c_str()), ErrorTitle, wxOK|wxCENTRE, frame); return false; } } startdate = &s; } if (parser.Found(wxT("e"), &end)) { if (end.Trim() == wxT("")) enddate = NULL; else if (tqsl_initDate(&e, end.mb_str()) || !tqsl_isDateValid(&e)) { if (quiet) { wxLogError(wxT("End date of %s is invalid"), end.c_str()); exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } else { wxMessageBox(wxString::Format(wxT("End date of %s is invalid"), end.c_str()), ErrorTitle, wxOK|wxCENTRE, frame); return false; } } enddate = &e; } wxString act; if (parser.Found(wxT("a"), &act)) { if (!act.CmpNoCase(wxT("abort"))) action = TQSL_ACTION_ABORT; else if (!act.CmpNoCase(wxT("compliant"))) action = TQSL_ACTION_NEW; else if (!act.CmpNoCase(wxT("all"))) action = TQSL_ACTION_ALL; else if (!act.CmpNoCase(wxT("ask"))) action = TQSL_ACTION_ASK; else { char tmp[100]; strncpy(tmp, (const char *)act.mb_str(wxConvUTF8), sizeof tmp); tmp[sizeof tmp -1] = '\0'; if (quiet) wxLogMessage(wxT("The -a parameter %hs is not recognized"), tmp); else cerr << "The action parameter " << tmp << " is not recognized" << endl; exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); } } if (parser.Found(wxT("u"))) { upload=true; } if (parser.Found(wxT("s"))) { // Add/Edit station location if (loc == 0) { if (tqsl_initStationLocationCapture(&loc)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); } AddEditStationLocation(loc, true); } else AddEditStationLocation(loc, false, wxT("Edit Station Location")); return false; } if (parser.GetParamCount()>0) { infile = parser.GetParam(0); } // We need a logfile, else there's nothing to do. if (wxIsEmpty(infile)) { // Nothing to sign if (diagFile) // Unless there's just a trace log return true; // in which case we let it open. wxLogError(wxT("No logfile to sign!")); if (quiet) exitNow(TQSL_EXIT_COMMAND_ERROR, quiet); return false; } if (loc == 0) { try { loc = frame->SelectStationLocation(wxT("Select Station Location for Signing")); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); if (quiet) exitNow(TQSL_EXIT_CANCEL, quiet); } } // If no location specified and not chosen, can't sign. Exit. if (loc == 0) { if (quiet) exitNow(TQSL_EXIT_CANCEL, quiet); return false; } wxString path, name, ext; if (!wxIsEmpty(outfile)) { path = outfile; } else { wxSplitPath(infile, &path, &name, &ext); if (!wxIsEmpty(path)) path += wxT("/"); path += name + wxT(".tq8"); } if (upload) { try { int val=frame->UploadLogFile(loc, infile, true, suppressdate, startdate, enddate, action, password); if (quiet) exitNow(val, quiet); else return true; // Run the GUI } catch (TQSLException& x) { wxString s; if (!infile.empty()) s = infile + wxT(": "); s += wxString(x.what(), wxConvLocal); wxLogError(wxT("%s"), (const char*)s.c_str()); if (quiet) exitNow(TQSL_EXIT_LIB_ERROR, quiet); else return true; } } else { try { int val = frame->ConvertLogFile(loc, infile, path, true, suppressdate, startdate, enddate, action, password); if (quiet) exitNow(val, quiet); else return true; } catch (TQSLException& x) { wxString s; if (!infile.empty()) s = infile + wxT(": "); s += wxString(x.what(), wxConvLocal); wxLogError(wxT("%s"), (const char*)s.c_str()); if (quiet) exitNow(TQSL_EXIT_LIB_ERROR, quiet); else return true; } } if (quiet) exitNow(TQSL_EXIT_SUCCESS, quiet); return true; } void MyFrame::FirstTime(void) { tqslTrace("MyFrame::FirstTime"); if (wxConfig::Get()->Read(wxT("HasRun")) == wxT("")) { wxConfig::Get()->Write(wxT("HasRun"), wxT("yes")); DisplayHelp(); wxMessageBox(wxT("Please review the introductory documentation before using this program."), wxT("Notice"), wxOK, this); } int ncerts = cert_tree->Build(CERTLIST_FLAGS); CertTreeReset(); if (ncerts == 0 && wxMessageBox(wxT("You have no callsign certificate installed on this computer with which to sign log submissions.\n") wxT("Would you like to request a callsign certificate now?"), wxT("Alert"), wxYES_NO, this) == wxYES) { wxCommandEvent e; CRQWizard(e); } wxString pending = wxConfig::Get()->Read(wxT("RequestPending")); wxStringTokenizer tkz(pending, wxT(",")); while (tkz.HasMoreTokens()) { wxString pend = tkz.GetNextToken(); bool found = false; tQSL_Cert *certs; int ncerts = 0; if (!tqsl_selectCertificates(&certs, &ncerts, pend.mb_str(), 0, 0, 0, TQSL_SELECT_CERT_WITHKEYS)) { for (int i = 0; i < ncerts; i++) { int keyonly; if (!tqsl_getCertificateKeyOnly(certs[i], &keyonly)) { if (!found && keyonly) found = true; } tqsl_freeCertificate(certs[i]); } } if (!found) { // Remove this call from the list of pending certificate requests wxString p = wxConfig::Get()->Read(wxT("RequestPending")); p.Replace(pend, wxT(""), true); if (p[0] == ',') p.Replace(wxT(","), wxT("")); if (p.Last() == ',') p.Truncate(pending.Len()-1); wxConfig::Get()->Write(wxT("RequestPending"), p); } else { if (wxMessageBox(wxT("Are you ready to load your new callsign certificate for ") + pend + wxT(" from LoTW now?"), wxT("Alert"), wxYES_NO, this) == wxYES) { wxCommandEvent e; OnLoadCertificateFile(e); } } } if (ncerts > 0) { TQ_WXCOOKIE cookie; wxTreeItemId it = cert_tree->GetFirstChild(cert_tree->GetRootItem(), cookie); while (it.IsOk()) { if (cert_tree->GetItemText(it) == wxT("Test Certificate Authority")) { wxMessageBox(wxT("You must delete your beta-test certificates (the ones\n") wxT("listed under \"Test Certificate Authority\") to ensure proprer\n") wxT("operation of the TrustedQSL software."), wxT("Warning"), wxOK, this); break; } it = cert_tree->GetNextChild(cert_tree->GetRootItem(), cookie); } } // Copy tqslcert preferences to tqsl unless already done. if (wxConfig::Get()->Read(wxT("PrefsMigrated")) == wxT("")) { wxConfig::Get()->Write(wxT("PrefsMigrated"), wxT("yes")); tqslTrace("MyFrame::FirstTime", "Migrating preferences from tqslcert"); wxConfig* certconfig = new wxConfig(wxT("tqslcert")); wxString name, gname; long context; wxString svalue; long lvalue; bool bvalue; double dvalue; wxArrayString groupNames; groupNames.Add(wxT("/")); bool more = certconfig->GetFirstGroup(gname, context); while (more) { groupNames.Add(wxT("/") + gname); more = certconfig->GetNextGroup(gname, context); } for (unsigned i = 0; i < groupNames.GetCount(); i++) { certconfig->SetPath(groupNames[i]); wxConfig::Get()->SetPath(groupNames[i]); more = certconfig->GetFirstEntry(name, context); while (more) { wxConfigBase::EntryType etype = certconfig->GetEntryType(name); switch (etype) { case wxConfigBase::Type_Unknown: case wxConfigBase::Type_String: certconfig->Read(name, &svalue); wxConfig::Get()->Write(name, svalue); break; case wxConfigBase::Type_Boolean: certconfig->Read(name, &bvalue); wxConfig::Get()->Write(name, bvalue); break; case wxConfigBase::Type_Integer: certconfig->Read(name, &lvalue); wxConfig::Get()->Write(name, lvalue); break; case wxConfigBase::Type_Float: certconfig->Read(name, &dvalue); wxConfig::Get()->Write(name, dvalue); break; } more = certconfig->GetNextEntry(name, context); } } delete certconfig; wxConfig::Get()->SetPath(wxT("/")); wxConfig::Get()->Flush(); } // Find and report conflicting mode maps init_modes(); return; } wxMenu * makeCertificateMenu(bool enable, bool keyonly) { tqslTrace("makeCertificateMenu", "enable=%d, keyonly=%d", enable, keyonly); wxMenu *c_menu = new wxMenu; c_menu->Append(tc_c_Properties, wxT("Display Callsign Certificate &Properties")); c_menu->Enable(tc_c_Properties, enable); c_menu->AppendSeparator(); c_menu->Append(tc_c_Load, wxT("&Load Callsign Certificate from File")); c_menu->Append(tc_c_Export, wxT("&Save Callsign Certificate to File...")); c_menu->Enable(tc_c_Export, enable); if (!keyonly) { c_menu->AppendSeparator(); c_menu->Append(tc_c_New, wxT("Request &New Callsign Certificate...")); c_menu->Append(tc_c_Renew, wxT("&Renew Callsign Certificate")); c_menu->Enable(tc_c_Renew, enable); } else c_menu->AppendSeparator(); c_menu->Append(tc_c_Delete, wxT("&Delete Callsign Certificate")); c_menu->Enable(tc_c_Delete, enable); return c_menu; } wxMenu * makeLocationMenu(bool enable) { tqslTrace("makeLocationMenu", "enable=%d", enable); wxMenu *loc_menu = new wxMenu; loc_menu->Append(tl_c_Properties, wxT("&Properties")); loc_menu->Enable(tl_c_Properties, enable); stn_menu->Enable(tm_s_Properties, enable); loc_menu->Append(tl_c_Edit, wxT("&Edit")); loc_menu->Enable(tl_c_Edit, enable); loc_menu->Append(tl_c_Delete, wxT("&Delete")); loc_menu->Enable(tl_c_Delete, enable); return loc_menu; } /////////// Frame ///////////// void MyFrame::OnLoadCertificateFile(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLoadCertificateFile"); LoadCertWiz lcw(this, help, wxT("Load Certificate File")); lcw.RunWizard(); cert_tree->Build(CERTLIST_FLAGS); CertTreeReset(); } void MyFrame::CRQWizardRenew(wxCommandEvent& event) { tqslTrace("MyFrame::CRQWizardRenew"); CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()); req = 0; tQSL_Cert cert; wxString callSign, name, address1, address2, city, state, postalCode, country, emailAddress; if (data != NULL && (cert = data->getCert()) != 0) { // Should be true char buf[256]; req = new TQSL_CERT_REQ; if (!tqsl_getCertificateIssuerOrganization(cert, buf, sizeof buf)) strncpy(req->providerName, buf, sizeof req->providerName); if (!tqsl_getCertificateIssuerOrganizationalUnit(cert, buf, sizeof buf)) strncpy(req->providerUnit, buf, sizeof req->providerUnit); if (!tqsl_getCertificateCallSign(cert, buf, sizeof buf)) { callSign = wxString(buf, wxConvLocal); strncpy(req->callSign, callSign.mb_str(), sizeof (req->callSign)); } if (!tqsl_getCertificateAROName(cert, buf, sizeof buf)) { name = wxString(buf, wxConvLocal); strncpy(req->name, name.mb_str(), sizeof (req->name)); } tqsl_getCertificateDXCCEntity(cert, &(req->dxccEntity)); tqsl_getCertificateQSONotBeforeDate(cert, &(req->qsoNotBefore)); tqsl_getCertificateQSONotAfterDate(cert, &(req->qsoNotAfter)); if (!tqsl_getCertificateEmailAddress(cert, buf, sizeof buf)) { emailAddress = wxString(buf, wxConvLocal); strncpy(req->emailAddress, emailAddress.mb_str(), sizeof (req->emailAddress)); } if (!tqsl_getCertificateRequestAddress1(cert, buf, sizeof buf)) { address1 = wxString(buf, wxConvLocal); strncpy(req->address1, address1.mb_str(), sizeof (req->address1)); } if (!tqsl_getCertificateRequestAddress2(cert, buf, sizeof buf)) { address2 = wxString(buf, wxConvLocal); strncpy(req->address2, address2.mb_str(), sizeof (req->address2)); } if (!tqsl_getCertificateRequestCity(cert, buf, sizeof buf)) { city = wxString(buf, wxConvLocal); strncpy(req->city, city.mb_str(), sizeof (req->city)); } if (!tqsl_getCertificateRequestState(cert, buf, sizeof buf)) { state = wxString(buf, wxConvLocal); strncpy(req->state, state.mb_str(), sizeof (req->state)); } if (!tqsl_getCertificateRequestPostalCode(cert, buf, sizeof buf)) { postalCode = wxString(buf, wxConvLocal); strncpy(req->postalCode, postalCode.mb_str(), sizeof (req->postalCode)); } if (!tqsl_getCertificateRequestCountry(cert, buf, sizeof buf)) { country = wxString(buf, wxConvLocal); strncpy(req->country, country.mb_str(), sizeof (req->country)); } } CRQWizard(event); if (req) delete req; req = 0; } void MyFrame::CRQWizard(wxCommandEvent& event) { tqslTrace("MyFrame::CRQWizard"); char renew = (req != 0) ? 1 : 0; tQSL_Cert cert = (renew ? ((CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()))->getCert() : 0); CRQWiz wiz(req, cert, this, help, renew ? wxT("Renew a Callsign Certificate") : wxT("Request a new Callsign Certificate")); int retval = 0; /* CRQ_ProviderPage *prov = new CRQ_ProviderPage(wiz, req); CRQ_IntroPage *intro = new CRQ_IntroPage(wiz, req); CRQ_NamePage *name = new CRQ_NamePage(wiz, req); CRQ_EmailPage *email = new CRQ_EmailPage(wiz, req); wxSize size = prov->GetSize(); if (intro->GetSize().GetWidth() > size.GetWidth()) size = intro->GetSize(); if (name->GetSize().GetWidth() > size.GetWidth()) size = name->GetSize(); if (email->GetSize().GetWidth() > size.GetWidth()) size = email->GetSize(); CRQ_PasswordPage *pw = new CRQ_PasswordPage(wiz); CRQ_SignPage *sign = new CRQ_SignPage(wiz, size, &(prov->provider)); wxWizardPageSimple::Chain(prov, intro); wxWizardPageSimple::Chain(intro, name); wxWizardPageSimple::Chain(name, email); wxWizardPageSimple::Chain(email, pw); if (renew) sign->cert = ; else wxWizardPageSimple::Chain(pw, sign); wiz.SetPageSize(size); */ if (wiz.RunWizard()) { // Save or upload? wxString file = flattenCallSign(wiz.callsign) + wxT(".") + wxT(TQSL_CRQ_FILE_EXT); bool upload = false; if (wxMessageBox(wxT("Do you want to upload this certificate request to LoTW now?\n" "You do not need an account on LoTW to do this."), wxT("Upload"), wxYES_NO|wxICON_QUESTION, this) == wxYES) { upload = true; // Save it in the working directory #ifdef _WIN32 file = wxString(tQSL_BaseDir, wxConvLocal) + wxT("\\") + file; #else file = wxString(tQSL_BaseDir, wxConvLocal) + wxT("/") + file; #endif } else { // Where to put it? file = wxFileSelector(wxT("Save request"), wxT(""), file, wxT(TQSL_CRQ_FILE_EXT), wxT("tQSL Cert Request files (*.") wxT(TQSL_CRQ_FILE_EXT) wxT(")|*.") wxT(TQSL_CRQ_FILE_EXT) wxT("|All files (") wxT(ALLFILESWILD) wxT(")|") wxT(ALLFILESWILD), wxSAVE | wxOVERWRITE_PROMPT); if (file.IsEmpty()) { wxLogMessage(wxT("Request cancelled")); return; } } TQSL_CERT_REQ req; strncpy(req.providerName, wiz.provider.organizationName, sizeof req.providerName); strncpy(req.providerUnit, wiz.provider.organizationalUnitName, sizeof req.providerUnit); strncpy(req.callSign, wiz.callsign.mb_str(), sizeof req.callSign); strncpy(req.name, wiz.name.mb_str(), sizeof req.name); strncpy(req.address1, wiz.addr1.mb_str(), sizeof req.address1); strncpy(req.address2, wiz.addr2.mb_str(), sizeof req.address2); strncpy(req.city, wiz.city.mb_str(), sizeof req.city); strncpy(req.state, wiz.state.mb_str(), sizeof req.state); strncpy(req.postalCode, wiz.zip.mb_str(), sizeof req.postalCode); if (wiz.country.IsEmpty()) strncpy(req.country, "USA", sizeof req.country); else strncpy(req.country, wiz.country.mb_str(), sizeof req.country); strncpy(req.emailAddress, wiz.email.mb_str(), sizeof req.emailAddress); strncpy(req.password, wiz.password.mb_str(), sizeof req.password); req.dxccEntity = wiz.dxcc; req.qsoNotBefore = wiz.qsonotbefore; req.qsoNotAfter = wiz.qsonotafter; req.signer = wiz.cert; if (req.signer) { char buf[40]; void *call = 0; if (!tqsl_getCertificateCallSign(req.signer, buf, sizeof(buf))) call = &buf; while (tqsl_beginSigning(req.signer, 0, getPassword, call)) { if (tQSL_Error != TQSL_PASSWORD_ERROR) { wxLogError(wxT("%hs"), tqsl_getErrorString()); return; } } } req.renew = renew ? 1 : 0; if (tqsl_createCertRequest(file.mb_str(), &req, 0, 0)) { if (req.signer) tqsl_endSigning(req.signer); wxLogError(wxT("%hs"), tqsl_getErrorString()); return; } if (upload) { ifstream in(file.mb_str(), ios::in | ios::binary); if (!in) { wxLogError(wxT("Error opening certificate request file %s: %hs"), file.c_str(), strerror(errno)); } else { string contents; in.seekg(0, ios::end); contents.resize(in.tellg()); in.seekg(0, ios::beg); in.read(&contents[0], contents.size()); in.close(); wxString fileType(wxT("Certificate Request")); retval = UploadFile(file, file.mb_str(), 0, (void *)contents.c_str(), contents.size(), fileType); if (retval != 0) wxLogError(wxT("Your certificate request did not upload properly\nPlease try again.")); } } else { wxString msg = wxT("You may now send your new certificate request ("); msg += file ; msg += wxT(")"); if (wiz.provider.emailAddress[0] != 0) msg += wxString(wxT("\nto:\n ")) + wxString(wiz.provider.emailAddress, wxConvLocal); if (wiz.provider.url[0] != 0) { msg += wxT("\n"); if (wiz.provider.emailAddress[0] != 0) msg += wxT("or "); msg += wxString(wxT("see:\n ")) + wxString(wiz.provider.url, wxConvLocal); } wxMessageBox(msg, wxT("TQSL")); } if (retval == 0) { wxString pending = wxConfig::Get()->Read(wxT("RequestPending")); if (pending.IsEmpty()) pending = wiz.callsign; else pending += wxT(",") + wiz.callsign; wxConfig::Get()->Write(wxT("RequestPending"),pending); } if (req.signer) tqsl_endSigning(req.signer); cert_tree->Build(CERTLIST_FLAGS); CertTreeReset(); } } void MyFrame::CertTreeReset() { if (!cert_save_label) return; cert_save_label->SetLabel(wxT("\nSave a Callsign Certificate")); cert_renew_label->SetLabel(wxT("\nRenew a Callsign Certificate")); cert_prop_label->SetLabel(wxT("\nDisplay a Callsign Certificate")); cert_menu->Enable(tc_c_Renew, false); cert_renew_button->Enable(false); cert_select_label->SetLabel(wxT("\nSelect a Callsign Certificate to process")); cert_save_button->Enable(false); cert_prop_button->Enable(false); } void MyFrame::OnCertTreeSel(wxTreeEvent& event) { tqslTrace("MyFrame::OnCertTreeSel"); wxTreeItemId id = event.GetItem(); CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(id); if (data) { int keyonly = 0; int expired = 0; int superseded = 0; char call[40]; tqsl_getCertificateCallSign(data->getCert(), call, sizeof call); wxString callSign(call, wxConvLocal); tqsl_getCertificateKeyOnly(data->getCert(), &keyonly); tqsl_isCertificateExpired(data->getCert(), &expired); tqsl_isCertificateSuperceded(data->getCert(), &superseded); tqslTrace("MyFrame::OnCertTreeSel", "call=%s", call); cert_select_label->SetLabel(wxT("")); cert_menu->Enable(tc_c_Properties, true); cert_menu->Enable(tc_c_Export, true); cert_menu->Enable(tc_c_Delete, true); cert_menu->Enable(tc_c_Renew, true); cert_save_button->Enable(true); cert_load_button->Enable(true); cert_prop_button->Enable(true); int w, h; loc_add_label->GetSize(&w, &h); cert_save_label->SetLabel(wxT("\nSave the callsign certificate for ") + callSign); cert_save_label->Wrap(w - 10); cert_prop_label->SetLabel(wxT("\nDisplay the callsign certificate properties for ") + callSign); cert_prop_label->Wrap(w - 10); if (!(keyonly || expired || superseded)) { cert_renew_label->SetLabel(wxT("\nRenew the callsign certificate for ") + callSign); cert_renew_label->Wrap(w - 10); } else { cert_renew_label->SetLabel(wxT("\nRenew a Callsign Certificate")); } cert_menu->Enable(tc_c_Renew, !(keyonly || expired || superseded)); cert_renew_button->Enable(!(keyonly || expired || superseded)); } else { CertTreeReset(); } } void MyFrame::OnCertProperties(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnCertProperties"); CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()); if (data != NULL) displayCertProperties(data, this); } void MyFrame::OnCertExport(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnCertExport"); CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()); if (data == NULL) // "Never happens" return; char call[40]; if (tqsl_getCertificateCallSign(data->getCert(), call, sizeof call)) { wxLogError(wxT("%hs"), tqsl_getErrorString()); return; } tqslTrace("MyFrame::OnCertExport", "call=%s", call); wxString file_default = flattenCallSign(wxString(call, wxConvLocal)); int ko = 0; tqsl_getCertificateKeyOnly(data->getCert(), &ko); if (ko) file_default += wxT("-key-only"); file_default += wxT(".p12"); wxString path = wxConfig::Get()->Read(wxT("CertFilePath"), wxT("")); wxString filename = wxFileSelector(wxT("Enter the name for the new Certificate Container file"), path, file_default, wxT(".p12"), wxT("Certificate Container files (*.p12)|*.p12|All files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT, this); if (filename == wxT("")) return; wxConfig::Get()->Write(wxT("CertFilePath"), wxPathOnly(filename)); GetNewPasswordDialog dial(this, wxT("Certificate Container Password"), wxT("Enter the password for the certificate container file.\n\n") wxT("If you are using a computer system that is shared\n") wxT("with others, you should specify a password to\n") wxT("protect this certificate. However, if you are using\n") wxT("a computer in a private residence, no password need be specified.\n\n") wxT("You will have to enter the password any time you\n") wxT("load the file into TrustedQSL\n\n") wxT("Leave the password blank and click 'Ok' unless you want to\n") wxT("use a password.\n\n"), true, help, wxT("save.htm")); if (dial.ShowModal() != wxID_OK) return; // Cancelled int terr; do { terr = tqsl_beginSigning(data->getCert(), 0, getPassword, (void *)&call); if (terr) { if (tQSL_Error == TQSL_PASSWORD_ERROR) continue; if (tQSL_Error == TQSL_OPERATOR_ABORT) return; wxLogError(wxT("%hs"), tqsl_getErrorString()); } } while (terr); if (tqsl_exportPKCS12File(data->getCert(), filename.mb_str(), dial.Password().mb_str())) wxLogError(wxT("Export to %s failed: %hs"), filename.c_str(), tqsl_getErrorString()); else wxLogMessage(wxT("Certificate saved in file %s"), filename.c_str()); tqsl_endSigning(data->getCert()); } void MyFrame::OnCertDelete(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnCertDelete"); CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()); if (data == NULL) // "Never happens" return; if (wxMessageBox( wxT("WARNING! BE SURE YOU REALLY WANT TO DO THIS!\n\n") wxT("This will permanently remove the certificate from your system.\n") wxT("You will NOT be able to recover it by loading a .TQ6 file.\n") wxT("You WILL be able to recover it from a container (.p12) file only if you have\n") wxT("created one via the Callsign Certificate menu's 'Save Callsign Certificate' command.\n\n") wxT("ARE YOU SURE YOU WANT TO DELETE THE CERTIFICATE?"), wxT("Warning"), wxYES_NO|wxICON_QUESTION, this) == wxYES) { char buf[128]; if (!tqsl_getCertificateCallSign(data->getCert(), buf, sizeof buf)) { wxString call = wxString(buf, wxConvLocal); wxString pending = wxConfig::Get()->Read(wxT("RequestPending")); pending.Replace(call, wxT(""), true); if (pending[0] == ',') pending.Replace(wxT(","), wxT("")); if (pending.Last() == ',') pending.Truncate(pending.Len()-1); wxConfig::Get()->Write(wxT("RequestPending"), pending); } if (tqsl_deleteCertificate(data->getCert())) wxLogError(wxT("%hs"), tqsl_getErrorString()); cert_tree->Build(CERTLIST_FLAGS); CertTreeReset(); } } void MyFrame::LocTreeReset() { if (!loc_edit_button) return; loc_edit_button->Disable(); loc_delete_button->Disable(); loc_prop_button->Disable(); stn_menu->Enable(tm_s_Properties, false); loc_edit_label->SetLabel(wxT("\nEdit a Station Location")); loc_delete_label->SetLabel(wxT("\nDelete a Station Location")); loc_prop_label->SetLabel(wxT("\nDisplay Station Location Properties")); loc_select_label->SetLabel(wxT("\nSelect a Station Location to process")); } void MyFrame::OnLocTreeSel(wxTreeEvent& event) { tqslTrace("MyFrame::OnLocTreeSel"); wxTreeItemId id = event.GetItem(); LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(id); if (data) { int w, h; wxString lname = data->getLocname(); wxString call = data->getCallSign(); tqslTrace("MyFrame::OnLocTreeSel", "lname=%s, call=%s", _S(lname), _S(call)); loc_add_label->GetSize(&w, &h); loc_edit_button->Enable(); loc_delete_button->Enable(); loc_prop_button->Enable(); stn_menu->Enable(tm_s_Properties, true); loc_edit_label->SetLabel(wxT("Edit Station Location ") + call + wxT(": ") + lname); loc_edit_label->Wrap(w - 10); loc_delete_label->SetLabel(wxT("Delete Station Location ") + call + wxT(": ") + lname); loc_delete_label->Wrap(w - 10); loc_prop_label->SetLabel(wxT("Display Station Location Properties for ") + call + wxT(": ") + lname); loc_prop_label->Wrap(w - 10); loc_select_label->SetLabel(wxT("")); } else { LocTreeReset(); } } void MyFrame::OnLocProperties(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLocProperties"); LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(loc_tree->GetSelection()); if (data != NULL) displayLocProperties(data, this); } void MyFrame::OnLocDelete(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLocDelete"); LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(loc_tree->GetSelection()); if (data == NULL) // "Never happens" return; if (wxMessageBox( wxT("This will permanently remove this station location from your system.\n") wxT("ARE YOU SURE YOU WANT TO DELETE THIS LOCATION?"), wxT("Warning"), wxYES_NO|wxICON_QUESTION, this) == wxYES) { if (tqsl_deleteStationLocation(data->getLocname().mb_str())) wxLogError(wxT("%hs"), tqsl_getErrorString()); loc_tree->Build(); LocTreeReset(); } } void MyFrame::OnLocEdit(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLocEdit"); LocTreeItemData *data = (LocTreeItemData *)loc_tree->GetItemData(loc_tree->GetSelection()); if (data == NULL) // "Never happens" return; tQSL_Location loc; wxString selname; char errbuf[512]; check_tqsl_error(tqsl_getStationLocation(&loc, data->getLocname().mb_str())); if (verify_cert(loc)) { // Check if there is a certificate before editing check_tqsl_error(tqsl_getStationLocationErrors(loc, errbuf, sizeof(errbuf))); if (strlen(errbuf) > 0) { wxMessageBox(wxString::Format(wxT("%hs\nThe invalid data was ignored."), errbuf), wxT("Station Location data error"), wxOK|wxICON_EXCLAMATION, this); } char loccall[512]; check_tqsl_error(tqsl_getLocationCallSign(loc, loccall, sizeof loccall)); selname = run_station_wizard(this, loc, help, true, wxString::Format(wxT("Edit Station Location : %hs - %s"), loccall, data->getLocname().c_str())); check_tqsl_error(tqsl_endStationLocationCapture(&loc)); } loc_tree->Build(); LocTreeReset(); } void MyFrame::OnLoginToLogbook(wxCommandEvent& WXUNUSED(event)) { tqslTrace("MyFrame::OnLoginToLogbook"); wxString url = wxConfig::Get()->Read(wxT("LogbookURL"), DEFAULT_LOTW_LOGIN_URL); if (!url.IsEmpty()) wxLaunchDefaultBrowser(url); return; } class CertPropDial : public wxDialog { public: CertPropDial(tQSL_Cert cert, wxWindow *parent = 0); void closeMe(wxCommandEvent&) { wxWindow::Close(TRUE); } DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(CertPropDial, wxDialog) EVT_BUTTON(tc_CertPropDialButton, CertPropDial::closeMe) END_EVENT_TABLE() CertPropDial::CertPropDial(tQSL_Cert cert, wxWindow *parent) : wxDialog(parent, -1, wxT("Certificate Properties"), wxDefaultPosition, wxSize(400, 15 * LABEL_HEIGHT)) { tqslTrace("CertPropDial::CertPropDial", "cert=%lx", (void *)cert); const char *labels[] = { "Begins: ", "Expires: ", "Organization: ", "", "Serial: ", "Operator: ", "Call sign: ", "DXCC Entity: ", "QSO Start Date: ", "QSO End Date: ", "Key: " }; wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *prop_sizer = new wxBoxSizer(wxVERTICAL); int y = 10; for (int i = 0; i < int(sizeof labels / sizeof labels[0]); i++) { wxBoxSizer *line_sizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *st = new wxStaticText(this, -1, wxString(labels[i], wxConvLocal), wxDefaultPosition, wxSize(LABEL_WIDTH, LABEL_HEIGHT), wxALIGN_RIGHT); line_sizer->Add(st); char buf[128] = ""; tQSL_Date date; int dxcc, keyonly; DXCC DXCC; long serial; switch (i) { case 0: tqsl_getCertificateKeyOnly(cert, &keyonly); if (keyonly) strncpy(buf, "N/A", sizeof buf); else if (!tqsl_getCertificateNotBeforeDate(cert, &date)) tqsl_convertDateToText(&date, buf, sizeof buf); break; case 1: tqsl_getCertificateKeyOnly(cert, &keyonly); if (keyonly) strncpy(buf, "N/A", sizeof buf); else if (!tqsl_getCertificateNotAfterDate(cert, &date)) tqsl_convertDateToText(&date, buf, sizeof buf); break; case 2: tqsl_getCertificateIssuerOrganization(cert, buf, sizeof buf); break; case 3: tqsl_getCertificateIssuerOrganizationalUnit(cert, buf, sizeof buf); break; case 4: tqsl_getCertificateKeyOnly(cert, &keyonly); if (keyonly) strncpy(buf, "N/A", sizeof buf); else { tqsl_getCertificateSerial(cert, &serial); snprintf(buf, sizeof buf, "%ld", serial); } break; case 5: tqsl_getCertificateKeyOnly(cert, &keyonly); if (keyonly) strncpy(buf, "N/A", sizeof buf); else tqsl_getCertificateAROName(cert, buf, sizeof buf); break; case 6: tqsl_getCertificateCallSign(cert, buf, sizeof buf); break; case 7: tqsl_getCertificateDXCCEntity(cert, &dxcc); DXCC.getByEntity(dxcc); strncpy(buf, DXCC.name(), sizeof buf); break; case 8: if (!tqsl_getCertificateQSONotBeforeDate(cert, &date)) tqsl_convertDateToText(&date, buf, sizeof buf); break; case 9: if (!tqsl_getCertificateQSONotAfterDate(cert, &date)) tqsl_convertDateToText(&date, buf, sizeof buf); break; case 10: // tqsl_getCertificateKeyOnly(cert, &keyonly); // if (keyonly) // strncpy(buf, "N/A", sizeof buf); // else { switch (tqsl_getCertificatePrivateKeyType(cert)) { case TQSL_PK_TYPE_ERR: wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), wxT("Error")); strncpy(buf, "", sizeof buf); break; case TQSL_PK_TYPE_NONE: strncpy(buf, "None", sizeof buf); break; case TQSL_PK_TYPE_UNENC: strncpy(buf, "Unencrypted", sizeof buf); break; case TQSL_PK_TYPE_ENC: strncpy(buf, "Password protected", sizeof buf); break; } // } break; } line_sizer->Add( new wxStaticText(this, -1, wxString(buf, wxConvLocal)) ); prop_sizer->Add(line_sizer); y += LABEL_HEIGHT; } topsizer->Add(prop_sizer, 0, wxALL, 10); topsizer->Add( new wxButton(this, tc_CertPropDialButton, wxT("Close")), 0, wxALIGN_CENTER | wxALL, 10 ); SetAutoLayout(TRUE); SetSizer(topsizer); topsizer->Fit(this); topsizer->SetSizeHints(this); CenterOnParent(); } void displayCertProperties(CertTreeItemData *item, wxWindow *parent) { tqslTrace("displayCertProperties", "item=%lx", (void *)item); if (item != NULL) { CertPropDial dial(item->getCert(), parent); dial.ShowModal(); } } class LocPropDial : public wxDialog { public: LocPropDial(wxString locname, wxWindow *parent = 0); void closeMe(wxCommandEvent&) { wxWindow::Close(TRUE); } DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(LocPropDial, wxDialog) EVT_BUTTON(tl_LocPropDialButton, LocPropDial::closeMe) END_EVENT_TABLE() LocPropDial::LocPropDial(wxString locname, wxWindow *parent) : wxDialog(parent, -1, wxT("Station Location Properties"), wxDefaultPosition, wxSize(1000, 15 * LABEL_HEIGHT)) { tqslTrace("LocPropDial", "locname=%s", _S(locname)); const char *fields[] = { "CALL", "Call sign: ", "DXCC", "DXCC Entity: ", "GRIDSQUARE", "Grid Square: ", "ITUZ", "ITU Zone: ", "CQZ", "CQ Zone: ", "IOTA", "IOTA Locator: ", "US_STATE", "State: ", "US_COUNTY", "County: ", "CA_PROVINCE", "Province: ", "RU_OBLAST", "Oblast: ", "CN_PROVINCE", "Province: ", "AU_STATE", "State: " }; tQSL_Location loc; check_tqsl_error(tqsl_getStationLocation(&loc, locname.mb_str())); wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer *prop_sizer = new wxBoxSizer(wxVERTICAL); int y = 10; char fieldbuf[512]; for (int i = 0; i < int(sizeof fields / sizeof fields[0]); i+=2) { if (tqsl_getStationLocationField(loc, fields[i], fieldbuf, sizeof fieldbuf) == 0) { if (strlen(fieldbuf) > 0) { wxBoxSizer *line_sizer = new wxBoxSizer(wxHORIZONTAL); wxStaticText *st = new wxStaticText(this, -1, wxString(fields[i+1], wxConvLocal), wxDefaultPosition, wxSize(LABEL_WIDTH, LABEL_HEIGHT), wxALIGN_RIGHT); line_sizer->Add(st, 30); if (!strcmp(fields[i], "DXCC")) { int dxcc = strtol(fieldbuf, NULL, 10); const char *dxccname = NULL; tqsl_getDXCCEntityName(dxcc, &dxccname); strncpy(fieldbuf, dxccname, sizeof fieldbuf); } line_sizer->Add( new wxStaticText(this, -1, wxString(fieldbuf, wxConvLocal), wxDefaultPosition, wxSize(LABEL_WIDTH, LABEL_HEIGHT)), 70 ); prop_sizer->Add(line_sizer); y += LABEL_HEIGHT; } } } topsizer->Add(prop_sizer, 0, wxALL, 10); topsizer->Add( new wxButton(this, tl_LocPropDialButton, wxT("Close")), 0, wxALIGN_CENTER | wxALL, 10 ); SetAutoLayout(TRUE); SetSizer(topsizer); topsizer->Fit(this); topsizer->SetSizeHints(this); CenterOnParent(); } void displayLocProperties(LocTreeItemData *item, wxWindow *parent) { tqslTrace("displayLocProperties", "item=%lx", item); if (item != NULL) { LocPropDial dial(item->getLocname(), parent); dial.ShowModal(); } } int getPassword(char *buf, int bufsiz, void *callsign) { tqslTrace("getPassword", "buf=%lx, bufsiz=%d, callsign=%s", buf, bufsiz, callsign ? callsign : "NULL"); wxString prompt(wxT("Enter the password to unlock the callsign certificate")); if (callsign) prompt = prompt + wxT(" for ") + wxString((const char *)callsign, wxConvLocal); tqslTrace("getPassword", "Probing for top window"); wxWindow* top = wxGetApp().GetTopWindow(); tqslTrace("getPassword", "Top window = 0x%lx", (void *)top); top->SetFocus(); tqslTrace("getPassword", "Focus grabbed. About to pop up password dialog"); GetPasswordDialog dial(top, wxT("Enter password"), prompt); if (dial.ShowModal() != wxID_OK) { tqslTrace("getPassword", "Password entry cancelled"); return 1; } tqslTrace("getPassword", "Password entered OK"); strncpy(buf, dial.Password().mb_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } void displayTQSLError(const char *pre) { tqslTrace("displayTQSLError", "pre=%s", pre); wxString s(pre, wxConvLocal); s += wxT(":\n"); s += wxString(tqsl_getErrorString(), wxConvLocal); wxMessageBox(s, wxT("Error")); } static wxString flattenCallSign(const wxString& call) { tqslTrace("flattenCallSign", "call=%s", _S(call)); wxString flat = call; size_t idx; while ((idx = flat.find_first_not_of(wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_"))) != wxString::npos) flat[idx] = '_'; return flat; } void tqslTrace(const char *name, const char *format, ...) { va_list ap; if (!diagFile) return; fprintf(diagFile, "%s: ", name); if (!format) { fprintf(diagFile, "\r\n"); fflush(diagFile); return; } va_start (ap, format); vfprintf(diagFile, format, ap); va_end(ap); fprintf(diagFile, "\r\n"); fflush(diagFile); } tqsl-2.0/apps/tqsl.50000664000076400007640000001131612231073120014353 0ustar rmurphyrmurphy.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH TQSL 5 "August 28, 2013" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .ll -5 .SH NAME TQSL \- digitally sign amateur radio contact logs .SH SYNOPSIS .B tqsl .RI \-i\ [ certificate-file ] "" ... .PP .B tqsl .RI [ OPTIONS ] .RI [ log-file ] "" ... .SH DESCRIPTION .B TrustedQSL is a file format and set of procedures that is used to send digitally signed QSL information (logs of contacts between amateur radio operators). One notable service that makes use of TrustedQSL is ARRL's .I Logbook of the World. .PP The \fBtqsl\fP program is used to digitally sign contact log files using a digital certificate. It is also used to generate requests for digital certificates and to store the resulting received digital certificates. (Certificates used to be handled by a separate program, \fBtqslcert\fP, but all functions are now handled by tqsl). .PP This manual page briefly documents the \fBtqsl\fP program. Complete documentation is also available: .sp \fBtqsl\fP: file:///usr/share/TrustedQSL/help/tqslapp/main.htm .SH OPTIONS .PP \fBtqsl\fP accepts these command line options: .TP .B \-b \fIbegin_date\fP and \-e \fIend_date\fP Supply a start date and end date for QSOs to be signed. If present, any QSOs before the begin date will be ignored, and any after the end date will be ignored. If either begin or end are omitted, then the corresponding limit is ignored. You should specify \fI-d\fP with this option to suppress the normal date range dialog as these options will override the user-specified dates if given. .TP .B \-d Suppress date-range dialog. If present, the QSO date-range dialog will not be shown for files that follow this option on the command line. .TP .B \-l \fIlocation_name\fP Selects an existing station location. This location will be used for the commands that follow. If the station location doesn't exist, \fBtqsl\fP will just exit. .TP .B \-o \fIoutput_file\fP Writes the resulting signed log file to \fIoutput_file\fP instead of a default name based on the input \fIlog-file\fP name. .TP .B \-s Add or edit station location. If there is a preceding -l option the specified location will be edited. If there is no preceding -l option, a new station location is being added. .TP .BR \-x " (or) " \-q Exit \fBtqsl\fP. If this argument is used it should be the last one on the command line. If this argument is not present, \fBtqsl\fP will begin normal operation after successfully processing all command-line arguments. .TP .B \-u Upload log file. If this argument is used, the input files will be signed then automatically uploaded to the Logbook of the World web site for processing. .TP .B \-v Display the version number of \fBtqsl\fP and exit. .TP .B \-i filename Import a certificate - either a signed response (.tq6) or a certificate stored with a private key in PKCS#12 format (.p12). .TP .B \-t filename Open a diagnostic trace file at startup. This file will log internal TQSL function calls for debugging purposes. .TP .B log-files Any command-line parameter that is not an option or an option's argument will be treated as the name of a log file (ADIF or Cabrillo) to be signed. The resulting signed file (.tq8) will be placed in the same directory as the log file, overwriting any existing .tq8 file of the same name. (Note: If this option is not preceded by a -l option that selects the station location to be used for signing, the Select Station Location for Signing dialog will be presented.) File names that contain spaces or other shell-special characters should be quoted in a manner suitable for the operating system and shell that's being used. If -u is used, the signed log is not saved to disk but is instead uploaded and submitted to Logbook of the World. .sp N.B.: If the private key needed to sign a log is protected by a password, the user will be prompted to supply that password for each file being signed. .SH AUTHOR trustedqsl was written by "American Radio Relay League, Inc." and the TrustedQSL authors. Please see the AUTHORS.txt file in the source distribution for a list of contributors. .PP This manual page was originally prepared by Kamal Mostafa , for the Debian project (and may be used by others). tqsl-2.0/apps/tqsl-new.ico0000664000076400007640000001266612231073120015561 0ustar rmurphyrmurphy  (& hN( @ ,/2LH\p_[q([jw0Qf>ll[v')JK<<<8G,sn^1NcKxq[v'Fq\\kv~^8[qIvsZt'3U5 UfsQs_<^wMy{Yv'1X .XhtJqRr`9\rKy~Vv '/V + ^yJsYzd;_qO}Ss '4X)[vNw\k@e|N{~Nq+  ;[ *gQ}\pEjHy{d %7 9b -kZgsFkPe1X2qOTE ` @k 0o]huJpU%1}L@o7sbrtInf(:!.4=T1.yQ<ujwu]?ekw,/,F2[Q '. |o|zghOqOw}#0@ }Qf5LiAKVGMX!!!5[pӇ$ & class item { public: wxString name; wxString call; wxString label; }; class TQSLStationListBox; class TQSLGetStationNameDialog : public wxDialog { public: TQSLGetStationNameDialog(wxWindow *parent, wxHtmlHelpController *help = 0, const wxPoint& pos = wxDefaultPosition, bool i_issave = false, const wxString& title = wxT(""), const wxString& okLabel = wxT("Ok"), bool i_editonly = false); void OnOk(wxCommandEvent& event); void OnCancel(wxCommandEvent& event); void OnDelete(wxCommandEvent& event); void OnHelp(wxCommandEvent& event); void OnNew(wxCommandEvent& event); void OnModify(wxCommandEvent& event); void OnNamelist(wxCommandEvent& event); void OnNameChange(wxCommandEvent& event); void OnDblClick(wxCommandEvent& event); wxString Selected() { return name_entry->GetValue().Trim(); } void DisplayProperties(wxCommandEvent& event); void SelectName(const wxString& name); virtual int ShowModal(); protected: void UpdateButtons(); void UpdateControls(); void RefreshList(); void OnSetFocus(wxFocusEvent& event); TQSLStationListBox *namelist; wxString _station_data_name; std::vector item_data; wxString _selected; bool issave, editonly; wxTextCtrl *name_entry; wxButton *okbut, *delbut, *newbut, *modbut; bool hack; int want_selected; bool updating; wxArrayInt sels; bool firstFocused; wxHtmlHelpController *_help; DECLARE_EVENT_TABLE() }; #endif // __stationdial_h tqsl-2.0/apps/stationdial.cpp0000664000076400007640000003256712231073120016334 0ustar rmurphyrmurphy/*************************************************************************** stationdial.cpp - description ------------------- begin : Mon Nov 11 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: stationdial.cpp,v 1.6 2013/03/01 13:00:59 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #define TQSL_ID_LOW 6000 #include "stationdial.h" #include "tqslwiz.h" #include "tqslexcept.h" #include "tqsltrace.h" #include #include #include "tqsllib.h" #include "wxutil.h" #include using namespace std; #define GS_NAMELIST TQSL_ID_LOW #define GS_OKBUT TQSL_ID_LOW+1 #define GS_CANCELBUT TQSL_ID_LOW+2 #define GS_NAMEENTRY TQSL_ID_LOW+3 #define GS_DELETEBUT TQSL_ID_LOW+4 #define GS_NEWBUT TQSL_ID_LOW+5 #define GS_MODIFYBUT TQSL_ID_LOW+6 #define GS_CMD_PROPERTIES TQSL_ID_LOW+7 #define GS_HELPBUT TQSL_ID_LOW+8 class TQSLStationListBox : public wxListBox { public: TQSLStationListBox(wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, int n = 0, const wxString choices[] = NULL, long style = 0) : wxListBox(parent, id, pos, size, n, choices, style) {} void OnRightDown(wxMouseEvent& event); DECLARE_EVENT_TABLE() }; BEGIN_EVENT_TABLE(TQSLStationListBox, wxListBox) EVT_RIGHT_DOWN(TQSLStationListBox::OnRightDown) END_EVENT_TABLE() void TQSLStationListBox::OnRightDown(wxMouseEvent& event) { wxMenu menu; menu.Append(GS_CMD_PROPERTIES, wxT("&Properties")); PopupMenu(&menu, event.GetPosition()); } class PropList : public wxDialog { public: PropList(wxWindow *parent); wxListCtrl *list; }; PropList::PropList(wxWindow *parent) : wxDialog(parent, -1, wxT("Properties"), wxDefaultPosition, wxSize(400, 300)) { tqslTrace("PropList::PropList", "parent=0x%lx", (void *)parent); list = new wxListCtrl(this, -1, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_SINGLE_SEL); list->InsertColumn(0, wxT("Name"), wxLIST_FORMAT_LEFT, 100); list->InsertColumn(1, wxT("Value"), wxLIST_FORMAT_LEFT, 300); wxLayoutConstraints *c = new wxLayoutConstraints; c->top.SameAs (this, wxTop); c->left.SameAs (this, wxLeft); c->right.SameAs (this, wxRight); c->height.PercentOf (this, wxHeight, 66); list->SetConstraints(c); CenterOnParent(); } static void check_tqsl_error(int rval) { if (rval == 0) return; throw TQSLException(tqsl_getErrorString()); } static bool itemLess(const item& s1, const item& s2) { int i = s1.call.CmpNoCase(s2.call); if (i == 0) i = s1.name.CmpNoCase(s2.name); return (i < 0); } BEGIN_EVENT_TABLE(TQSLGetStationNameDialog, wxDialog) EVT_BUTTON(GS_OKBUT, TQSLGetStationNameDialog::OnOk) EVT_BUTTON(GS_CANCELBUT, TQSLGetStationNameDialog::OnCancel) EVT_BUTTON(GS_DELETEBUT, TQSLGetStationNameDialog::OnDelete) EVT_BUTTON(GS_HELPBUT, TQSLGetStationNameDialog::OnHelp) EVT_BUTTON(GS_NEWBUT, TQSLGetStationNameDialog::OnNew) EVT_BUTTON(GS_MODIFYBUT, TQSLGetStationNameDialog::OnModify) EVT_LISTBOX(GS_NAMELIST, TQSLGetStationNameDialog::OnNamelist) EVT_LISTBOX_DCLICK(GS_NAMELIST, TQSLGetStationNameDialog::OnDblClick) EVT_TEXT(GS_NAMEENTRY, TQSLGetStationNameDialog::OnNameChange) EVT_MENU(GS_CMD_PROPERTIES, TQSLGetStationNameDialog::DisplayProperties) EVT_SET_FOCUS(TQSLGetStationNameDialog::OnSetFocus) END_EVENT_TABLE() void TQSLGetStationNameDialog::OnSetFocus(wxFocusEvent& event) { if (!firstFocused) { firstFocused = true; if (issave) { if (name_entry) name_entry->SetFocus(); } else if (namelist) namelist->SetFocus(); } } void TQSLGetStationNameDialog::OnOk(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnOk"); wxString s = name_entry->GetValue().Trim().Trim(false); if (editonly) EndModal(wxID_CANCEL); else if (s != wxT("")) { _selected = s; EndModal(wxID_OK); } } void TQSLGetStationNameDialog::OnCancel(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnCancel"); EndModal(wxID_CANCEL); } // Reset the list of Station Locations in the listbox void TQSLGetStationNameDialog::RefreshList() { tqslTrace("TQSLGetStationNameDialog::RefreshList"); namelist->Clear(); item_data.clear(); int n; tQSL_Location loc; check_tqsl_error(tqsl_initStationLocationCapture(&loc)); check_tqsl_error(tqsl_getNumStationLocations(loc, &n)); for (int i = 0; i < n && i < 2000; i++) { item it; char buf[256]; check_tqsl_error(tqsl_getStationLocationName(loc, i, buf, sizeof buf)); it.name = wxString(buf, wxConvLocal); char cbuf[256]; check_tqsl_error(tqsl_getStationLocationCallSign(loc, i, cbuf, sizeof cbuf)); it.call = wxString(cbuf, wxConvLocal); it.label = it.call + wxT(" - ") + it.name; item_data.push_back(it); } sort(item_data.begin(), item_data.end(), itemLess); for (int i = 0; i < (int)item_data.size(); i++) namelist->Append(item_data[i].label, &(item_data[i].name)); } TQSLGetStationNameDialog::TQSLGetStationNameDialog(wxWindow *parent, wxHtmlHelpController *help, const wxPoint& pos, bool i_issave, const wxString& title, const wxString& okLabel, bool i_editonly) : wxDialog(parent, -1, wxT("Select Station Data"), pos), issave(i_issave), editonly(i_editonly), newbut(0), modbut(0), updating(false), firstFocused(false), _help(help) { tqslTrace("TQSLGetStationNameDialog::TQSLGetStationNameDialog", "parent=0x%lx, i_issave=%d, title=%s, okLabel=%s, i_editonly=%d", parent, i_issave, _S(title), _S(okLabel), i_editonly); wxBoxSizer *topsizer = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxSize text_size = getTextSize(this); int control_width = text_size.GetWidth()*30; if (title != wxT("")) SetTitle(title); else if (issave) SetTitle(wxT("Save Station Data")); // List namelist = new TQSLStationListBox(this, GS_NAMELIST, wxDefaultPosition, wxSize(control_width, text_size.GetHeight()*10), 0, 0, wxLB_MULTIPLE|wxLB_HSCROLL|wxLB_ALWAYS_SB); sizer->Add(namelist, 1, wxALL|wxEXPAND, 10); RefreshList(); sizer->Add(new wxStaticText(this, -1, issave ? wxT("Enter a name for this Station Location") : wxT("Selected Station Location")), 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 10); name_entry = new wxTextCtrl(this, GS_NAMEENTRY, wxT(""), wxDefaultPosition, wxSize(control_width, -1)); if (!issave) name_entry->Enable(false); sizer->Add(name_entry, 0, wxALL|wxEXPAND, 10); topsizer->Add(sizer, 1, 0, 0); wxBoxSizer *button_sizer = new wxBoxSizer(wxVERTICAL); if (!issave) { newbut = new wxButton(this, GS_NEWBUT, wxT("New...")); newbut->Enable(TRUE); button_sizer->Add(newbut, 0, wxALL|wxALIGN_TOP, 3); modbut = new wxButton(this, GS_MODIFYBUT, wxT("Edit...")); modbut->Enable(FALSE); button_sizer->Add(modbut, 0, wxALL|wxALIGN_TOP, 3); } delbut = new wxButton(this, GS_DELETEBUT, wxT("Delete")); delbut->Enable(FALSE); button_sizer->Add(delbut, 0, wxALL|wxALIGN_TOP, 3); button_sizer->Add(new wxStaticText(this, -1, wxT("")), 1, wxEXPAND); if (_help) button_sizer->Add(new wxButton(this, GS_HELPBUT, wxT("Help") ), 0, wxALL|wxALIGN_BOTTOM, 3); if (!editonly) button_sizer->Add(new wxButton(this, GS_CANCELBUT, wxT("Cancel") ), 0, wxALL|wxALIGN_BOTTOM, 3); okbut = new wxButton(this, GS_OKBUT, okLabel ); button_sizer->Add(okbut, 0, wxALL|wxALIGN_BOTTOM, 3); topsizer->Add(button_sizer, 0, wxTOP|wxBOTTOM|wxRIGHT|wxEXPAND, 7); hack = (namelist->GetCount() > 0) ? true : false; UpdateControls(); SetAutoLayout(TRUE); SetSizer(topsizer); topsizer->Fit(this); topsizer->SetSizeHints(this); CentreOnParent(); } void TQSLGetStationNameDialog::UpdateButtons() { tqslTrace("TQSLGetStationNameDialog::UpdateButtons"); wxArrayInt newsels; namelist->GetSelections(newsels); delbut->Enable(newsels.GetCount() > 0); if (modbut) modbut->Enable(newsels.GetCount() > 0); wxArrayInt sels; namelist->GetSelections(sels); if (!editonly) okbut->Enable(issave ? (name_entry->GetValue().Trim() != wxT("")) : (sels.GetCount() > 0)); } void TQSLGetStationNameDialog::UpdateControls() { tqslTrace("TQSLGetStationNameDialog::UpdateControls"); if (updating) // Sentinel to prevent recursion return; updating = true; wxArrayInt newsels; namelist->GetSelections(newsels); int newsel = -1; for (int i = 0; i < (int)newsels.GetCount(); i++) { if (sels.Index(newsels[i]) == wxNOT_FOUND) { newsel = newsels[i]; break; } } //cout << "newsel: " << newsel << endl; if (newsel > -1) { for (int i = 0; i < (int)newsels.GetCount(); i++) { if (newsels[i] != newsel) namelist->Deselect(newsels[i]); } } namelist->GetSelections(sels); int idx = (sels.GetCount() > 0) ? sels[0] : -1; //cout << "UpdateControls selection: " << idx << endl; if (idx >= 0) name_entry->SetValue((idx < 0) ? wxT("") : *(wxString *)namelist->GetClientData(idx)); UpdateButtons(); //cout << "UpdateControls selection(1): " << idx << endl; updating = false; } void TQSLGetStationNameDialog::OnDelete(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnDelete"); wxArrayInt newsels; namelist->GetSelections(newsels); int idx = (newsels.GetCount() > 0) ? newsels[0] : -1; if (idx < 0) return; wxString name = *(wxString *)namelist->GetClientData(idx); if (name == wxT("")) return; if (wxMessageBox(wxString(wxT("Delete \"")) + name + wxT("\"?"), wxT("TQSL Confirm"), wxYES_NO|wxCENTRE, this) == wxYES) { check_tqsl_error(tqsl_deleteStationLocation(name.mb_str())); if (!issave) name_entry->Clear(); RefreshList(); UpdateControls(); } } void TQSLGetStationNameDialog::OnNamelist(wxCommandEvent& event) { tqslTrace("TQSLGetStationNameDialog::OnNamelist"); /* if (hack) { // We seem to get an extraneous start-up event (GTK only?) cout << "OnNamelist hack" << endl; hack = false; if (want_selected < 0) namelist->Deselect(0); else namelist->SetSelection(want_selected); } */ //cout << "OnNamelist" << endl; UpdateControls(); } void TQSLGetStationNameDialog::OnDblClick(wxCommandEvent& event) { tqslTrace("TQSLGetStationNameDialog::OnDblClick"); if(editonly) { OnNamelist(event); EndModal(wxID_MORE); } else { UpdateControls(); OnOk(event); } //updatecontrols sets up the text field that ok checks } void TQSLGetStationNameDialog::OnNew(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnNew"); EndModal(wxID_APPLY); } void TQSLGetStationNameDialog::OnModify(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnModify"); EndModal(wxID_MORE); } void TQSLGetStationNameDialog::OnHelp(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnHelp"); if (_help) _help->Display(wxT("stnloc.htm")); } void TQSLGetStationNameDialog::OnNameChange(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::OnNameChange"); UpdateButtons(); } void TQSLGetStationNameDialog::DisplayProperties(wxCommandEvent&) { tqslTrace("TQSLGetStationNameDialog::DisplayProperties"); wxArrayInt newsels; namelist->GetSelections(newsels); int idx = (newsels.GetCount() > 0) ? newsels[0] : -1; if (idx < 0) return; wxString name = *(wxString *)namelist->GetClientData(idx); if (name == wxT("")) return; tQSL_Location loc; try { map props; check_tqsl_error(tqsl_getStationLocation(&loc, name.mb_str())); do { int nfield; check_tqsl_error(tqsl_getNumLocationField(loc, &nfield)); for (int i = 0; i < nfield; i++) { char buf[256]; check_tqsl_error(tqsl_getLocationFieldDataLabel(loc, i, buf, sizeof buf)); wxString key = wxString(buf, wxConvLocal); int type; check_tqsl_error(tqsl_getLocationFieldDataType(loc, i, &type)); if (type == TQSL_LOCATION_FIELD_DDLIST || type == TQSL_LOCATION_FIELD_LIST) { int sel; check_tqsl_error(tqsl_getLocationFieldIndex(loc, i, &sel)); check_tqsl_error(tqsl_getLocationFieldListItem(loc, i, sel, buf, sizeof buf)); } else check_tqsl_error(tqsl_getLocationFieldCharData(loc, i, buf, sizeof buf)); props[key] = wxString(buf, wxConvLocal); } int rval; if (tqsl_hasNextStationLocationCapture(loc, &rval) || !rval) break; check_tqsl_error(tqsl_nextStationLocationCapture(loc)); } while(1); check_tqsl_error(tqsl_endStationLocationCapture(&loc)); PropList plist(this); int i = 0; for (map::iterator it = props.begin(); it != props.end(); it++) { plist.list->InsertItem(i, it->first); plist.list->SetItem(i, 1, it->second); i++; //cout << idx << ", " << it->first << " => " << it->second << endl; } plist.ShowModal(); } catch (TQSLException& x) { wxLogError(wxT("%hs"), x.what()); } } void TQSLGetStationNameDialog::SelectName(const wxString& name) { tqslTrace("TQSLGetStationNameDialog::SelectName", "name=%s", _S(name)); wxArrayInt sels; namelist->GetSelections(sels); for (int i = 0; i < (int)sels.GetCount(); i++) namelist->Deselect(sels[i]); for (int i = 0; i < (int) namelist->GetCount(); i++) { if (name == *(wxString *)namelist->GetClientData(i)) { namelist->SetSelection(i, TRUE); break; } } namelist->GetSelections(sels); UpdateControls(); } int TQSLGetStationNameDialog::ShowModal() { tqslTrace("TQSLGetStationNameDialog::ShowModal"); if (namelist->GetCount() == 0 && !issave) wxMessageBox(wxT("You have no Station Locations defined.\n\n") wxT("You must define at least one Station Location to use for signing.\n") wxT("Use the \"New\" Button of the dialog you're about to see to\ndefine a Station Location."), wxT("TQSL Warning"), wxOK, this); return wxDialog::ShowModal(); } tqsl-2.0/apps/save.xpm0000664000076400007640000002675212231073120015000 0ustar rmurphyrmurphy/* XPM */ static const char * save_xpm[] = { "48 48 431 2", " c None", ". c #4CA21B", "+ c #4CA61A", "@ c #51A520", "# c #58AB28", "$ c #58AA29", "% c #50A41E", "& c #4DA61B", "* c #5BA82B", "= c #A6DE8D", "- c #E6FADE", "; c #E4FBDC", "> c #E3FBDB", ", c #CBF8BC", "' c #D5F8CA", ") c #BFF0AD", "! c #94D976", "~ c #64B038", "{ c #4EA41B", "] c #4DA419", "^ c #90CE71", "/ c #E4FADC", "( c #E3FADB", "_ c #CBF1BC", ": c #9DE381", "< c #B2ED9B", "[ c #D2F9C5", "} c #90F070", "| c #60E933", "1 c #CCF8BD", "2 c #A9E691", "3 c #61AF34", "4 c #4EA31A", "5 c #86CA64", "6 c #E2F9DA", "7 c #B0DC9A", "8 c #53A525", "9 c #409912", "0 c #3F9612", "a c #469F16", "b c #5CAD2F", "c c #ADEC96", "d c #ACF395", "e c #41E50B", "f c #42E50D", "g c #82EE5F", "h c #C8F6B8", "i c #85CE63", "j c #4DA31A", "k c #4CA31A", "l c #4DCA1A", "m c #5EAB31", "n c #3A910F", "o c #2B8606", "p c #2B8506", "q c #358D0B", "r c #4CA21C", "s c #9BE67F", "t c #96F078", "u c #3DE406", "v c #4EE51C", "w c #B2F39C", "x c #9CDF81", "y c #4FA51D", "z c #4EA21B", "A c #4CA21A", "B c #34930A", "C c #2E9006", "D c #339309", "E c #4DA41C", "F c #B3F09D", "G c #5FE732", "H c #3DE106", "I c #3DDF06", "J c #42DF0C", "K c #9EEE83", "L c #99DE7D", "M c #4FA31C", "N c #4EA01C", "O c #38A00A", "P c #34A007", "Q c #35A007", "R c #4C9F1A", "S c #66B83B", "T c #B2F29C", "U c #40DE0A", "V c #3DDC07", "W c #3EDA07", "X c #41DA0B", "Y c #A1EC86", "Z c #83CD60", "` c #4EA41A", " . c #9B9B9B", ".. c #9A9A9A", "+. c #999999", "@. c #46A513", "#. c #39AF07", "$. c #3FAB0C", "%. c #4DA01B", "&. c #4DA51A", "*. c #9AE47E", "=. c #6DE343", "-. c #3ED907", ";. c #3ED707", ">. c #3ED608", ",. c #48D615", "'. c #AFEC99", "). c #5FAE32", "!. c #9C9C9C", "~. c #A2A2A2", "{. c #D0D0D0", "]. c #EEEEEE", "^. c #FBFBFB", "/. c #868686", "(. c #8B8B8B", "_. c #909090", ":. c #8F8F8F", "<. c #929292", "[. c #969696", "}. c #4BA218", "|. c #40B50B", "1. c #3CBB07", "2. c #45AE10", "3. c #6EBD44", "4. c #A0EB85", "5. c #3ED408", "6. c #3FD308", "7. c #3FD108", "8. c #64D938", "9. c #9CDE7E", "0. c #ADADAD", "a. c #DADADA", "b. c #F3F3F3", "c. c #FCFCFC", "d. c #F8F8F8", "e. c #858585", "f. c #848484", "g. c #838383", "h. c #44AB0E", "i. c #4FA21C", "j. c #B0EB9A", "k. c #4FD71C", "l. c #3FD009", "m. c #3FCE09", "n. c #3FCD09", "o. c #A1E686", "p. c #64AF38", "q. c #B9B9B9", "r. c #E4E4E4", "s. c #F7F7F7", "t. c #FAFAFA", "u. c #F6F6F6", "v. c #F5F5F5", "w. c #7B7B7B", "x. c #4A4A4A", "y. c #3B3B3B", "z. c #474747", "A. c #828282", "B. c #4DA41A", "C. c #92D872", "D. c #6EDB45", "E. c #3FCB09", "F. c #40CA0A", "G. c #6FD647", "H. c #8BD06A", "I. c #55A027", "J. c #9E9E9E", "K. c #C8C8C8", "L. c #EBEBEB", "M. c #F4F4F4", "N. c #3E3E3E", "O. c #3F3F3F", "P. c #5C5C5C", "Q. c #818181", "R. c #77C152", "S. c #8AE069", "T. c #40C80A", "U. c #40C70A", "V. c #4DC91B", "W. c #A5E08B", "X. c #54A325", "Y. c #D4D4D4", "Z. c #F1F1F1", "`. c #F9F9F9", " + c #545454", ".+ c #5F5F5F", "++ c #64B338", "@+ c #9CE380", "#+ c #40C60A", "$+ c #40C50A", "%+ c #40C30B", "&+ c #41C20B", "*+ c #A3E088", "=+ c #5CA92F", "-+ c #EAF2E6", ";+ c #F2F2F2", ">+ c #1D1D1D", ",+ c #4EA11B", "'+ c #4EA11C", ")+ c #5AA82C", "!+ c #A4E48A", "~+ c #41C00B", "{+ c #41BF0B", "]+ c #94DA76", "^+ c #63AF38", "/+ c #53A323", "(+ c #53A322", "_+ c #F0F0F0", ":+ c #808080", "<+ c #B0E79A", "[+ c #B2E89C", "}+ c #B2E89B", "|+ c #B0E69A", "1+ c #AFE699", "2+ c #ADE597", "3+ c #41BD0B", "4+ c #41BC0C", "5+ c #91D772", "6+ c #A7DE8E", "7+ c #A6DC8C", "8+ c #A5DC8C", "9+ c #A4DA8A", "0+ c #A3D989", "a+ c #51A420", "b+ c #91B878", "c+ c #DFDFDF", "d+ c #EFEFEF", "e+ c #6ABB41", "f+ c #A0E385", "g+ c #47C713", "h+ c #41BA0C", "i+ c #42B90C", "j+ c #42B70C", "k+ c #42B60D", "l+ c #42B40D", "m+ c #43B40F", "n+ c #8BCF69", "o+ c #71BB4A", "p+ c #6AAA43", "q+ c #C6C7C6", "r+ c #C6C6C6", "s+ c #D8D8D8", "t+ c #E8E8E8", "u+ c #EDEDED", "v+ c #222222", "w+ c #7F7F7F", "x+ c #4DA31B", "y+ c #83CD5F", "z+ c #86D863", "A+ c #41BD0C", "B+ c #42B30D", "C+ c #43B10D", "D+ c #6EC245", "E+ c #87C965", "F+ c #54A324", "G+ c #B9C1B4", "H+ c #C3C3C3", "I+ c #C2C2C2", "J+ c #D7D7D7", "K+ c #ECECEC", "L+ c #757575", "M+ c #383838", "N+ c #7E7E7E", "O+ c #52A31F", "P+ c #96D978", "Q+ c #66CA3C", "R+ c #43B00E", "S+ c #54B524", "T+ c #92CF73", "U+ c #5BA72D", "V+ c #9CB78C", "W+ c #C0C0C0", "X+ c #BFBFBF", "Y+ c #BEBEBE", "Z+ c #EAEAEA", "`+ c #5FAC33", " @ c #9ADA7E", ".@ c #4FBE1D", "+@ c #43AF0E", "@@ c #43AE0E", "#@ c #46AD12", "$@ c #8ACB69", "%@ c #6AB341", "&@ c #75AB55", "*@ c #BDBDBD", "=@ c #BCBCBC", "-@ c #BBBBBB", ";@ c #BABABA", ">@ c #CACACA", ",@ c #E5E5E5", "'@ c #E9E9E9", ")@ c #7D7D7D", "!@ c #619E3C", "~@ c #72BE4A", "{@ c #8BD16A", "]@ c #43B50F", "^@ c #42B20D", "/@ c #43AC0E", "(@ c #43AB0E", "_@ c #71BE49", ":@ c #7CBF57", "<@ c #58A22B", "[@ c #B6BAB3", "}@ c #B8B8B8", "|@ c #B7B7B7", "1@ c #D6D6D6", "2@ c #E7E7E7", "3@ c #E6E6E6", "4@ c #91978D", "5@ c #59A72A", "6@ c #82C85F", "7@ c #71C448", "8@ c #44A90F", "9@ c #59B229", "0@ c #8BC86B", "a@ c #56A527", "b@ c #A1B396", "c@ c #B6B6B6", "d@ c #B5B5B5", "e@ c #B4B4B4", "f@ c #B3B3B3", "g@ c #CECECE", "h@ c #7C7C7C", "i@ c #CDE3C0", "j@ c #59A72B", "k@ c #8ECD6E", "l@ c #58B529", "m@ c #44A80F", "n@ c #49A816", "o@ c #87C565", "p@ c #64AC38", "q@ c #81AA67", "r@ c #B2B2B2", "s@ c #B1B1B1", "t@ c #B0B0B0", "u@ c #AFAFAF", "v@ c #DDDDDD", "w@ c #E3E3E3", "x@ c #313131", "y@ c #2F2F2F", "z@ c #424242", "A@ c #95C378", "B@ c #65B03A", "C@ c #8AC968", "D@ c #49AA16", "E@ c #44A60F", "F@ c #44A50F", "G@ c #74BA4D", "H@ c #75B74E", "I@ c #5FA235", "J@ c #9E9F9D", "K@ c #989898", "L@ c #919191", "M@ c #939393", "N@ c #A0A0A0", "O@ c #ABABAB", "P@ c #ACACAC", "Q@ c #D3D3D3", "R@ c #E2E2E2", "S@ c #E1E1E1", "T@ c #292929", "U@ c #4D4D4D", "V@ c #ECEEEB", "W@ c #65AC3B", "X@ c #72B84A", "Y@ c #77BE51", "Z@ c #44A310", "`@ c #5DAE30", " # c #86C164", ".# c #54A124", "+# c #848F7E", "@# c #8D8D8D", "## c #8E8E8E", "$# c #A6A6A6", "%# c #A7A7A7", "&# c #CDCDCD", "*# c #E0E0E0", "=# c #4C4C4C", "-# c #7A7A7A", ";# c #D6E3CE", "># c #56A526", ",# c #82C05E", "'# c #6AB340", ")# c #8AC269", "!# c #5FA733", "~# c #749462", "{# c #DEDEDE", "]# c #ACCE97", "^# c #5FA932", "/# c #90C572", "(# c #71B14A", "_# c #5F9A3D", ":# c #DCDCDC", "<# c #DBDBDB", "[# c #77B252", "}# c #56A426", "|# c #539E25", "1# c #898E85", "2# c #D9D9D9", "3# c #4B4B4B", "4# c #797979", "5# c #D8DED4", "6# c #7C926F", "7# c #D5D5D5", "8# c #787878", "9# c #949494", "0# c #D2D2D2", "a# c #D1D1D1", "b# c #979797", "c# c #A5A5A5", "d# c #C9C9C9", "e# c #9F9F9F", "f# c #CFCFCF", "g# c #9D9D9D", "h# c #CCCCCC", "i# c #A3A3A3", "j# c #A8A8A8", "k# c #C7C7C7", "l# c #CBCBCB", "m# c #C5C5C5", "n# c #C1C1C1", "o# c #AEAEAE", "p# c #888888", "q# c #959595", "r# c #303030", "s# c #2D2D2D", "t# c #353535", "u# c #434343", "v# c #898989", "w# c #8A8A8A", "x# c #8C8C8C", " . + @ # $ % & ", " * = - ; > , ' ) ! ~ { ", " ] ^ / ( _ : < [ } | } 1 2 3 4 ", " 5 6 7 8 9 0 a b c d e f g h i j ", " k l m n o p p p q r s t u u v w x y ", " z A B C C C C C C D E F G H I J K L M ", "N N O P P P P P P P Q R S T U V W X Y Z ` ...+. ... ", "N @.#.#.#.#.#.#.#.#.$.%.&.*.=.-.;.>.,.'.). !.~.{.].^./.(._.:.:.<.[.[. ", "}.|.1.1.1.1.1.1.1.1.2. 3.4.>.5.6.7.8.9.j +...0.a.b.c.^.d.c./.e.f.f.f.g.g.[. ", " h. i.j.k.7.l.m.n.o.p. !. .q.r.s.c.t.d.u.v.v.c.e.f.w.x.y.z.A.[. ", " B.C.D.m.n.E.F.G.H.I. !.J.K.L.t.c.t.d.u.u.v.v.v.M.c.f.f.N.y.O.P.Q.[. ", " R.S.E.F.T.U.V.W.X.Y.Z.c.c.`.d.u.u.u.v.v.M.b.b.b.^.f.g.y.y. +.+Q.[. ", " ++@+T.#+$+%+&+*+=+-+`.s.s.u.u.v.v.v.M.b.b.b.;+Z.^.g.g.>+>+.+.+Q.[. ", " N N ,+,+'+N )+!+$+%+&+~+{+]+^+N /+/+(+N N ;+M.b.b.;+Z.Z.Z._+t.g.g.>+>+.+.+:+[. ", " z <+[+}+|+1+2+&+~+{+3+4+5+6+7+8+9+0+a+b+c+L.;+Z.Z._+_+d+d+t.A.A.>+>+.+.+:+[. ", " 4 e+f+g+%+&+~+{+3+4+h+i+j+k+l+m+n+o+p+q+r+s+t+_+d+d+].].u+t.A.Q.v+>+.+.+w+[. ", " x+y+z+~+{+A+4+h+i+j+k+l+B+C+D+E+F+G+H+H+I+J+L.].].u+K+L.`.Q.Q.L+M+.+.+N+[. ", " O+P+Q+4+h+i+j+k+l+B+C+R+S+T+U+V+W+W+X+Y+X+a.u+K+L.L.Z+d.Q.:+:+w+w+N+N+[. ", " `+ @.@j+k+l+B+C++@@@#@$@%@&@*@*@=@-@-@;@>@,@L.Z+'@t+s.:+:+w+N+N+N+)@[. ", " !@~@{@]@^@C++@@@/@(@_@:@<@[@;@q.}@}@|@|@|@1@'@t+2@3@u.:+w+N+N+N+)@)@[. ", " 4@5@6@7@+@@@/@(@8@9@0@a@b@|@c@c@d@e@e@f@f@g@3@3@,@,@v.w+N+N+N+)@)@h@[. ", " [.i@j@k@l@(@8@m@n@o@p@q@e@f@f@r@r@s@t@t@u@-@v@r.w@w@M.N+N+x@y@x@z@h@[. ", " [.t.A@B@C@D@E@F@G@H@I@J@K@<.L@M@+.N@O@P@O@t@Q@w@R@S@;+N+)@T@T@x.U@w.[. ", " [.`.V@W@X@Y@Z@`@ #.#+#@#@#@#@#@#@#@###+.$#%#&#S@*#c+Z.)@)@>+>+U@=#-#[. ", " [.d.d+;#>#,#'#)#!#~#@#@#@#@#@#@#@#@#@#@###!.K.c+{#v@d+)@h@>+>+=#=#-#[. ", " [.s.].u+]#^#/#(#_#@#@#@#@#@#@#@#@#@#@#@#@#@#X+v@:#<#].h@h@>+>+=#=#-#[. ", " [.u.K+K+t+[#}#|#1#@#@#@#@#@#@#@#@#@#@#@#@#@#}@s+a.2#K+h@h@>+>+=#3#4#[. ", " [.v.L.2@r.5#N 6#@#@#@#@#@#@#@#@#@#@#@#@#@#@#;@7#1@J+Z+h@w.>+>+3#3#4#[. ", " [.M.2@r.w@R@*@@#@#@#@#@#@#@#@#@#@#@#@#@#@#@#-@Y.Q@Y.t+w.-#>+>+3#3#8#[. ", " [.;+r.w@R@S@X+@#@#@#@#@#_.9#....K@@#@#@#@#@#*@Q@0#a#3@-#-#>+>+x.x.8#[. ", " [._+w@R@S@Q@f@9#@###L@..f@a.;+b. .@#@#@#@#9#I+0#a#{.,@-#4#>+>+x.x.8#[. ", " [.d+R@S@Y.N@>@O@b#c#d#K+_+d+d+>@M@@#@#@#@#e#>@a#{.f#r.4#4#>+>+x.x.8#[. ", " [.].S@*#u@1@t+Z+R@K+3@,@u+r.J+!.@#@#@#@#@#d@f#{.f#f#R@4#8#>+>+x.x.8#[. ", " [.u+*#c+g#K+d#0#s+v@2@t+a.0#e###@#@#@#@#:.*@{.f#g@g@S@8#8#>+>+x.x.8#[. ", " [.K+c+{# .3@&#J+R@K+c+a#d#J.:.@#@#@#@#@#%#d#f#g@&#&#c+8#8#>+>+x.x.8#[. ", " [.Z+{#v@$#2#c+2@Z+J+>@-@J._.@#@#@#@#@#_.=@f#g@&#&#h#{#8#8#>+>+x.x.8#[. ", " [.'@v@:#X+;@_+R@{.I+O@..##@#@#@#@#@#@#e@h#g@&#h#h#h#v@8#8#>+>+x.x.8#[. ", " [.t+:#:#2#i#X+>@s@e#~.@#@#@#@#@#@#@#t@r+g@&#h#h#h#h#:#8#8#>+>+x.x.8#[. ", " [.2@*#v@a.{.%# .j#k#l#}@K@@#@#@#K@}@K.g@&#h#h#h#h#h#<#8#8#>+>+x.x.8#[. ", " [.t@m#7#S@*#v@<#J+7#Y.a#I+=@;@=@n#h#g@&#h#h#h#h#h#h#a.8#8#>+>+x.x.8#[. ", " M@+.+.$#-@h#a.{#a.J+Y.a#{.f#g@g@&#h#h#h#h#h#h#h#a.8#8#>+>+x.x.8#[. ", " g.<.b#J.o#I+{.a.s+Y.a#g@h#h#h#h#h#h#h#h#2#8#8#>+>+x.x.8#[. ", " p#q#+.c#|@K.Y.1@Q@a#g@h#h#h#h#s+8#8#r#s#t#u#8#[. ", " w+<.[.e#t@X+@Y.a#f#J+8#8#8#8#8#8#8#[. ", " _.b#..j#q.k#Q@4#w+g.v#w#x#:.[. ", " ##K@b#K@b#[.M@ ", " ", " "}; tqsl-2.0/apps/right.xpm0000664000076400007640000000120512231073120015141 0ustar rmurphyrmurphy/* XPM */ static const char *right_xpm[]={ "10 10 30 1", "a c None", "g c #000000", "v c #030303", "d c #040404", "s c #090909", "h c #0c0c0c", "p c #141314", "k c #161516", "n c #201f20", "y c #363536", "w c #4c4a4c", "e c #585758", "t c #616061", "i c #686668", "q c #777577", "l c #787678", "o c #898789", "B c #8e8c8e", "c c #9d9b9d", "z c #a19fa1", "A c #aba9ab", "# c #adaaad", "x c #b0aeb0", "r c #b2afb2", ". c #b3b0b3", "b c #b5b2b5", "f c #b7b4b7", "u c #bcb9bc", "j c #bcbabc", "m c #c2bfc2", ".#aaaaaaaa", "cdefaaaaaa", "cgghijaaaa", "cggggklmaa", "cggggggnoa", "cggggggpqr", "cggggstuaa", "cggvwxaaaa", "cgyzaaaaaa", "ABaaaaaaaa"}; tqsl-2.0/apps/replaced.xpm0000664000076400007640000000165012231073120015607 0ustar rmurphyrmurphy/* XPM */ static const char * replaced_xpm[] = { "16 16 37 1", " c None", ". c #494949", "+ c #3E3E3E", "@ c #2E2E2E", "# c #1B1B1B", "$ c #0B0B0B", "% c #6C6C6C", "& c #6F6F6F", "* c #CECECE", "= c #949494", "- c #6D6D6D", "; c #CACACA", "> c #F7F7F8", ", c #F4F4F5", "' c #969696", ") c #929292", "! c #A6A6A6", "~ c #A7A7A7", "{ c #F0F0F1", "] c #EFEFF0", "^ c #EEEEEF", "/ c #BFBFBF", "( c #A4A4A4", "_ c #EEEEEE", ": c #EAEAEB", "< c #EDEDEE", "[ c #CFCFCF", "} c #787878", "| c #E5E5E5", "1 c #E8E8E9", "2 c #E9E9EA", "3 c #DDDDDE", "4 c #AEAEAE", "5 c #D6D6D6", "6 c #DCDCDC", "7 c #F1F1F1", "8 c #FFFFFF", "8888888888888888", "888..88888888888", "88+++88888888888", "88@8@88888888888", "88####8888888888", "8$$88$8888888888", "8888888888888888", "888%888888888888", "88&*=%8-88888888", "8%;>,')!88888888", "88~,{]^/%888...8", "88%(_:<[%888+8+8", "888}|123%888@@@8", "888456|7%888#8##", "8888%%%%8888$$$8", "8888888888888888"}; tqsl-2.0/apps/quick0000775000076400007640000002402212231073120014342 0ustar rmurphyrmurphyQUICK-START GUIDE for TQSL version 2.0 ====================================== TQSL is an application used to digitally sign and upload QSOs to the ARRL's Logbook of the World (LoTW) online service, and to manage the Callsign Certificates used when digitally signing. TQSL accepts QSOs in a log file whose format is either ADIF or Cabrillo, which many logging applications can create. To digitally sign the QSOs in a log file, TQSL requires you to present a Callsign Certificate issued to you by the ARRL, and requires you to specify the location from which you operated when making every QSO in that log file. To make this easy, TQSL lets you define and name a Station Location that specifies your Callsign Certificate and operating location. Documentation for TQSL is available via its Help menu's "Display Documentation" command; on OS X, documentation is available via the Help menu's "Contents" command). The information in this Quick-Start Guide is a subset extracted from the documentation. TQSL can be installed and executed on Windows, Mac OS X, and Linux. Installation ============ To install TQSL on Windows, download and execute the .msi file to start the TQSL installer. The installer makes TQSL accessible via the Windows Start/Programs/TrustedQSL menu unless you direct it to use a different menu. The installer also provides the option of creating a Desktop shortcut for TQSL. To install on Mac OS X, download and open the disk image file (.dmg). and drag the TrustedQSL folder to your Applications folder. If you are replacing an existing installation of TQSL, you should choose "Replace All" when prompted. On a Mac OS X 10.8 or later system, you may need to grant permission for the TQSL application to run: right-click or control-click on the application icon, and then choose "Open"; when an "Are you sure" dialog box appears, click the "Open" button to permit TQSL to start. You will only need to do this when installing a TQSL release. To install on Linux, consult the instructions in the INSTALL document included with the source code. If you're updating an existing TQSL installation ================================================ Note that this version of TQSL includes the Callsign Certificate management functionality previously provided by TQSLCert; TQSLCert is no longer required, and has been removed from your computer. To request, load, save, renew, or delete a Callsign Certificate, use the "Callsign Certificates" tab on TQSL's main window and its "Callsign Certificate" menu commands. TQSLCert was by default configured to hide both "replaced" and "expired" certificates. TQSL displays all Callsign Certificates on its main window's "Callsign Certificates" tab: - "replaced" Certificates are denoted by an A=>B icon - "expired" Certificates are denoted by an alarm clock icon. You should delete each "replaced" or "expired" Callsign Certificate by clicking its entry on the "Callsign Certificates" tab, and then selecting the "Callsign Certificate" menu's "Delete Callsign Certificate" command. If you're installing TQSL for the first time ============================================ 1) Request a Callsign Certificate When you start TQSL, you'll be informed that you have no Callsign Certificates and be asked if you want to request one. Choose "Yes", and proceed through the sequence of "Request a new Callsign Certificate" dialogs: a) When prompted to specify a callsign, use your present callsign without any portable identifiers. b) The "QSO begin date" is the date of the earliest QSO you'll submit to LoTW using the callsign you've specified; normally, this is date-of-issue for your license. Leave the "QSO end date" blank. c) For US callsigns, your mailing address must match the address in the FCC's database. If your address is now different than what you last filed with the FCC, you must register your new address with the FCC. d) You will be prompted to specify a password. If you're using a shared computer, you should protect your Callsign Certificate by entering the same password in both password textboxes; you'll be asked to provide this password each time you direct TQSL to digitally sign a log file, so be sure not to forget it! If you control access to the computer you're using, you can leave both password textboxes empty, thereby avoiding the need to provide a password each time you direct TQSL to digitally sign a log file. e) When given the option to digitally sign the Callsign Certificate request, choose "unsigned". f) If your computer is connected to the internet, TQSL will offer to submit your Callsign Certificate Request; choose "Yes". If you chose "No", you'll be prompted to save a .tq5 file, which you should then attach to an email message to lotw-logs@arrl.org, or upload via the Web (https://www.arrl.org/lotw/). g) If you are a US licensee, you will receive a post card in the mail with further instructions; the post card will be sent to your address in the FCC's database, so make sure that's correct! If you are a non-US licensee, you must submit proof of license and identity to receive your Callsign Certificate. See http://www.arrl.org/lotw/ for details. NOTE! Do not delete the Callsign Certificate Request (the red-lined "pending" icon) from TQSL's "Callsign Certificates" tab after the Request has been conveyed. Each Certificate Request is unique and must match the Callsign Certificate that you will receive from the ARRL. If you direct TQSL to delete the Certificate Request, you will not be able to load the Callsign Certificate the ARRL sends you in response. 2) Accept the Callsign Certificate Your Callsign Certificate will arrive as a file with a .TQ6 suffix attached to an email message sent to the email address that you specified in the "Request a new Callsign Certificate" dialog. You must accept the Callsign Certificate using the same computer on which you generated the Callsign Certificate Request in step 1 above. Attempting to accept a Callsign Certificate using a different computer will fail. Double-click the email attachment in the received email message to launch TQSL and direct it to load the .TQ6 file. If double-clicking the attachment does not start TQSL, then save the attached .tq6 file to a folder, start TQSL, and use its Callsign Certificate menu's "Load Callsign Certificate From File" command to load your Callsign Certificate. This certificate will appear on TQSL's "Callsign Certificates" tab with a yellow medal icon indicating that it is valid. 3) Backup the Callsign Certificate This step is strongly recommended: if you fail to make a backup and later lose your Callsign Certificate to a hard-drive crash or operating system failure, your certificate will not be recoverable. Select the File menu's "Backup Station Locations, Certificates, and Preferences..." command, and create a backup on a flash (thumb) drive, an external hard drive, or on a cloud storage service like DropBox, Google Drive, or Microsoft Sky Drive. 4) Request Additional Callsign Certificate Logbook of the World treats a callsign with a portable identifier (e.g. NU1AW/4 or KP2/W1AW) as distinct from its home callsign. To submit QSOs made with a portable callsign, you must obtain a Callsign Certificate for that portable callsign. After you have received your Callsign Certificate for your home callsign, repeat steps 1, 2, and 3 above, but - in step 1a specify your portable callsign - in step 1e digitally sign the request with the Callsign Certificate for your present callsign 5) Create a Log File TQSL accepts log files saved from logging applications in either ADIF or Cabrillo format. If you're not yet using a logging application and want to create a log file containing a few QSOs, start TQSL, select the "Log Operations" tab, and click the "Create an ADIF file for signing and uploading" button. Because new modes may not yet be specified in ADIF, and because LoTW may not accept all modes specified in ADIF, TQSL enables you to "map" a new mode to a mode or mode group recognized by LoTW; this most often takes the form of mapping a new digital mode to the DATA mode group. Previous versions of TQSL would allow you to map modes accepted by LoTW. This version of TQSL will refuse to map a mode that is recognized by LoTW. Any existing mappings of modes recognized by LoTW will be automatically removed on startup. 6) Define a Station Location Select TQSL's "Station Locations" tab and click the "Create a new Station Location" button. A sequence of "Add Station Location" dialogs will prompt you for the location of the station used to make all of the QSOs in the log file you'll be submitting, and will enable you to specify a name that identifies the Station Location you've defined, e.g., "Home" or "Portable in EM29". 7) Digitally Sign and Submit a Log File In TQSL, select the "Log Operations" tab and click the "Sign a log and upload it automatically to LoTW" button. In the "Select File to Sign" dialog, specify either ADIF (.adi) or Cabrillo (.cbr or .log) format, navigate to the folder containing your log file, select your log file, and click the "Open" button. In the "Select Station Location" dialog, select the Station Location from which you were operating when you made all of the QSOs in the log file, and click the "OK" button; TQSL will digitally sign your QSOs and submit them to LoTW via the internet. When submitting log files in Cabrillo format, previous versions of TQSL submitted FM and PH modes as PHONE. TQSL now submits FM mode as FM, and PH mode as SSB. 8) Visit the Logbook of the World Web site at https://www.arrl.org/lotw/ to view your submitted QSOs and confirmed QSOs, and to apply for award credits. Using TQSL, you can navigate there by clicking the "Log Operations" tab's "Log in to the Logbook of the World Site" button. 9) For assistance or to report defects, send email to lotw-help@arrl.org. tqsl-2.0/apps/qsodatadialog.h0000664000076400007640000000423312231073120016267 0ustar rmurphyrmurphy/*************************************************************************** qsodatadialog.h - description ------------------- begin : Sat Dec 7 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #ifndef QSODATADIALOG_H #define QSODATADIALOG_H #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "tqsllib.h" #include #include #include #include /** Display and edit QSO data * *@author Jon Bloom */ class QSORecord { public: QSORecord() { _mode = wxT("CW"); _band = wxT("160M"); _rxband = wxT(""); } wxString _call, _freq, _rxfreq; wxString _mode, _band, _rxband; wxString _propmode, _satellite; tQSL_Date _date; tQSL_Time _time; }; typedef std::vector QSORecordList; class QSODataDialog : public wxDialog { public: QSODataDialog(wxWindow *parent, wxHtmlHelpController *help, QSORecordList *reclist = 0, wxWindowID id = -1, const wxString& title = wxT("QSO Data")); ~QSODataDialog(); wxString GetMode() const; bool SetMode(const wxString&); QSORecord rec; virtual bool TransferDataToWindow(); virtual bool TransferDataFromWindow(); private: void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); void OnHelp(wxCommandEvent&); void OnRecUp(wxCommandEvent&); void OnRecDown(wxCommandEvent&); void OnRecBottom(wxCommandEvent&); void OnRecTop(wxCommandEvent&); void OnRecNew(wxCommandEvent&); void OnRecDelete(wxCommandEvent&); void SetRecno(int); void UpdateControls(); wxTextCtrl *_recno_ctrl; wxTextCtrl *_call_ctrl; wxStaticText *_recno_label_ctrl; wxBitmapButton *_recdown_ctrl, *_recup_ctrl, *_recbottom_ctrl, *_rectop_ctrl; QSORecordList *_reclist; int _mode, _band, _rxband, _propmode, _satellite; int _recno; DECLARE_EVENT_TABLE() bool _isend; wxHtmlHelpController *_help; }; #endif tqsl-2.0/apps/qsodatadialog.cpp0000664000076400007640000004563012231073120016630 0ustar rmurphyrmurphy/*************************************************************************** qsodatadialog.cpp - description ------------------- begin : Sat Dec 7 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id: qsodatadialog.cpp,v 1.7 2013/03/01 12:59:37 k1mu Exp $ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "qsodatadialog.h" #include #include #include #include "tqslvalidator.h" #include "wx/valgen.h" #include "wx/spinctrl.h" #include "wx/statline.h" #include "tqsllib.h" #include "tqslexcept.h" #include "tqsltrace.h" using namespace std; #define TQSL_ID_LOW 6000 #ifdef __WIN32__ #define TEXT_HEIGHT 24 #define LABEL_HEIGHT 18 #define TEXT_WIDTH 8 #define TEXT_POINTS 10 #define VSEP 3 #define GEOM1 4 #elif defined(__APPLE__) #define TEXT_HEIGHT 24 #define LABEL_HEIGHT 18 #define TEXT_WIDTH 8 #define TEXT_POINTS 10 #define VSEP 3 #define GEOM1 4 #else #define TEXT_HEIGHT 18 #define LABEL_HEIGHT TEXT_HEIGHT #define TEXT_WIDTH 8 #define TEXT_POINTS 12 #define VSEP 4 #define GEOM1 6 #endif #undef TEXT_HEIGHT #define TEXT_HEIGHT -1 #define SKIP_HEIGHT (TEXT_HEIGHT+VSEP) #define QD_CALL TQSL_ID_LOW #define QD_DATE TQSL_ID_LOW+1 #define QD_TIME TQSL_ID_LOW+2 #define QD_MODE TQSL_ID_LOW+3 #define QD_BAND TQSL_ID_LOW+4 #define QD_FREQ TQSL_ID_LOW+5 #define QD_OK TQSL_ID_LOW+6 #define QD_CANCEL TQSL_ID_LOW+7 #define QD_RECNO TQSL_ID_LOW+8 #define QD_RECDOWN TQSL_ID_LOW+9 #define QD_RECUP TQSL_ID_LOW+10 #define QD_RECBOTTOM TQSL_ID_LOW+11 #define QD_RECTOP TQSL_ID_LOW+12 #define QD_RECNEW TQSL_ID_LOW+13 #define QD_RECDELETE TQSL_ID_LOW+14 #define QD_RECNOLABEL TQSL_ID_LOW+15 #define QD_HELP TQSL_ID_LOW+16 #define QD_PROPMODE TQSL_ID_LOW+17 #define QD_SATELLITE TQSL_ID_LOW+18 #define QD_RXBAND TQSL_ID_LOW+19 #define QD_RXFREQ TQSL_ID_LOW+20 static void set_font(wxWindow *w, wxFont& font) { #ifndef __WIN32__ w->SetFont(font); #endif } // Images for buttons. #include "left.xpm" #include "right.xpm" #include "bottom.xpm" #include "top.xpm" class choice { public: choice(const wxString& _value, const wxString& _display = wxT(""), int _low = 0, int _high = 0) { value = _value; display = (_display == wxT("")) ? value : _display; low = _low; high = _high; } wxString value, display; int low, high; bool operator ==(const choice& other) { return other.value == value; } }; class valid_list : public std::vector { public: valid_list() {} valid_list(const char **values, int nvalues); wxString *GetChoices() const; }; valid_list::valid_list(const char **values, int nvalues) { while(nvalues--) push_back(choice(wxString(*(values++), wxConvLocal))); } wxString * valid_list::GetChoices() const { wxString *ary = new wxString[size()]; wxString *sit = ary; const_iterator it; for (it = begin(); it != end(); it++) *sit++ = (*it).display; return ary; } static valid_list valid_modes; static valid_list valid_bands; static valid_list valid_rxbands; static valid_list valid_propmodes; static valid_list valid_satellites; static int init_valid_lists() { tqslTrace("init_valid_lists"); if (valid_bands.size() > 0) return 0; if (tqsl_init()) return 1; int count; if (tqsl_getNumMode(&count)) return 1; const char *cp, *cp1; for (int i = 0; i < count; i++) { if (tqsl_getMode(i, &cp, 0)) return 1; valid_modes.push_back(choice(wxString(cp, wxConvLocal))); } valid_rxbands.push_back(choice(wxT(""), wxT("NONE"))); if (tqsl_getNumBand(&count)) return 1; for (int i = 0; i < count; i++) { int low, high, scale; if (tqsl_getBand(i, &cp, &cp1, &low, &high)) return 1; wxString low_s = wxString::Format(wxT("%d"), low); wxString high_s = wxString::Format(wxT("%d"), high); const char *hz; if (!strcmp(cp1, "HF")) { hz = "kHz"; scale = 1; // Config file freqs are in KHz } else { hz = "mHz"; scale = 1000; // Freqs are in MHz for VHF/UHF. } if (low >= 1000) { low_s = wxString::Format(wxT("%g"), low / 1000.0); high_s = wxString::Format(wxT("%g"), high / 1000.0); if (!strcmp(cp1, "HF")) { hz = "MHz"; } else { hz = "GHz"; } if (high == 0) high_s = wxT("UP"); } wxString display = wxString::Format(wxT("%s (%s-%s %s)"), wxString(cp, wxConvLocal).c_str(), low_s.c_str(), high_s.c_str(), wxString(hz, wxConvLocal).c_str()); valid_bands.push_back(choice(wxString(cp, wxConvLocal), display, low*scale, high*scale)); valid_rxbands.push_back(choice(wxString(cp, wxConvLocal), display, low*scale, high*scale)); } valid_propmodes.push_back(choice(wxT(""), wxT("NONE"))); if (tqsl_getNumPropagationMode(&count)) return 1; for (int i = 0; i < count; i++) { if (tqsl_getPropagationMode(i, &cp, &cp1)) return 1; valid_propmodes.push_back(choice(wxString(cp, wxConvLocal), wxString(cp1, wxConvLocal))); } valid_satellites.push_back(choice(wxT(""), wxT("NONE"))); if (tqsl_getNumSatellite(&count)) return 1; for (int i = 0; i < count; i++) { if (tqsl_getSatellite(i, &cp, &cp1, 0, 0)) return 1; valid_satellites.push_back(choice(wxString(cp, wxConvLocal), wxString(cp1, wxConvLocal))); } return 0; } #define LABEL_WIDTH (22*TEXT_WIDTH) BEGIN_EVENT_TABLE(QSODataDialog, wxDialog) EVT_BUTTON(QD_OK, QSODataDialog::OnOk) EVT_BUTTON(QD_CANCEL, QSODataDialog::OnCancel) EVT_BUTTON(QD_HELP, QSODataDialog::OnHelp) EVT_BUTTON(QD_RECDOWN, QSODataDialog::OnRecDown) EVT_BUTTON(QD_RECUP, QSODataDialog::OnRecUp) EVT_BUTTON(QD_RECBOTTOM, QSODataDialog::OnRecBottom) EVT_BUTTON(QD_RECTOP, QSODataDialog::OnRecTop) EVT_BUTTON(QD_RECNEW, QSODataDialog::OnRecNew) EVT_BUTTON(QD_RECDELETE, QSODataDialog::OnRecDelete) END_EVENT_TABLE() QSODataDialog::QSODataDialog(wxWindow *parent, wxHtmlHelpController *help, QSORecordList *reclist, wxWindowID id, const wxString& title) : wxDialog(parent, id, title), _reclist(reclist), _isend(false), _help(help) { tqslTrace("QSODataDialog::QSODataDialog", "parent=0x%lx, reclist=0x%lx, id=0x%lx, %s", (void *)parent, (void *)reclist, (void *) id, _S(title)); wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL); wxFont font = GetFont(); // font.SetPointSize(TEXT_POINTS); set_font(this, font); #define QD_MARGIN 3 if (init_valid_lists()) throw TQSLException(tqsl_getErrorString()); // Call sign wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxStaticText(this, -1, wxT("Call Sign:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); _call_ctrl = new wxTextCtrl (this, QD_CALL, wxT(""), wxDefaultPosition, wxSize(14*TEXT_WIDTH,TEXT_HEIGHT), 0, wxTextValidator(wxFILTER_NONE, &rec._call)); sizer->Add(_call_ctrl, 0, wxALL, QD_MARGIN); topsizer->Add(sizer, 0); // Date sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxStaticText(this, -1, wxT("UTC Date (YYYY-MM-DD):"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxTextCtrl (this, QD_DATE, wxT(""), wxDefaultPosition, wxSize(14*TEXT_WIDTH,TEXT_HEIGHT), 0, TQSLDateValidator(&rec._date)), 0, wxALL, QD_MARGIN); topsizer->Add(sizer, 0); // Time sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxStaticText(this, -1, wxT("UTC Time (HHMM):"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxTextCtrl (this, QD_TIME, wxT(""), wxDefaultPosition, wxSize(14*TEXT_WIDTH,TEXT_HEIGHT), 0, TQSLTimeValidator(&rec._time)), 0, wxALL, QD_MARGIN); topsizer->Add(sizer, 0); // Mode sizer = new wxBoxSizer(wxHORIZONTAL); wxString *choices = valid_modes.GetChoices(); sizer->Add(new wxStaticText(this, -1, wxT("Mode:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxChoice(this, QD_MODE, wxDefaultPosition, wxDefaultSize, valid_modes.size(), choices, 0, wxGenericValidator(&_mode)), 0, wxALL, QD_MARGIN); delete[] choices; topsizer->Add(sizer, 0); // Band sizer = new wxBoxSizer(wxHORIZONTAL); choices = valid_bands.GetChoices(); sizer->Add(new wxStaticText(this, -1, wxT("Band:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxChoice(this, QD_BAND, wxDefaultPosition, wxDefaultSize, valid_bands.size(), choices, 0, wxGenericValidator(&_band)), 0, wxALL, QD_MARGIN); delete[] choices; topsizer->Add(sizer, 0); // RX Band sizer = new wxBoxSizer(wxHORIZONTAL); choices = valid_rxbands.GetChoices(); sizer->Add(new wxStaticText(this, -1, wxT("RX Band:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxChoice(this, QD_BAND, wxDefaultPosition, wxDefaultSize, valid_rxbands.size(), choices, 0, wxGenericValidator(&_rxband)), 0, wxALL, QD_MARGIN); delete[] choices; topsizer->Add(sizer, 0); // Frequency sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxStaticText(this, -1, wxT("Frequency (MHz):"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxTextCtrl (this, QD_FREQ, wxT(""), wxDefaultPosition, wxSize(14*TEXT_WIDTH,TEXT_HEIGHT), 0, wxTextValidator(wxFILTER_NONE, &rec._freq)), 0, wxALL, QD_MARGIN); topsizer->Add(sizer, 0); // RX Frequency sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxStaticText(this, -1, wxT("RX Frequency (MHz):"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxTextCtrl (this, QD_RXFREQ, wxT(""), wxDefaultPosition, wxSize(14*TEXT_WIDTH,TEXT_HEIGHT), 0, wxTextValidator(wxFILTER_NONE, &rec._rxfreq)), 0, wxALL, QD_MARGIN); topsizer->Add(sizer, 0); // Propagation Mode sizer = new wxBoxSizer(wxHORIZONTAL); choices = valid_propmodes.GetChoices(); sizer->Add(new wxStaticText(this, -1, wxT("Propagation Mode:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxChoice(this, QD_PROPMODE, wxDefaultPosition, wxDefaultSize, valid_propmodes.size(), choices, 0, wxGenericValidator(&_propmode)), 0, wxALL, QD_MARGIN); delete[] choices; topsizer->Add(sizer, 0); // Satellite sizer = new wxBoxSizer(wxHORIZONTAL); choices = valid_satellites.GetChoices(); sizer->Add(new wxStaticText(this, -1, wxT("Satellite:"), wxDefaultPosition, wxSize(LABEL_WIDTH,TEXT_HEIGHT), wxALIGN_RIGHT), 0, wxALL, QD_MARGIN); sizer->Add(new wxChoice(this, QD_SATELLITE, wxDefaultPosition, wxDefaultSize, valid_satellites.size(), choices, 0, wxGenericValidator(&_satellite)), 0, wxALL, QD_MARGIN); delete[] choices; topsizer->Add(sizer, 0); if (_reclist != 0) { if (_reclist->empty()) _reclist->push_back(QSORecord()); topsizer->Add(new wxStaticLine(this, -1), 0, wxEXPAND|wxLEFT|wxRIGHT, 10); _recno_label_ctrl = new wxStaticText(this, QD_RECNOLABEL, wxT(""), wxDefaultPosition, wxSize(20*TEXT_WIDTH,TEXT_HEIGHT), wxST_NO_AUTORESIZE|wxALIGN_CENTER); topsizer->Add(_recno_label_ctrl, 0, wxALIGN_CENTER|wxALL, 5); _recno = 1; sizer = new wxBoxSizer(wxHORIZONTAL); _recbottom_ctrl = new wxBitmapButton(this, QD_RECBOTTOM, wxBitmap(bottom_xpm), wxDefaultPosition, wxSize(18, TEXT_HEIGHT)), sizer->Add(_recbottom_ctrl, 0, wxTOP|wxBOTTOM, 5); _recdown_ctrl = new wxBitmapButton(this, QD_RECDOWN, wxBitmap(left_xpm), wxDefaultPosition, wxSize(18, TEXT_HEIGHT)); sizer->Add(_recdown_ctrl, 0, wxTOP|wxBOTTOM, 5); _recno_ctrl = new wxTextCtrl(this, QD_RECNO, wxT("1"), wxDefaultPosition, wxSize(4*TEXT_WIDTH,TEXT_HEIGHT)); _recno_ctrl->Enable(FALSE); sizer->Add(_recno_ctrl, 0, wxALL, 5); _recup_ctrl = new wxBitmapButton(this, QD_RECUP, wxBitmap(right_xpm), wxDefaultPosition, wxSize(18, TEXT_HEIGHT)); sizer->Add(_recup_ctrl, 0, wxTOP|wxBOTTOM, 5); _rectop_ctrl = new wxBitmapButton(this, QD_RECTOP, wxBitmap(top_xpm), wxDefaultPosition, wxSize(18, TEXT_HEIGHT)), sizer->Add(_rectop_ctrl, 0, wxTOP|wxBOTTOM, 5); if (_reclist->size() > 0) rec = *(_reclist->begin()); topsizer->Add(sizer, 0, wxALIGN_CENTER); sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxButton(this, QD_RECNEW, wxT("Add QSO")), 0, wxALL, 5); sizer->Add(new wxButton(this, QD_RECDELETE, wxT("Delete")), 0, wxALL, 5); topsizer->Add(sizer, 0, wxALIGN_CENTER); } topsizer->Add(new wxStaticLine(this, -1), 0, wxEXPAND|wxLEFT|wxRIGHT, 10); sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(new wxButton(this, QD_HELP, wxT("Help")), 0, wxALL, 10); sizer->Add(new wxButton(this, QD_CANCEL, wxT("Cancel")), 0, wxALL, 10); sizer->Add(new wxButton(this, QD_OK, wxT("Ok")), 0, wxALL, 10); topsizer->Add(sizer, 0, wxALIGN_CENTER); UpdateControls(); SetAutoLayout(TRUE); SetSizer(topsizer); topsizer->Fit(this); topsizer->SetSizeHints(this); CentreOnParent(); } QSODataDialog::~QSODataDialog(){ } bool QSODataDialog::TransferDataFromWindow() { tqslTrace("QSODataDialog::TransferDataFromWindow"); rec._call.Trim(FALSE).Trim(TRUE); if (!wxDialog::TransferDataFromWindow()) return false; if (_mode < 0 || _mode >= (int)valid_modes.size()) return false; rec._mode = valid_modes[_mode].value; if (_band < 0 || _band >= (int)valid_bands.size()) return false; rec._band = valid_bands[_band].value; rec._rxband = valid_rxbands[_rxband].value; rec._freq.Trim(FALSE).Trim(TRUE); rec._rxfreq.Trim(FALSE).Trim(TRUE); rec._propmode = valid_propmodes[_propmode].value; rec._satellite = valid_satellites[_satellite].value; double freq; if (!rec._freq.IsEmpty()) { if (!rec._freq.ToDouble(&freq)) { wxMessageBox(wxT("QSO Frequency is invalid"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } freq = freq * 1000.0; // Freq is is MHz but the limits are in KHz if (freq < valid_bands[_band].low || (valid_bands[_band].high > 0 && freq > valid_bands[_band].high)) { wxMessageBox(wxT("QSO Frequency is out of range for the selected band"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } } if (!rec._rxfreq.IsEmpty()) { if (!rec._rxfreq.ToDouble(&freq)) { wxMessageBox(wxT("QSO RX Frequency is invalid"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } freq = freq * 1000.0; // Freq is is MHz but the limits are in KHz if (freq < valid_rxbands[_rxband].low || (valid_rxbands[_rxband].high > 0 && freq > valid_rxbands[_rxband].high)) { wxMessageBox(wxT("QSO RX Frequency is out of range for the selected band"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } } if (!_isend && rec._call == wxT("")) { wxMessageBox(wxT("Call Sign cannot be empty"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } if (rec._propmode == wxT("SAT") && rec._satellite == wxT("")) { wxMessageBox(wxT("'Satellite' propagation mode selected, so\na a Satellite must be chosen"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } if (rec._propmode != wxT("SAT") && rec._satellite != wxT("")) { wxMessageBox(wxT("Satellite choice requires that\nPropagation Mode be 'Satellite'"), wxT("QSO Data Error"), wxOK | wxICON_EXCLAMATION, this); return false; } if (_reclist != 0) (*_reclist)[_recno-1] = rec; return true; } bool QSODataDialog::TransferDataToWindow() { tqslTrace("QSODataDialog::TransferDataToWindow"); valid_list::iterator it; if ((it = find(valid_modes.begin(), valid_modes.end(), rec._mode.Upper())) != valid_modes.end()) _mode = distance(valid_modes.begin(), it); else wxLogWarning(wxT("QSO Data: Invalid Mode ignored - %s"), (const char*) rec._mode.Upper().mb_str()); if ((it = find(valid_bands.begin(), valid_bands.end(), rec._band.Upper())) != valid_bands.end()) _band = distance(valid_bands.begin(), it); if ((it = find(valid_rxbands.begin(), valid_rxbands.end(), rec._rxband.Upper())) != valid_rxbands.end()) _rxband = distance(valid_rxbands.begin(), it); if ((it = find(valid_propmodes.begin(), valid_propmodes.end(), rec._propmode.Upper())) != valid_propmodes.end()) _propmode = distance(valid_propmodes.begin(), it); if ((it = find(valid_satellites.begin(), valid_satellites.end(), rec._satellite.Upper())) != valid_satellites.end()) _satellite = distance(valid_satellites.begin(), it); return wxDialog::TransferDataToWindow(); } void QSODataDialog::OnOk(wxCommandEvent&) { tqslTrace("QSODataDialog::OnOk"); _isend = true; TransferDataFromWindow(); _isend = false; if (rec._call == wxT("") && _recno == (int)_reclist->size()) { _reclist->erase(_reclist->begin() + _recno - 1); EndModal(wxID_OK); } else if (Validate() && TransferDataFromWindow()) EndModal(wxID_OK); } void QSODataDialog::OnCancel(wxCommandEvent&) { tqslTrace("QSODataDialog::OnCancel"); EndModal(wxID_CANCEL); } void QSODataDialog::OnHelp(wxCommandEvent&) { tqslTrace("QSODataDialog::OnHelp"); if (_help) _help->Display(wxT("qsodata.htm")); } void QSODataDialog::SetRecno(int new_recno) { tqslTrace("QSODataDialog::SetRecno", "new_recno=%d", new_recno); if (_reclist == NULL || new_recno < 1) return; if (TransferDataFromWindow()) { // (*_reclist)[_recno-1] = rec; if (_reclist && new_recno > (int)_reclist->size()) { new_recno = _reclist->size() + 1; QSORecord newrec; // Copy QSO fields from current record if (_recno > 0) { newrec = (*_reclist)[_recno-1]; newrec._call = wxT(""); } _reclist->push_back(newrec); } _recno = new_recno; if (_reclist) rec = (*_reclist)[_recno-1]; TransferDataToWindow(); UpdateControls(); _call_ctrl->SetFocus(); } } void QSODataDialog::OnRecDown(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecDown"); SetRecno(_recno - 1); } void QSODataDialog::OnRecUp(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecUp"); SetRecno(_recno + 1); } void QSODataDialog::OnRecBottom(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecBottom"); SetRecno(1); } void QSODataDialog::OnRecTop(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecTop"); if (_reclist == 0) return; SetRecno(_reclist->size()); } void QSODataDialog::OnRecNew(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecNew"); if (_reclist == 0) return; SetRecno(_reclist->size()+1); } void QSODataDialog::OnRecDelete(wxCommandEvent&) { tqslTrace("QSODataDialog::OnRecDelete"); if (_reclist == 0) return; _reclist->erase(_reclist->begin() + _recno - 1); if (_reclist->empty()) _reclist->push_back(QSORecord()); if (_recno > (int)_reclist->size()) _recno = _reclist->size(); rec = (*_reclist)[_recno-1]; TransferDataToWindow(); UpdateControls(); } void QSODataDialog::UpdateControls() { tqslTrace("QSODataDialog::UpdateControls"); if (_reclist == 0) return; _recdown_ctrl->Enable(_recno > 1); _recbottom_ctrl->Enable(_recno > 1); _recup_ctrl->Enable(_recno < (int)_reclist->size()); _rectop_ctrl->Enable(_recno < (int)_reclist->size()); _recno_ctrl->SetValue(wxString::Format(wxT("%d"), _recno)); _recno_label_ctrl->SetLabel(wxString::Format(wxT("%d QSO Record%hs"), (int)_reclist->size(), (_reclist->size() == 1) ? "" : "s")); } tqsl-2.0/apps/properties_dis.xpm0000664000076400007640000001706412231073120017071 0ustar rmurphyrmurphy/* XPM */ static const char * properties_dis_xpm[] = { "48 48 179 2", " c None", ". c #ACACAC", "+ c #AAAAAA", "@ c #AFAFAF", "# c #B2B2B2", "$ c #B3B3B3", "% c #B0B0B0", "& c #ADADAD", "* c #9C9C9C", "= c #989898", "- c #A2A2A2", "; c #BFBFBF", "> c #C7C7C7", ", c #CECECE", "' c #D0D0D0", ") c #D1D1D1", "! c #CFCFCF", "~ c #C8C8C8", "{ c #C0C0C0", "] c #B1B1B1", "^ c #A3A3A3", "/ c #9A9A9A", "( c #9E9E9E", "_ c #8B8B8B", ": c #8D8D8D", "< c #9D9D9D", "[ c #B9B9B9", "} c #CBCBCB", "| c #BBBBBB", "1 c #B8B8B8", "2 c #B5B5B5", "3 c #9F9F9F", "4 c #909090", "5 c #858585", "6 c #7F7F7F", "7 c #999999", "8 c #C5C5C5", "9 c #ABABAB", "0 c #A8A8A8", "a c #B6B6B6", "b c #828282", "c c #868686", "d c #767676", "e c #7E7E7E", "f c #BCBCBC", "g c #A7A7A7", "h c #A5A5A5", "i c #BDBDBD", "j c #818181", "k c #787878", "l c #686868", "m c #7D7D7D", "n c #B4B4B4", "o c #6B6B6B", "p c #5E5E5E", "q c #A0A0A0", "r c #838383", "s c #616161", "t c #535353", "u c #727272", "v c #AEAEAE", "w c #A1A1A1", "x c #565656", "y c #494949", "z c #ECECEC", "A c #F9F9F9", "B c #EDEDED", "C c #646464", "D c #4C4C4C", "E c #3F3F3F", "F c #919191", "G c #959595", "H c #E7E7E7", "I c #FFFFFF", "J c #E8E8E8", "K c #949494", "L c #9B9B9B", "M c #4E4E4E", "N c #414141", "O c #3C3C3C", "P c #696969", "Q c #929292", "R c #F4F4F4", "S c #F6F6F6", "T c #747474", "U c #353535", "V c #4B4B4B", "W c #8A8A8A", "X c #8F8F8F", "Y c #8E8E8E", "Z c #F1F1F1", "` c #F3F3F3", " . c #373737", ".. c #363636", "+. c #6A6A6A", "@. c #8C8C8C", "#. c #D6D6D6", "$. c #D8D8D8", "%. c #939393", "&. c #797979", "*. c #333333", "=. c #3D3D3D", "-. c #898989", ";. c #D2D2D2", ">. c #EBEBEB", ",. c #D3D3D3", "'. c #404040", "). c #343434", "!. c #575757", "~. c #888888", "{. c #878787", "]. c #383838", "^. c #6F6F6F", "/. c #808080", "(. c #7B7B7B", "_. c #3A3A3A", ":. c #737373", "<. c #BABABA", "[. c #444444", "}. c #303030", "|. c #454545", "1. c #757575", "2. c #7C7C7C", "3. c #FBFBFB", "4. c #E9E9E9", "5. c #505050", "6. c #313131", "7. c #4A4A4A", "8. c #7A7A7A", "9. c #595959", "0. c #2F2F2F", "a. c #4D4D4D", "b. c #777777", "c. c #717171", "d. c #C3C3C3", "e. c #5F5F5F", "f. c #E4E4E4", "g. c #6D6D6D", "h. c #707070", "i. c #E3E3E3", "j. c #E6E6E6", "k. c #848484", "l. c #5B5B5B", "m. c #424242", "n. c #393939", "o. c #474747", "p. c #5A5A5A", "q. c #666666", "r. c #6C6C6C", "s. c #6E6E6E", "t. c #E2E2E2", "u. c #585858", "v. c #464646", "w. c #4F4F4F", "x. c #636363", "y. c #E0E0E0", "z. c #FAFAFA", "A. c #F8F8F8", "B. c #F7F7F7", "C. c #DDDDDD", "D. c #606060", "E. c #434343", "F. c #2D2D2D", "G. c #515151", "H. c #545454", "I. c #EEEEEE", "J. c #676767", "K. c #525252", "L. c #484848", "M. c #555555", "N. c #656565", "O. c #DFDFDF", "P. c #2E2E2E", "Q. c #A4A4A4", "R. c #5D5D5D", "S. c #626262", "T. c #3E3E3E", "U. c #5C5C5C", "V. c #323232", " ", " ", " ", " . + . @ # $ % & . & ", " * = - % ; > , ' ) ! ~ { ] ^ / ( ", " _ : < [ } ~ ; | 1 1 1 1 | { > ~ 2 3 4 : ", " 5 6 7 2 8 1 9 0 0 0 0 0 0 0 0 0 0 9 1 8 a * b c ", " d e ^ f $ g h h h h h h h h h h h h h h g $ i g j k ", " l m % # - - - - - - - - - - - - - - - - - - - - ] n b o ", " p m 9 0 q 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 q 0 @ r s ", " t u . q * * * * * * * * * * v ; { @ * * * * * * * * * * w % d x ", " y p / * 7 7 7 7 7 7 7 7 7 = ] z A A B # = 7 7 7 7 7 7 7 7 7 < - C D ", " E y F * G G G G G G G G G G 3 H I I I I J q K G G G G G G G G G < L M N ", " O P / Q Q Q Q Q Q Q Q Q Q F g R I I I I S 0 4 Q Q Q Q Q Q Q Q Q Q 3 T E ", " U V W X X X X X X X X X X X Y 3 Z I I I I ` q : X X X X X X X X X X X G t . ", " ..+.X : : : : : : : : : : : @._ #.I I I I $._ @.: : : : : : : : : : : %.&. . ", " *.=.@.-.-.-.-.-.-.-.-.-.-.-.-.-.5 Y ;.>.z ,.Y 5 -.-.-.-.-.-.-.-.-.-.-.-.W L '.U ", " ).!.~.c c c c c c c c c c c c c 5 r {.K K {.b 5 c c c c c c c c c c c c c : s U ", " ].^.b b b b b b b b b b b j j j /././././././.j b b b b b b b b b b b b b b (._. ", " E :.6 6 6 6 6 6 6 6 6 6 6 m [ <.<.<.<.<.<.<.@ c 6 6 6 6 6 6 6 6 6 6 6 6 6 6 /.[. ", " }.|.1.m m m m m m m m m m 2.k 3.I I I I I I I 4.X m m m m m m m m m m m m m m 6 5.6. ", " }.7.1.8.8.8.8.8.8.8.8.8.8.&.T 3.I I I I I I I J @.8.(.(.8.8.8.8.8.8.8.8.8.8.8.6 9.6. ", " 0.a.:.d d d d d d d d d b.d c.| | d.Z I I I I H ~.&.&.k k b.d d d d d d d d d (.e.}. ", " 0.a.c.:.:.:.:.:.:.:.T 1.d d T 1.T r f.I I I I H c d b.b.b.d 1.T :.:.:.:.:.:.m j !.0. ", " 0.7.g.^.^.^.^.^.h.c.u :.:.T T 1.1.j i.I I I I j.k.1.d 1.T :.:.u u T d &.k h.l.m.n.0. ", " 0.o.+.g.g.g.g.g.^.^.h.c.u :.T T T /.i.I I I I j.b :.T T T 1.k 6 b d o p.V m.N N n.0. ", " 0.N e.C q.P +.o r.s.s.h.h.c.c.:.u e t.I I I I H c &.&.8.e b.+.u.y v.[.m.N N N N n.0. ", " 0. .o.y V w.t p.e.x.q.+.g.h.T d d 6 y.z.A A.B.C.1.x.D.9.t a.V 7.y o.v.E.m.N N N .0. ", " F.U m.N N m.[.v.o.7.V D w.G.t H.t C ' I.I.I.I.,.J.K.t G.5.w.a.D 7.L.v.|.E.N N E.U F. ", " *.m.N N [.|.o.y V D M 5.G.K.H.H.C ' I.I.I.I.,.J.H.H.t K.5.w.a.D 7.L.v.|.m.m.E.*. ", " }.O [.m.|.v.L.7.D M 5.G.t H.M.x N.' I.I.I.I.,.l x x M.H.K.5.w.a.V 7.o.v.[.|.=.}. ", " 0.U v.|.v.o.7.V a.w.G.t H.x !.u.q.' I.I.I.I.,.l u.u.x M.H.K.5.w.D 7.y v.|.o...0. ", " }.N L.v.L.V D w.5.K.H.x !.9.9.l ) I.I.I.I.,.+.9.9.9.!.M.H.G.5.a.V y o.y m.}. ", " 0.].L.L.y V a.5.G.H.M.!.x M.x J.) I.I.I.I.,.P x x x u.x H.K.5.w.a.7.y 7.n.0. ", " 6.E a.V D M 5.K.H.x !.G.= / g O.I.I.I.I.y.0 / 7 K.u.!.M.t G.w.a.V M '.6. ", " P.U 7.M a.w.G.t M.!.u.G.4.I.I.I.I.I.I.I.I.I.I.I.H.9.9.x H.K.5.M w.V U P. ", " 0.].D 5.5.K.H.x u.9.H.4.I.I.I.I.I.I.I.I.I.I.I.x 9.9.!.M.t 5.G.a.n.0. ", " }.O K.t K.H.x 9.9.H.w ^ Q.Q.h h h h Q.^ ^ - x p.9.!.M.t H.H.=.}. ", " }.=.w.x M.x 9.p.p.p.R.p D.S.x.C x.D.e.R.l.p.l.9.!.M.!.5.T.}. ", " }._.5.9.u.9.l.R.e.s x.N.l P +.P J.C S.D.p U.9.9.p.G._.}. ", " 0...v.!.l.U.R.e.s x.N.J.l l J.q.C S.D.p R.U.!.v...0. ", " 0.V.=.D R.e.e.D.S.x.N.J.J.q.C x.s D.D.p a.=.V.0. ", " 0.6._.o.M.U.D.S.x.C N.C x.D.U.x o._.6.0. ", " }.*. .O [.y w.5.5.w.y [.O .*.6. ", " V.}.6.V.V.V.V.V.}.V. ", " ", " ", " "}; tqsl-2.0/apps/properties.xpm0000664000076400007640000003510012231073120016221 0ustar rmurphyrmurphy/* XPM */ static const char * properties_xpm[] = { "48 48 628 2", " c None", ". c #8FB1D0", "+ c #8CAFCF", "@ c #8EB1D0", "# c #93B4D3", "$ c #96B7D4", "% c #98B7D4", "& c #95B5D3", "* c #90B2D1", "= c #8FB1D1", "- c #91B2D1", "; c #7BA2C7", "> c #749EC4", ", c #82A8CB", "' c #95B5D4", ") c #A8C3DC", "! c #B2CAE1", "~ c #BCD1E6", "{ c #BFD3E7", "] c #C0D4E7", "^ c #BDD2E6", "/ c #B3CBE2", "( c #AAC4DE", "_ c #96B6D5", ": c #83A9CC", "< c #76A0C6", "[ c #7DA4C8", "} c #6592BC", "| c #6694BE", "1 c #7CA3C9", "2 c #A0BDD9", "3 c #B9CEE4", "4 c #B4CBE5", "5 c #A9C2E1", "6 c #A3BEDF", "7 c #9FBCDF", "8 c #9FBBDF", "9 c #A3BFE0", "0 c #A9C3E2", "a c #B3CAE4", "b c #9AB9D7", "c c #7DA5CA", "d c #6A97C0", "e c #6794BE", "f c #5E8CB7", "g c #5486B5", "h c #779FC6", "i c #9BB9D7", "j c #B0C8E3", "k c #9EBCDE", "l c #8CAFD8", "m c #89ADD7", "n c #8DAFD8", "o c #9FBCDE", "p c #9BBAD8", "q c #7AA2C8", "r c #5889B8", "s c #5F8DB9", "t c #4A7DAD", "u c #5385B4", "v c #A5C0DE", "w c #98B7DB", "x c #87ACD6", "y c #85AAD5", "z c #98B7DC", "A c #A5C1DE", "B c #89ACCF", "C c #5788B7", "D c #4C7FB0", "E c #3870A5", "F c #5284B3", "G c #95B4D6", "H c #96B6DA", "I c #81A7D3", "J c #96B5DA", "K c #9AB8D8", "L c #5889B7", "M c #3B73A7", "N c #2C669D", "O c #5384B3", "P c #8EB0D2", "Q c #89ADD5", "R c #7DA5D1", "S c #7DA4D1", "T c #89ADD6", "U c #93B3D5", "V c #5A8AB7", "W c #2F69A0", "X c #205C96", "Y c #4579AB", "Z c #8FB0D5", "` c #7FA5D2", " . c #78A1CF", ".. c #79A1CF", "+. c #91B2D8", "@. c #A8C2E0", "#. c #A9C3E0", "$. c #92B3D8", "%. c #7FA6D2", "&. c #94B4D7", "*. c #4A7DAF", "=. c #235F99", "-. c #15528E", ";. c #2D669F", ">. c #799FC9", ",. c #749ECE", "'. c #739DCD", "). c #96B5D9", "!. c #E6EDF5", "~. c #F7F9FC", "{. c #E7EEF6", "]. c #97B6D9", "^. c #7AA2D0", "/. c #82A7CD", "(. c #336CA3", "_. c #185591", ":. c #0A4885", "<. c #13528E", "[. c #6D97C3", "}. c #79A1CE", "|. c #709BCB", "1. c #6F9BCB", "2. c #7FA4CE", "3. c #DFE8F2", "4. c #FFFFFF", "5. c #E1E9F2", "6. c #80A5CE", "7. c #6F9ACB", "8. c #7AA2CF", "9. c #79A0C8", "0. c #185793", "a. c #0C4A88", "b. c #054584", "c. c #3B70A6", "d. c #769FCD", "e. c #6C98CA", "f. c #6B97C9", "g. c #8BABD0", "h. c #F1F5F9", "i. c #F3F6FA", "j. c #8DACD1", "k. c #6A96C8", "l. c #7DA4CF", "m. c #487BAC", "n. c #064887", "o. c #003E7D", "p. c #175490", "q. c #6490C0", "r. c #6895C7", "s. c #6794C6", "t. c #81A3CB", "u. c #EDF2F7", "v. c #EFF3F8", "w. c #83A4CB", "x. c #6693C6", "y. c #729BC6", "z. c #1F5B96", "A. c #00407F", "B. c #003F7D", "C. c #3C72A7", "D. c #6795C7", "E. c #6493C6", "F. c #6492C6", "G. c #6691C0", "H. c #CBD8E8", "I. c #CDDAE9", "J. c #6791C0", "K. c #6392C6", "L. c #6E99C9", "M. c #5080B1", "N. c #004080", "O. c #003B79", "P. c #084683", "Q. c #6492C3", "R. c #6090C3", "S. c #5F8FC3", "T. c #5B8BC0", "U. c #6A93C1", "V. c #C4D4E5", "W. c #E6ECF4", "X. c #E6EDF4", "Y. c #C6D5E6", "Z. c #6B93C1", "`. c #6090C4", " + c #78A0CB", ".+ c #0B4987", "++ c #003D7B", "@+ c #003D7A", "#+ c #275F97", "$+ c #5E8EC3", "%+ c #5C8DC2", "&+ c #5B8CC2", "*+ c #5989BF", "=+ c #608DBF", "-+ c #7299C5", ";+ c #618DBF", ">+ c #5889BF", ",+ c #6593C5", "'+ c #34699D", ")+ c #003E7C", "!+ c #04407C", "~+ c #4176AC", "{+ c #5789C0", "]+ c #5688BF", "^+ c #5687BF", "/+ c #5587BE", "(+ c #5586BE", "_+ c #5281B2", ":+ c #064380", "<+ c #0C4782", "[+ c #457AB2", "}+ c #5386BE", "|+ c #5184BC", "1+ c #A2BDDA", "2+ c #A3BEDB", "3+ c #A3BDDA", "4+ c #96B3D5", "5+ c #5E8CC0", "6+ c #5786B9", "7+ c #124C87", "8+ c #003872", "9+ c #134D88", "0+ c #477CB5", "a+ c #4F84BC", "b+ c #4E83BC", "c+ c #4A7FB8", "d+ c #FAFBFC", "e+ c #E1EAF3", "f+ c #6995C4", "g+ c #4E84BD", "h+ c #4F84BE", "i+ c #4F84BD", "j+ c #5486BB", "k+ c #215890", "l+ c #003974", "m+ c #18528D", "n+ c #467DB6", "o+ c #4B81BA", "p+ c #4B81BB", "q+ c #4A81BA", "r+ c #457BB7", "s+ c #E0E9F3", "t+ c #6592C3", "u+ c #4A82BD", "v+ c #4B83BE", "w+ c #4B82BD", "x+ c #4B82BC", "y+ c #5286BB", "z+ c #2B6197", "A+ c #003771", "B+ c #1B5590", "C+ c #437BB6", "D+ c #467DB8", "E+ c #467EBA", "F+ c #467FBA", "G+ c #457EBB", "H+ c #4179B6", "I+ c #A4BFDC", "J+ c #A4BFDB", "K+ c #AFC6DF", "L+ c #EDF2F8", "M+ c #5F8FC2", "N+ c #4681BE", "O+ c #4680BD", "P+ c #4680BC", "Q+ c #467FBB", "R+ c #467EB9", "S+ c #4D82BA", "T+ c #32669C", "U+ c #003770", "V+ c #1C5590", "W+ c #4079B5", "X+ c #427BB6", "Y+ c #427BB7", "Z+ c #427CB8", "`+ c #427DBA", " @ c #427EBB", ".@ c #427EBC", "+@ c #407CBB", "@@ c #417DBA", "#@ c #3F7CBA", "$@ c #588ABF", "%@ c #DBE6F0", "&@ c #417FBE", "*@ c #4280BF", "=@ c #427FBE", "-@ c #427FBD", ";@ c #427DBB", ">@ c #427CB9", ",@ c #427BB8", "'@ c #437BB7", ")@ c #4F84BB", "!@ c #5688BD", "~@ c #285F98", "{@ c #003670", "]@ c #18528F", "^@ c #3B75B2", "/@ c #3E77B4", "(@ c #3E78B5", "_@ c #3E79B7", ":@ c #3E7AB8", "<@ c #3E7BBA", "[@ c #3E7CBB", "}@ c #3E7DBD", "|@ c #3E7DBE", "1@ c #3E7EBF", "2@ c #3D7EBF", "3@ c #5488C0", "4@ c #DAE5F0", "5@ c #DEE7F2", "6@ c #588BC1", "7@ c #3D7EBE", "8@ c #3E7FBF", "9@ c #3E7CBC", "0@ c #3E7AB9", "a@ c #437CB8", "b@ c #477EB8", "c@ c #4A80B8", "d@ c #497FB8", "e@ c #3E78B2", "f@ c #2164A6", "g@ c #024D98", "h@ c #004286", "i@ c #134F8D", "j@ c #3672B0", "k@ c #3A75B2", "l@ c #3A75B4", "m@ c #3A77B5", "n@ c #3A78B7", "o@ c #3A79B9", "p@ c #3A7ABB", "q@ c #3A7BBC", "r@ c #3A7CBE", "s@ c #3A7DBF", "t@ c #3A7EC0", "u@ c #3A7DC0", "v@ c #5187BF", "w@ c #D9E4F0", "x@ c #DDE7F1", "y@ c #5489C0", "z@ c #397DC0", "A@ c #4380BE", "B@ c #4D87C0", "C@ c #548AC1", "D@ c #457EB9", "E@ c #3674B1", "F@ c #2163A6", "G@ c #0E559D", "H@ c #004C98", "I@ c #004B97", "J@ c #2868AA", "K@ c #2F6DAD", "L@ c #316FAE", "M@ c #3471AF", "N@ c #3573B1", "O@ c #3674B4", "P@ c #3675B6", "Q@ c #3677B8", "R@ c #3677B9", "S@ c #3679BB", "T@ c #367ABD", "U@ c #367BBF", "V@ c #367BC0", "W@ c #367DC2", "X@ c #357CC1", "Y@ c #4D86BF", "Z@ c #D8E4F0", "`@ c #DEE8F2", " # c #588DC2", ".# c #3F83C5", "+# c #4184C4", "@# c #4787C5", "## c #3E81C1", "$# c #2D74B9", "%# c #1563AE", "&# c #0355A5", "*# c #0051A1", "=# c #004F9E", "-# c #004D9A", ";# c #004C97", "># c #004284", ",# c #00366F", "'# c #014080", ")# c #07519B", "!# c #0B539C", "~# c #0E559E", "{# c #1159A1", "]# c #165DA5", "^# c #1D64AB", "/# c #2269AF", "(# c #266DB3", "_# c #2870B7", ":# c #2C74BA", "<# c #2E77BD", "[# c #327AC0", "}# c #367EC2", "|# c #3880C5", "1# c #4E87C0", "2# c #D6E2ED", "3# c #FAFAFA", "4# c #F9F9F9", "5# c #F8F8F8", "6# c #F7F7F7", "7# c #D3DEEA", "8# c #407EBB", "9# c #1B6FBD", "0# c #176DBC", "a# c #0F66B8", "b# c #0760B3", "c# c #005AAE", "d# c #0058AC", "e# c #0056A9", "f# c #0055A7", "g# c #0053A3", "h# c #004E9C", "i# c #004C99", "j# c #004081", "k# c #00346F", "l# c #004D99", "m# c #004D9B", "n# c #0051A2", "o# c #0053A4", "p# c #0057AB", "q# c #0059AE", "r# c #005CB1", "s# c #025FB4", "t# c #0361B7", "u# c #0262B9", "v# c #0161BA", "w# c #256FB5", "x# c #C4D2E0", "y# c #EEEEEE", "z# c #C8D5E1", "A# c #2971B5", "B# c #0060B9", "C# c #0061BA", "D# c #005FB7", "E# c #005EB5", "F# c #005CB3", "G# c #005AAF", "H# c #0059AD", "I# c #0057AA", "J# c #0054A6", "K# c #0052A3", "L# c #00509F", "M# c #004E9B", "N# c #003B77", "O# c #004F9D", "P# c #0051A0", "Q# c #005BB1", "R# c #005DB4", "S# c #005FB6", "T# c #0062BB", "U# c #0062BC", "V# c #256FB6", "W# c #C3D2E0", "X# c #C8D5E2", "Y# c #2971B7", "Z# c #0063BD", "`# c #0060B8", " $ c #0056A8", ".$ c #0054A5", "+$ c #0052A1", "@$ c #00509E", "#$ c #004E9A", "$$ c #003B78", "%$ c #003873", "&$ c #00468B", "*$ c #004F9F", "=$ c #0052A2", "-$ c #0054A7", ";$ c #005BB0", ">$ c #0061BB", ",$ c #0064C0", "'$ c #0065C1", ")$ c #2570B8", "!$ c #2972B8", "~$ c #0064BE", "{$ c #005EB6", "]$ c #005CB2", "^$ c #0058AB", "/$ c #0050A0", "($ c #00478D", "_$ c #005AB0", ":$ c #0065C0", "<$ c #0066C3", "[$ c #0067C3", "}$ c #2571BA", "|$ c #C3D2E1", "1$ c #2973B9", "2$ c #0067C4", "3$ c #0064BF", "4$ c #005EB4", "5$ c #0055A6", "6$ c #0053A5", "7$ c #004C95", "8$ c #0069C6", "9$ c #0069C7", "0$ c #2573BC", "a$ c #C3D3E1", "b$ c #2975BC", "c$ c #0068C4", "d$ c #0066C2", "e$ c #0055A8", "f$ c #004D98", "g$ c #004182", "h$ c #2572BC", "i$ c #C3D3E2", "j$ c #2974BB", "k$ c #0057A9", "l$ c #0056A7", "m$ c #004283", "n$ c #004A91", "o$ c #709FCC", "p$ c #72A1CD", "q$ c #85ADD1", "r$ c #D8E0E7", "s$ c #DAE1E8", "t$ c #88ADD1", "u$ c #72A1CC", "v$ c #72A0CC", "w$ c #025FB6", "x$ c #005FB8", "y$ c #004B93", "z$ c #003570", "A$ c #005BB2", "B$ c #0067C5", "C$ c #005FB9", "D$ c #E7E9EB", "E$ c #0562B8", "F$ c #0068C5", "G$ c #005CB4", "H$ c #003D7C", "I$ c #004183", "J$ c #0059AC", "K$ c #0068C6", "L$ c #E7E9EC", "M$ c #0564BB", "N$ c #0063BE", "O$ c #78A8D4", "P$ c #7BAAD5", "Q$ c #7BABD6", "R$ c #7BABD7", "S$ c #7BACD8", "T$ c #7BACD9", "U$ c #7BAAD6", "V$ c #7BA9D4", "W$ c #0264BD", "X$ c #006AC8", "Y$ c #00478C", "Z$ c #005DB3", "`$ c #0063BF", " % c #006AC9", ".% c #006ACA", "+% c #006DCE", "@% c #006FD1", "#% c #0071D4", "$% c #0073D8", "%% c #0075DB", "&% c #0076DB", "*% c #0074D9", "=% c #0071D5", "-% c #0070D2", ";% c #006BCB", ">% c #0066C4", ",% c #00488E", "'% c #004385", ")% c #0068C7", "!% c #006BCA", "~% c #006DCD", "{% c #0072D6", "]% c #0075DA", "^% c #0077DE", "/% c #007BE2", "(% c #007CE6", "_% c #007DE7", ":% c #007CE4", "<% c #0079E0", "[% c #0076DC", "}% c #0073D7", "|% c #006ECF", "1% c #006CCC", "2% c #0069C8", "3% c #004386", "4% c #003F7E", "5% c #00529E", "6% c #0066C1", "7% c #0070D1", "8% c #0072D5", "9% c #0075D9", "0% c #0077DD", "a% c #007AE2", "b% c #007BE3", "c% c #007AE1", "d% c #0078DE", "e% c #0071D3", "f% c #00529F", "g% c #003A76", "h% c #00478B", "i% c #0070D3", "j% c #0079DF", "k% c #006ED0", "l% c #005AAD", "m% c #004486", "n% c #0053A0", "o% c #006CCA", "p% c #0074D8", "q% c #006CCB", "r% c #0065BF", "s% c #0053A1", "t% c #004487", "u% c #003975", "v% c #013872", "w% c #003B75", "x% c #00407E", "y% c #004689", "z% c #004F9A", "A% c #0056A6", "B% c #005CB0", "C% c #005EB3", "D% c #00468A", "E% c #013972", "F% c #023A73", "G% c #003871", "H% c #003973", "I% c #003A73", "J% c #003A74", "K% c #023A72", " ", " ", " ", " . + @ # $ % & * = - ", " ; > , ' ) ! ~ { ] ^ / ( _ : < [ ", " } | 1 2 3 4 5 6 7 8 8 7 9 0 a / b c d e ", " f g h i j k l m m m m m m m m m m n o j p q r s ", " t u : v w x y y y y y y y y y y y y y y x z A B C D ", " E F G H I I I I I I I I I I I I I I I I I I I I J K L M ", " N O P Q R S S S S S S S S S S S S S S S S S S S S R T U V W ", " X Y Z ` . . . . . . . . ...+.@.#.$... . . . . . . . . .%.&.*.=. ", " -.;.>...,.,.,.,.,.,.,.,.,.'.).!.~.~.{.].'.,.,.,.,.,.,.,.,.,.^./.(._. ", " :.<.[.}.|.|.|.|.|.|.|.|.|.1.2.3.4.4.4.4.5.6.7.|.|.|.|.|.|.|.|.|.8.9.0.a. ", " b.c.d.e.e.e.e.e.e.e.e.e.e.f.g.h.4.4.4.4.i.j.k.e.e.e.e.e.e.e.e.e.e.l.m.n. ", " o.p.q.r.r.r.r.r.r.r.r.r.r.r.s.t.u.4.4.4.4.v.w.x.r.r.r.r.r.r.r.r.r.r.r.y.z.A. ", " B.C.D.E.E.E.E.E.E.E.E.E.E.E.F.G.H.4.4.4.4.I.J.K.E.E.E.E.E.E.E.E.E.E.E.L.M.N. ", " O.P.Q.R.S.S.S.S.S.S.S.S.S.S.S.S.T.U.V.W.X.Y.Z.T.S.S.S.S.S.S.S.S.S.S.S.S.`. +.+++ ", " @+#+$+%+%+%+%+%+%+%+%+%+%+%+%+%+&+*+=+-+-+;+>+&+%+%+%+%+%+%+%+%+%+%+%+%+%+,+'+)+ ", " !+~+{+{+{+{+{+{+{+{+{+{+{+]+]+^+/+/+(+(+(+/+/+^+{+{+{+{+{+{+{+{+{+{+{+{+{+{+_+:+ ", " <+[+}+}+}+}+}+}+}+}+}+}+}+|+1+2+3+3+3+3+3+3+4+5+}+}+}+}+}+}+}+}+}+}+}+}+}+}+6+7+ ", " 8+9+0+a+a+a+a+a+a+a+a+a+a+b+c+d+4.4.4.4.4.4.4.e+f+g+h+i+a+a+a+a+a+a+a+a+a+a+a+j+k+l+ ", " 8+m+n+o+o+o+o+o+o+o+o+o+p+q+r+d+4.4.4.4.4.4.4.s+t+u+v+w+x+p+o+o+o+o+o+o+o+o+o+y+z+l+ ", " A+B+C+D+D+D+D+D+D+D+D+E+F+G+H+I+J+K+L+4.4.4.4.3.M+N+N+O+P+Q+E+R+D+D+D+D+D+D+D+S+T+8+ ", " U+V+W+X+X+X+X+X+Y+Y+Z+`+ @.@+@@@#@$@%@4.4.4.4.3.%+&@*@=@-@ @;@>@,@Y+X+X+X+'@)@!@~@A+ ", " {@]@^@/@/@/@/@/@(@_@:@<@[@}@|@1@2@3@4@4.4.4.4.5@6@7@8@1@|@9@[@0@:@a@b@c@d@e@f@g@h@U+ ", " {@i@j@k@k@k@k@l@m@n@o@p@q@r@s@t@u@v@w@4.4.4.4.x@y@z@t@s@s@7@A@B@C@D@E@F@G@g@H@I@h@{@ ", " {@a.J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@4.4.4.4.`@ #.#.#+#@###$#%#&#*#=#-#H@H@H@;#>#{@ ", " ,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#|#1#2#3#4#5#6#7#8#9#0#a#b#c#d#e#f#g#*#h#-#H@H@i#j#,# ", " k#++l#H@H@m#=#n#o#e#p#q#r#s#t#u#v#w#x#y#y#y#y#z#A#B#C#D#E#F#G#H#I#J#K#L#h#H@H@M#o.k# ", " N#l#i#i#O#P#o#f#p#q#Q#R#S#B#T#U#V#W#y#y#y#y#X#Y#U#Z#C#`#E#F#G#H# $.$+$@$-#-##$$$ ", " %$&$*$m#L#=$-$e#q#;$R#D#>$Z#,$'$)$W#y#y#y#y#X#!$'$'$~$U#B#{$]$G#^$ $o#*#O#/$($%$ ", " {@)+K#L#*#o# $d#_$F#D#C#Z#:$<$[$}$|$y#y#y#y#X#1$[$2$'$3$T#`#4$r#H#I#5$=$/$6$B.{@ ", " %$7$.$K#J#p#q#]$E#B#U#:$<$8$9$0$a$y#y#y#y#X#b$9$9$c$d$~$T#D#R#G#d#e$6$f#f$%$ ", " ,#g$.$.$f#d#G#R#D#T#3$d$:$,$'$h$i$y#y#y#y#X#j$:$:$'$[$:$Z#B#{$r#c#k$f#l$m$,# ", " l+n$G#p#H#Q#{$B#Z#'$<$D#o$p$q$r$y#y#y#y#s$t$u$v$w$2$d$3$>$x$F#G#d#Q#y$l+ ", " z$++k$A$G#]$D#C#3$d$B$C$D$y#y#y#y#y#y#y#y#y#y#y#E$F$c$'$U#`#R#Q#G$^$H$z$ ", " {@I$J${$R#`#U#:$2$K$T#L$y#y#y#y#y#y#y#y#y#y#y#M$9$K$d$N$C#E#D#c#>#{@ ", " %$&$B#C#B#U#'$F$9$Z#O$P$Q$R$S$T$S$S$R$U$P$V$W$X$9$<$N$>$T#T#Y$%$ ", " 8+($Z$'$`$'$F$ % %.%+%@%#%$%%%&%*%=%-%+%;%.%;%9$>%,$d$E#,%8+ ", " %$'%E#)%2$K$!%~%-%{%]%^%/%(%_%:%<%[%}%#%|%1%9$K$2%S#3%%$ ", " {@4%5%6%;%1%~%7%8%9%0%<%a%b%c%d%&%}%e%|%~%1%d$f%4%{@ ", " {@g%h%J$+%i%i%#%$%%%^%j%j%d%[%*%{%#%=%k%l%Y$g%{@ ", " U+l+m%n%~$o%e%$%%%[%0%[%p%#%q%r%s%t%u%A+ ", " v%w%x%y%z%A%B%C%C%B%A%z%D%A.w%E% ", " F%G%H%I%J%J%J%I%G%K% ", " ", " ", " "}; tqsl-2.0/apps/nocert.xpm0000664000076400007640000000117212231073120015321 0ustar rmurphyrmurphy/* XPM */ static const char * nocert_xpm[] = { "16 16 17 1", " c None", ". c #FE0706", "+ c #FA463F", "@ c #F9786F", "# c #F29688", "$ c #D0CAA2", "% c #DEDC9D", "& c #EAD5C7", "* c #FA3832", "= c #F7F69D", "- c #E4DCDA", "; c #FA271F", "> c #F7E9E9", ", c #FEBD89", "' c #F25B51", ") c #FCFCFC", "! c #FE1A11", ")))))&@'+'#>))))", "))))'.*'''!.#)))", "))>*!,%%$$%#.'))", "))'!%$==%=%%,.#)", ")&.,%==$=$=%+.!)", ")@;=$=$===@!;,.,", ")++=%=%=='.@$=!@", ")+'%%==#!;,%%$*@", ")+@$=$'.@==%=-*@", ")@;)#!;#$$%%$>.,", ")>.*.'$%%%$>)@!)", "))@.#%=%$$=-,.#)", ")))+.@%=$%%'.@))", "))))@..+**.!#)))", "))))$$@'''@%$)))", ")))))->--->>))))"}; tqsl-2.0/apps/lotw.xpm0000664000076400007640000001537512231073120015026 0ustar rmurphyrmurphy/* XPM */ static const char * lotw_xpm[] = { "48 48 128 2", " c #D0CFD2", ". c #61531E", "+ c #5B090C", "@ c #434559", "# c #F3DE9B", "$ c #585665", "% c #E49C6C", "& c #747387", "* c #E9CD27", "= c #EFD74C", "- c #676568", "; c #787775", "> c #887270", ", c #83701B", "' c #363746", ") c #080401", "! c #676578", "~ c #E8E8EA", "{ c #E6B393", "] c #8C8476", "^ c #9698A8", "/ c #484244", "( c #262327", "_ c #383337", ": c #858485", "< c #F2DD65", "[ c #BDBDBF", "} c #D1B41A", "| c #58535A", "1 c #FFFFFF", "2 c #AC9317", "3 c #665954", "4 c #ADB4C9", "5 c #858696", "6 c #29120E", "7 c #161317", "8 c #B2938C", "9 c #A6A4A5", "0 c #484B61", "a c #940F13", "b c #9B999A", "c c #B08973", "d c #272832", "e c #72654B", "f c #5D6065", "g c #625C69", "h c #FCE8D1", "i c #AC972F", "j c #F28B36", "k c #F5D7C4", "l c #788195", "m c #756767", "n c #726A78", "o c #8B6F54", "p c #AB6D4E", "q c #807B8A", "r c #544843", "s c #AFA694", "t c #A6A8B6", "u c #514B54", "v c #302828", "w c #5A5A6F", "x c #958851", "y c #0F0903", "z c #75716C", "A c #423B3F", "B c #BBC8D8", "C c #98862F", "D c #CEB42E", "E c #AC7A67", "F c #9B8414", "G c #DCDCDF", "H c #B6A971", "I c #FCF5ED", "J c #F4F4F5", "K c #9DA1AD", "L c #FAEDE5", "M c #FE0000", "N c #1B100A", "O c #988684", "P c #A89CA6", "Q c #BBA32F", "R c #2A201C", "S c #19181E", "T c #4F5168", "U c #3D3F52", "V c #C50E13", "W c #A69756", "X c #DA1820", "Y c #B4A8A5", "Z c #979387", "` c #6B6E7D", " . c #2F2D31", ".. c #F4E37F", "+. c #BAAA59", "@. c #5C504A", "#. c #8E909D", "$. c #DDE3EA", "%. c #CE7E55", "&. c #BCA218", "*. c #D1C06C", "=. c #918D92", "-. c #B3B1AE", ";. c #3A312A", ">. c #B5AAB5", ",. c #D7C352", "'. c #FFFBF5", "). c #FCF7F4", "!. c #965A42", "~. c #AEB0BA", "{. c #1F1D20", "]. c #2E2F3D", "^. c #EFEFEF", "/. c #1F2028", "(. c #C3BFC9", "_. c #7F7F7B", ":. c #0A0A0C", "<. c #ECF3F6", "[. c #E4E2E2", "}. c #100C0D", "|. c #505056", "1. c #F0F1ED", "2. c #EF1C24", "3. c #4F4E60", "4. c #101013", "5. c #6E6F6E", "6. c #51556F", "7. c #000000", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.' @ @ @ @ @ @ @ @ @ 4.7.@ d @ @ @ @ @ @ @ @ /.) ) ) 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.@ U @ @ 1 U @ @ @ 7 :.1 @ ' & 1 ' & 1 @ @ 4.:.:.:.:.) ) ) ) 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.U @ {.1 @ [ @ @ [ 4.].@ 1 ' ^ 0 ' ^ 0 0 0 d /.7 7 4.}.:.:.:.) 7.7.7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.U @ {.^.U ~.@ @ @ d @ ' ~ U ` G @ & G T 0 0 U /.{.S S 4.4.:.:.) ) 7.7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.@ @ d @ @ @ @ @ @ {.0 ' 0 0 T 0 T T 0 T T T U ]. .d /.{.S 4.}.:.:.) 7.7.7.7.7.7.7.7.7.7.7.7.", "7.7.) ) ) ) ) ) y :.}.7 S ( d ].' U U @ 0 0 0 0 0 @ U ' ].d ( {.7 4.:.) ) 7.7.7.7.7.7.7.7.7.7.7.", "7.) ) ) ) ) ) ) }.4.7 {.( .' U @ 3.B 4 $.^ l l 8 #.l 0 @ ' ].d /.S 4.:.) 7.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) ) ) y }.4.7 {.d _ U 0 t L k L k k { { =.O c c > ` 3.@ ' ]./.S 4.:.:.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) ) y y }.7 {.d ' U 3.).I h L h { % % %.%.@ E E E u | | @ ' ]./.S 4.:.) 7.7.7.7.7.7.7.7.7.", ") ) ) ) ) y }.7 {.d _ / 3.I I 1 h { O > %.> o 3 c 8 c E o .U A @ ' ./.7 :.:.) 7.7.7.7.7.7.7.7.", ") ) ) y y }.7 {.v _ U T B >.(.[.t 8 z 3 3 3 O E !.p A _ @ .d d 0 ' d {.7 :.) 7.7.7.7.7.7.7.7.", ") ) 7 S S 4.7 {. .U T ^ 5 >.K ^ (.b : ; P : 9 c c E > A U / . ./ {.0 U d S S S 7 4.4.4.7.7.7.7.", ") d 0 0 0 U {.v T w s & & q & 5 s s & ! n q & ! g $ | w Z g T U | w 0 Z T U 0 @ @ @ @ @ U 7.7.7.", ") {.0 < 0 ' ( @ O = & ,.*.& & ..5 n } q n ..& _.= & & = ! g < $ 3.# x 6.< 0 0 # @ @ &.@ ].7.7.7.", ") ) U * 3.{.v $ < & ` l < ` *.} =.> n q 5 < q q = & H e $ T < ` T * T T 6.< @ ..@ &.@ S 7.7.7.7.", ") y U * 3.R _ w * ` 5 #.< q * z >.q n 5 =.< n +.,.` * $ / 3.+.= +.F 3.d 6.* 0 ..= @ d 7.7.7.7.7.", ") y U * 3.( A w } ` 5 & = ! &.m p > ..q #.* n - * & * w / u *.} i , 0 d 6.* 0 * &., @ ) 7.7.7.7.", "y y U * 3._ $ g &.! ! ! } ! F &.c o = m m * g ! &.! C n u $ * @.6.F w ' 6.F 0 } @ F } ' 7.7.7.7.", "y {.@ } 3.$ = w , 2 ! W . g ! 2 & m } - n } - g . g g F w $ , $ T F f T } 6.0 F 0 @ F @ ' 7.7.7.", "y .e r r @.3 g & & , 3 q 5 - - ;.. m q m e @.r g $ u $ , @.$ / u T 3 . w 0 @./ ;.U .;.@ ) 7.7.", "y y R v .A / u 5 l 5 & : K b z ;.( 9 s 3 @.@.@./ A A A u / _ . . ._ u T ' ' d /.S S S 4.7.7.7.", "y y y N R v _ / ` b - g ; @.> | , Q . -.Y ] r r / A r A A | / _ v .( ( 0 ' d S :.) 7.7.7.7.7.7.", "y y y N 6 v _ / g ! : : r [ z Q {.S S 3 -.q ` ! w 6.6.T T 6.! w 0 @ 0 0 6.T @ 0 ].; 7.7.7.7.7.7.", "y y y N S R ;./ | 5.: ; m @.-., C i &.@.9 1 & #.! 6.w 5 t T @ ~ T [ 0 K 1 K U 0 @ ) 7.7.7.7.7.7.", "y y y N N R ;.A u f _.- : @.m . C Q ( 9 9 J K 5 w w w 5 K T T 0 G & T ^ G ^ ^ 0 @ ) 7.7.7.7.7.7.", "y y y N N R v _ / $ | ; _.3 Z / C i r b _.3 3 5.r u | 5.- A _ - _ .A 0 U ' d d :.) 7.7.7.7.7.7.", "y y y N N 6 R ;.A u $ | ; z ; : {.{.A _.e ] z 3 r ;.| : _.f f f v v v U ]./.7 :.) 7.7.7.7.7.7.7.", "y y y N N N R v _ / | f 3 5.- 3 i r : 3 @.; @.3 m r r A / 5.5.f _ ( @ ].d S 4.:.) 7.7.7.7.7.7.7.", "y y y y N N 6 R ;.A u $ f z ; _.f A : : : m ] m - 3 / ;.;.| r v v 0 U ./.7 :.:.7.7.7.7.7.7.7.7.", "y y y y }.N N R v ;.A u g f 5.; ; z _._._.; 5.- A | $ - - A v v 3.U ].( S 4.:.) 7.7.7.7.7.7.7.7.", "y y y y y N N S R v ;.A u $ f - - ; ; ; ; ; ; ; f 5.f | $ r _ 0 A ].( S 4.:.) 7.7.7.7.7.7.7.7.7.", ") y y y y }.N N N R v ;.A u | 3 f - 5.z 5.5.5.5.- f f / u 3.@ A ].( {.7 }.:.) 7.7.7.7.7.7.7.7.7.", ") y y y y y N N N 6 R v ;._ / u | g | f f f f f f $ u 3.u U ' .( S 7 }.:.) ) 7.7.7.7.7.7.7.7.7.", ") ) y y y y y y N N N R R v ;.A / r u | | $ $ $ 3.u @ U ' ].d ( S 7 }.:.) ) 7.7.7.7.7.7.7.7.7.7.", ") ) y y y y y y N N N N R R v ._ A A / / / / / A A _ . .( {.S 4.}.:.) ) 7.7.7.7.7.7.7.7.7.7.7.", ") ) ) y y y y y y y }.N N S {.R R v v . . . . . .v ( {.{.S 7 }.}.:.) ) ) 7.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) y y y y y y y N N N N 6 6 R R R R R R R {.{.S 7 7 4.}.y y ) ) ) ) 7.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) ) y y y y y y y y N N N N N N N 6 N N N N 4.}.}.}.y y y ) ) ) ) ) 7.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) ) ) y y y y y y y y y y y N }.}.}.}.}.}.}.y y y y y ) ) ) ) ) 7.7.7.7.7.7.7.7.7.7.7.7.7.", ") ) ) ) ) ) ) ) y y y y y y y y y y y y y y y y y y y y y ) ) ) ) ) ) 7.7.7.7.7.7.7.7.7.7.7.7.7."}; tqsl-2.0/apps/loctree.h0000664000076400007640000000307512231073120015113 0ustar rmurphyrmurphy/*************************************************************************** loctree.h - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __loctree_h #define __loctree_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "tqsllib.h" #include "wx/treectrl.h" class LocTreeItemData : public wxTreeItemData { public: LocTreeItemData(wxString locname, wxString callsign) : _locname(locname), _callsign(callsign) {} wxString getLocname() { return _locname; } wxString getCallSign() { return _callsign; } private: wxString _locname; wxString _callsign; }; class LocTree : public wxTreeCtrl { public: LocTree(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); virtual ~LocTree(); int Build(int flags = TQSL_SELECT_CERT_WITHKEYS, const TQSL_PROVIDER *provider = 0); void OnItemActivated(wxTreeEvent& event); void OnRightDown(wxMouseEvent& event); bool useContextMenu; LocTreeItemData *GetItemData(wxTreeItemId id) { return (LocTreeItemData *)wxTreeCtrl::GetItemData(id); } int GetNumLocations() const { return _nloc; } private: int _nloc; DECLARE_EVENT_TABLE() }; #endif // __loctree_h tqsl-2.0/apps/loctree.cpp0000664000076400007640000000722312231073120015445 0ustar rmurphyrmurphy/*************************************************************************** loctree.cpp - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include "loctree.h" #include #include #include #include "tqslctrls.h" #include "tqslerrno.h" #include "tqsltrace.h" #include #include #include #include "util.h" using namespace std; #include "folder.xpm" #include "home.xpm" enum { FOLDER_ICON = 0, HOME_ICON = 1 }; ///////////// Location Tree Control //////////////// BEGIN_EVENT_TABLE(LocTree, wxTreeCtrl) EVT_TREE_ITEM_ACTIVATED(-1, LocTree::OnItemActivated) EVT_RIGHT_DOWN(LocTree::OnRightDown) END_EVENT_TABLE() LocTree::LocTree(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxTreeCtrl(parent, id, pos, size, style), _nloc(0) { tqslTrace("LocTree::LocTree", "parent=0x%lx, id=0x%lx, style=%d", (void *)parent, (void *)id, style); useContextMenu = true; wxBitmap homebm(home_xpm); wxBitmap folderbm(folder_xpm); wxImageList *il = new wxImageList(16, 16, false, 2); il->Add(folderbm); il->Add(homebm); SetImageList(il); } LocTree::~LocTree() { } typedef pair locitem; typedef vector loclist; static bool cl_cmp(const locitem& i1, const locitem& i2) { return i1.first < i2.first; } static void check_tqsl_error(int rval) { if (rval == 0) return; wxLogError(wxT("%hs"), tqsl_getErrorString()); } int LocTree::Build(int flags, const TQSL_PROVIDER *provider) { tqslTrace("LocTree::Build", "provider=0x%lx", (void *)provider); typedef map locmap; locmap callsigns; DeleteAllItems(); wxTreeItemId rootId = AddRoot(wxT("Station Locations"), FOLDER_ICON); tQSL_Location loc; check_tqsl_error(tqsl_initStationLocationCapture(&loc)); check_tqsl_error(tqsl_getNumStationLocations(loc, &_nloc)); for (int i = 0; i < _nloc && i < 2000; i++) { char locname[256]; check_tqsl_error(tqsl_getStationLocationName(loc, i, locname, sizeof locname)); char callsign[256]; check_tqsl_error(tqsl_getStationLocationCallSign(loc, i, callsign, sizeof callsign)); callsigns[wxString(callsign, wxConvLocal)].push_back(make_pair(wxString(locname, wxConvLocal),i)); } // Sort each callsign list and add items to tree locmap::iterator loc_it; for (loc_it = callsigns.begin(); loc_it != callsigns.end(); loc_it++) { wxTreeItemId id = AppendItem(rootId, loc_it->first, FOLDER_ICON); loclist& list = loc_it->second; sort(list.begin(), list.end(), cl_cmp); for (int i = 0; i < (int)list.size(); i++) { LocTreeItemData *loc = new LocTreeItemData(list[i].first, loc_it->first); AppendItem(id, list[i].first, HOME_ICON, -1, loc); } Expand(id); } Expand(rootId); return _nloc; } void LocTree::OnItemActivated(wxTreeEvent& event) { tqslTrace("LocTree::OnItemActivated"); wxTreeItemId id = event.GetItem(); displayLocProperties((LocTreeItemData *)GetItemData(id), this); } void LocTree::OnRightDown(wxMouseEvent& event) { tqslTrace("LocTree::OnRightDown"); if (!useContextMenu) return; wxTreeItemId id = HitTest(event.GetPosition()); if (id && GetItemData(id)) { SelectItem(id); wxString locname = GetItemData(id)->getLocname(); wxMenu *cm = makeLocationMenu(true); PopupMenu(cm, event.GetPosition()); delete cm; } } tqsl-2.0/apps/loc_add_dis.xpm0000664000076400007640000001642112231073120016256 0ustar rmurphyrmurphy/* XPM */ static const char * loc_add_dis_xpm[] = { "48 48 161 2", " c None", ". c #8E8E8E", "+ c #8F8F8F", "@ c #ACACAC", "# c #ADADAD", "$ c #595959", "% c #6D6D6D", "& c #6E6E6E", "* c #A9A9A9", "= c #A3A3A3", "- c #A5A5A5", "; c #909090", "> c #AFAFAF", ", c #A7A7A7", "' c #B5B5B5", ") c #8C8C8C", "! c #A6A6A6", "~ c #9F9F9F", "{ c #969696", "] c #999999", "^ c #6C6C6C", "/ c #A1A1A1", "( c #8B8B8B", "_ c #A8A8A8", ": c #919191", "< c #929292", "[ c #989898", "} c #A4A4A4", "| c #6B6B6B", "1 c #9D9D9D", "2 c #868686", "3 c #8A8A8A", "4 c #767676", "5 c #A0A0A0", "6 c #949494", "7 c #8D8D8D", "8 c #959595", "9 c #979797", "0 c #818181", "a c #858585", "b c #9C9C9C", "c c #888888", "d c #ABABAB", "e c #6A6A6A", "f c #7C7C7C", "g c #898989", "h c #9B9B9B", "i c #828282", "j c #878787", "k c #696969", "l c #797979", "m c #7A7A7A", "n c #7D7D7D", "o c #7F7F7F", "p c #848484", "q c #939393", "r c #A2A2A2", "s c #686868", "t c #777777", "u c #616161", "v c #717171", "w c #727272", "x c #757575", "y c #7E7E7E", "z c #838383", "A c #AAAAAA", "B c #787878", "C c #6F6F6F", "D c #747474", "E c #7B7B7B", "F c #808080", "G c #676767", "H c #737373", "I c #707070", "J c #636363", "K c #646464", "L c #666666", "M c #5D5D5D", "N c #5F5F5F", "O c #606060", "P c #656565", "Q c #5B5B5B", "R c #5C5C5C", "S c #5E5E5E", "T c #626262", "U c #9A9A9A", "V c #B1B1B1", "W c #B4B4B4", "X c #BBBBBB", "Y c #9E9E9E", "Z c #E6E6E6", "` c #E2E2E2", " . c #E3E3E3", ".. c #E4E4E4", "+. c #E5E5E5", "@. c #E7E7E7", "#. c #E8E8E8", "$. c #E9E9E9", "%. c #EAEAEA", "&. c #EBEBEB", "*. c #ECECEC", "=. c #EDEDED", "-. c #EEEEEE", ";. c #EFEFEF", ">. c #F0F0F0", ",. c #F1F1F1", "'. c #F2F2F2", "). c #F3F3F3", "!. c #F4F4F4", "~. c #F6F6F6", "{. c #F7F7F7", "]. c #F8F8F8", "^. c #FAFAFA", "/. c #E1E1E1", "(. c #F5F5F5", "_. c #F9F9F9", ":. c #DFDFDF", "<. c #E0E0E0", "[. c #DEDEDE", "}. c #DDDDDD", "|. c #DCDCDC", "1. c #C9C9C9", "2. c #C1C1C1", "3. c #C2C2C2", "4. c #C3C3C3", "5. c #C4C4C4", "6. c #C6C6C6", "7. c #D0D0D0", "8. c #DBDBDB", "9. c #C7C7C7", "0. c #DADADA", "a. c #BFBFBF", "b. c #CACACA", "c. c #CBCBCB", "d. c #CCCCCC", "e. c #CECECE", "f. c #D1D1D1", "g. c #D5D5D5", "h. c #C8C8C8", "i. c #D8D8D8", "j. c #D9D9D9", "k. c #BEBEBE", "l. c #C0C0C0", "m. c #CFCFCF", "n. c #BDBDBD", "o. c #C5C5C5", "p. c #D7D7D7", "q. c #BCBCBC", "r. c #D6D6D6", "s. c #B8B8B8", "t. c #BABABA", "u. c #B6B6B6", "v. c #B7B7B7", "w. c #D4D4D4", "x. c #B9B9B9", "y. c #D3D3D3", "z. c #B3B3B3", "A. c #D2D2D2", "B. c #AEAEAE", "C. c #B0B0B0", "D. c #B2B2B2", " ", " ", " ", " ", " . + ", " . @ # + ", " $ % % % & $ + * = - # ; ", " % > - , ' & ) ! ~ { ] - @ . ", " ^ / ( + _ & ( = ] : < { [ } @ . ", " | 1 2 3 - 4 ) 5 6 ( 7 + < 8 9 } @ ; ", " | ] 0 a 6 ; b ; 2 c 3 ) + : 6 9 } d . ", " e 8 f 0 g h 3 0 i a j 3 7 + : 6 9 = d . ", " k : l 3 9 a m n o i p 2 g ( . : q 8 r d + ", " s : a 6 i 4 t l f o 0 p 2 c ( . ; < { = d . ", " u ) 6 f v w x t l f y 0 z 2 c ( 7 + q 8 / A . ", " c . B | % C w D 4 l E n F i a c 3 ) + < 6 / A + ", " 2 ) x G s e ^ C v H 4 B m n o i a j g ) + : 8 / A + ", " j 7 I J K L s e % C v H x B m n o i p j g ) . : 6 5 * ; ", " 2 j ^ M N O J P G e ^ & I w D t l E o 0 z 2 c ( 7 ; < ~ * + ", " c a e Q Q R S u T P G k | & I w D 4 l f y F z a c ( 7 ; q 5 * : ", " c : < 3 g ( ) 7 . ; : q 6 8 9 [ U b 1 ~ / = } ! _ A @ # > V W X > < ", " 3 3 ( F h U U U U h h h h b b b b b 1 1 1 Y Y Y Y Y ~ ~ ~ ~ ~ 5 F : ; ; ", " l Z ` ` ...+.Z @.#.$.%.&.*.=.-.;.>.,.'.).!.!.~.~.{.].].^.n ", " l Z /./.` ....+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.(.(.~.{.]._.n ", " l ..:.<./.` ...+.Z @.#.$.%.&.*.=.-.;.>.>.'.'.).!.(.~.~._.n ", " l ..[.:.<./.` ...+.Z @.#.#.%.&.&.=.-.-.>.>.,.).).!.(.~.].f ", " l .}.[.:.<./.` ...+.Z @.#.$.%.&.*.=.-.;.>.>.'.'.).!.(.].f ", " B ` |.|.[.[.<././.[.1.2.2.3.3.4.5.5.6.7.#.;.;.>.,.'.).!.{.f ", " B /.8.8.|.}.[.:.<.9.j { 9 [ [ ] ] U U ( 7.=.-.;.>.,.'.).(.f ", " B <.0.8.8.}.}.[.<.a.{ b.1.c.d.e.7.f.g.h h.*.=.-.;.>.,.'.(.f ", " B :.i.j.0.8.|.}.[.k.8 5.l.3.5.6.h.b.m.U 9.&.*.=.-.;.>.>.!.f ", " B [.i.i.j.0.8.|.}.n.6 2.k.a.2.5.o.9.e.] 6.%.%.*.=.=.;.>.).f ", " t [.p.p.i.j.0.8.|.q.6 a.X n.a.3.5.o.d.] o.$.%.&.*.=.-.;.'.E ", " t }.g.r.p.i.j.0.0.X < n.s.t.q.a.l.3.m.[ 5.#.#.$.%.&.*.=.,.E ", " t |.g.g.r.p.i.i.0.X < X u.v.t.q.k.d./.b 4.Z @.#.$.%.&.*.,.E ", " t |.w.g.g.r.p.i.i.t.: x.W ' v.t.X 4.[.] 3.+.Z @.#.$.%.&.>.E ", " t 8.y.y.w.g.r.p.p.x.: u.V z.' v.x.X 4.8 2.+.+.Z @.#.$.%.;.E ", " t 0.A.y.y.w.g.g.r.s.; W B.C.D.W u.s.2.6 l. . .+.Z Z #.$.=.m ", " t 0.f.A.A.y.w.g.r.s.; z.@ B.C.D.W u.a.6 a.` ...+.Z @.#.=.m ", " t 8.g.g.r.p.p.i.j.t.+ u.D.z.' v.x.t.2.q 2...+.+.Z @.#.$.=.m ", " k U h h h h b b b ( v . + + ; : : : : H 7 ~ 5 5 5 / / / r | ", " ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/loc_add.xpm0000664000076400007640000003147512231073120015425 0ustar rmurphyrmurphy/* XPM */ static const char * loc_add_xpm[] = { "48 48 516 2", " c None", ". c #D78E46", "+ c #D98F46", "@ c #D78C46", "# c #EEB461", "$ c #EFB661", "% c #D98E45", "& c #5B5958", "* c #746C66", "= c #746D66", "- c #756D66", "; c #756E67", "> c #D88C48", ", c #F0AF5B", "' c #F9B13E", ") c #F9B740", "! c #F1B85E", "~ c #D88F48", "{ c #D1AD90", "] c #CBA381", "^ c #CEA583", "/ c #D6B396", "( c #756E68", "_ c #D68845", ": c #F0A85A", "< c #F8A73D", "[ c #F8A229", "} c #F9A92A", "| c #F9B641", "1 c #F0B75D", "2 c #D98E44", "3 c #736C65", "4 c #C79F7D", "5 c #BB885E", "6 c #BF8C61", "7 c #CEA685", "8 c #756D67", "9 c #D68745", "0 c #ECA15C", "a c #F89B39", "b c #F79726", "c c #F79B25", "d c #F8A227", "e c #F8A72A", "f c #F9B43F", "g c #EEB561", "h c #726B65", "i c #C39A79", "j c #B68358", "k c #BA885C", "l c #8B7562", "m c #D78746", "n c #EF9A56", "o c #F78F36", "p c #F78921", "q c #F78E22", "r c #F79323", "s c #F89A25", "t c #F89F27", "u c #F8A428", "v c #F9B33F", "w c #F1B65D", "x c #726A64", "y c #BE9775", "z c #B17F54", "A c #B58358", "B c #C59165", "C c #D58B50", "D c #EE9354", "E c #F68635", "F c #F57D1F", "G c #F6821F", "H c #F68720", "I c #F68D22", "J c #F79924", "K c #F79E26", "L c #F8A529", "M c #F9B341", "N c #F0B55D", "O c #716963", "P c #BB9371", "Q c #AC7A4F", "R c #B67E4E", "S c #D18347", "T c #EB8F57", "U c #F57A30", "V c #F5721C", "W c #F5761B", "X c #F57C1D", "Y c #F6811E", "Z c #F78D22", "` c #F79223", " . c #F79824", ".. c #F89E26", "+. c #F8A429", "@. c #EEB360", "#. c #706862", "$. c #B78E6D", "%. c #AF7647", "&. c #D78245", "*. c #ED8651", "=. c #F56E2D", "-. c #F46317", ";. c #F46919", ">. c #F46E1A", ",. c #F5751C", "'. c #F57A1D", "). c #F67F1E", "!. c #F68520", "~. c #F78A21", "{. c #F79023", "]. c #F89624", "^. c #F89C26", "/. c #F8A127", "(. c #F9B03E", "_. c #F1B35D", ":. c #D88E48", "<. c #6F6862", "[. c #BE8F67", "}. c #CE7E44", "|. c #ED7F4F", "1. c #F4652D", "2. c #F35816", "3. c #F35D15", "4. c #F36216", "5. c #F36818", "6. c #F4731B", "7. c #F5791D", "8. c #F6841F", "9. c #F68921", "0. c #F79022", "a. c #F79524", "b. c #F9AF40", "c. c #D98D44", "d. c #716052", "e. c #D3844D", "f. c #EA7F53", "g. c #F35A28", "h. c #F24E14", "i. c #F25113", "j. c #F35714", "k. c #F35C15", "l. c #F36116", "m. c #F46818", "n. c #F46D19", "o. c #F5791C", "p. c #F57E1E", "q. c #F6831F", "r. c #F68F22", "s. c #F79423", "t. c #F89B25", "u. c #F8A028", "v. c #F9AE3D", "w. c #EEB15F", "x. c #D67D44", "y. c #EC724C", "z. c #F24F26", "A. c #F1400F", "B. c #F24511", "C. c #F24A12", "D. c #F35013", "E. c #F35414", "F. c #F35915", "G. c #F46017", "H. c #F46518", "I. c #F46B19", "J. c #F5711B", "K. c #F5761C", "L. c #F68721", "M. c #F78C22", "N. c #F89825", "O. c #F89D26", "P. c #F9AD3D", "Q. c #F1B25C", "R. c #D57A43", "S. c #EB6D4B", "T. c #F14726", "U. c #F0370E", "V. c #F13B0D", "W. c #F13F0E", "X. c #F14410", "Y. c #F24A11", "Z. c #F24E12", "`. c #F25313", " + c #F35A15", ".+ c #F35F16", "++ c #F36417", "@+ c #F4701A", "#+ c #F4751C", "$+ c #F5811E", "%+ c #F68620", "&+ c #F78C21", "*+ c #F89724", "=+ c #F89F28", "-+ c #F8AD3F", ";+ c #F1B15C", ">+ c #D88E47", ",+ c #D57B44", "'+ c #E96F4F", ")+ c #F13D21", "!+ c #F02D0C", "~+ c #F0300B", "{+ c #F0350C", "]+ c #F13A0D", "^+ c #F13F0F", "/+ c #F24410", "(+ c #F24911", "_+ c #F35413", ":+ c #F35914", "<+ c #F35E16", "[+ c #F46417", "}+ c #F46A19", "|+ c #F46F1A", "1+ c #F57B1D", "2+ c #F6801F", "3+ c #F78B21", "4+ c #F79123", "5+ c #F79724", "6+ c #F89E27", "7+ c #F8AB3C", "8+ c #EEAF5F", "9+ c #D88F49", "0+ c #D67A43", "a+ c #EA6348", "b+ c #F0341F", "c+ c #EE2107", "d+ c #EF2508", "e+ c #EF2909", "f+ c #F02E0B", "g+ c #F0330C", "h+ c #F0370D", "i+ c #F13D0F", "j+ c #F14210", "k+ c #F14711", "l+ c #F24D12", "m+ c #F25614", "n+ c #F35D16", "o+ c #F36217", "p+ c #F36718", "q+ c #F5781C", "r+ c #F57F1E", "s+ c #F8AA3C", "t+ c #F0B05B", "u+ c #D47C47", "v+ c #EA5E47", "w+ c #EF2F1F", "x+ c #EE1B07", "y+ c #EE1D06", "z+ c #EE2007", "A+ c #EF2408", "B+ c #F02909", "C+ c #EF2D0A", "D+ c #F0320C", "E+ c #F1380D", "F+ c #F03C0E", "G+ c #F1410F", "H+ c #F24711", "I+ c #F24C12", "J+ c #F25013", "K+ c #F35614", "L+ c #F35B15", "M+ c #F36117", "N+ c #F46718", "O+ c #F4721B", "P+ c #F57E1D", "Q+ c #F68E22", "R+ c #F79424", "S+ c #F79B27", "T+ c #F8AA3E", "U+ c #F1B05B", "V+ c #D7904D", "W+ c #D47C48", "X+ c #E97159", "Y+ c #F4655C", "Z+ c #F35A50", "`+ c #F35B4E", " @ c #F35E4F", ".@ c #F36050", "+@ c #F36350", "@@ c #F46651", "#@ c #F46952", "$@ c #F46C53", "%@ c #F57054", "&@ c #F57354", "*@ c #F57655", "=@ c #F67A56", "-@ c #F57D57", ";@ c #F58158", ">@ c #F68559", ",@ c #F6885A", "'@ c #F78C5B", ")@ c #F7915C", "!@ c #F7945D", "~@ c #F7985E", "{@ c #F89C5F", "]@ c #F8A060", "^@ c #F9A461", "/@ c #F9A862", "(@ c #F9AB63", "_@ c #F9B064", ":@ c #F9B465", "<@ c #FAB968", "[@ c #FBC274", "}@ c #EEB36B", "|@ c #D7904E", "1@ c #CE834C", "2@ c #CF834C", "3@ c #D0834D", "4@ c #B97C4A", "5@ c #D49866", "6@ c #D39764", "7@ c #D39765", "8@ c #D49865", "9@ c #D59966", "0@ c #D59967", "a@ c #D69A68", "b@ c #D79B68", "c@ c #D79B69", "d@ c #D89C69", "e@ c #D89C6A", "f@ c #D99D6A", "g@ c #B97D4B", "h@ c #D38E51", "i@ c #D28D51", "j@ c #797979", "k@ c #E6E6E6", "l@ c #E2E2E2", "m@ c #E3E3E3", "n@ c #E4E4E4", "o@ c #E5E5E5", "p@ c #E7E7E7", "q@ c #E8E8E8", "r@ c #E9E9E9", "s@ c #EAEAEA", "t@ c #EBEBEB", "u@ c #ECECEC", "v@ c #EDEDED", "w@ c #EEEEEE", "x@ c #EFEFEF", "y@ c #F0F0F0", "z@ c #F1F1F1", "A@ c #F2F2F2", "B@ c #F3F3F3", "C@ c #F4F4F4", "D@ c #F6F6F6", "E@ c #F7F7F7", "F@ c #F8F8F8", "G@ c #FAFAFA", "H@ c #7D7D7D", "I@ c #E1E1E1", "J@ c #F5F5F5", "K@ c #F9F9F9", "L@ c #DFDFDF", "M@ c #E0E0E0", "N@ c #DEDEDE", "O@ c #7D7C7C", "P@ c #DDDDDD", "Q@ c #7C7C7C", "R@ c #787878", "S@ c #DCDCDC", "T@ c #C9C9C9", "U@ c #C1C1C1", "V@ c #C2C2C2", "W@ c #C3C3C3", "X@ c #C4C4C4", "Y@ c #C6C6C6", "Z@ c #D0D0D0", "`@ c #DBDBDB", " # c #C7C7C7", ".# c #83888A", "+# c #8E989D", "@# c #8F999E", "## c #8F9A9E", "$# c #909A9F", "%# c #909B9F", "&# c #919BA0", "*# c #919CA0", "=# c #929CA1", "-# c #878C8E", ";# c #DADADA", "># c #BFBFBF", ",# c #8D989C", "'# c #B3D0DC", ")# c #AFD0DD", "!# c #B0D1DF", "~# c #B2D3E0", "{# c #B4D4E2", "]# c #B6D6E4", "^# c #B7D7E5", "/# c #BEDBE7", "(# c #939CA1", "_# c #C8C8C8", ":# c #D8D8D8", "<# c #D9D9D9", "[# c #BEBEBE", "}# c #8C979B", "|# c #AACAD7", "1# c #A3C7D6", "2# c #A5C9D8", "3# c #A7CBDA", "4# c #A9CDDC", "5# c #ABCFDE", "6# c #ADD1E0", "7# c #B6D5E3", "8# c #929BA0", "9# c #BDBDBD", "0# c #8C969B", "a# c #A8C7D5", "b# c #A1C4D4", "c# c #A2C6D6", "d# c #A4C8D8", "e# c #A8CCDC", "f# c #AACEDE", "g# c #B5D4E1", "h# c #919B9F", "i# c #777777", "j# c #D7D7D7", "k# c #BCBCBC", "l# c #8B969A", "m# c #A6C5D3", "n# c #9EC2D2", "o# c #A0C3D4", "p# c #A4C9D8", "q# c #A6CBDA", "r# c #B3D2DF", "s# c #C5C5C5", "t# c #7B7B7B", "u# c #D5D5D5", "v# c #D6D6D6", "w# c #BBBBBB", "x# c #8A9499", "y# c #A4C2D0", "z# c #9BBFCF", "A# c #9DC0D0", "B# c #9FC2D2", "C# c #A2C5D5", "D# c #A3C7D7", "E# c #A5C9D9", "F# c #B8D4E0", "G# c #8A9498", "H# c #A1C1CE", "I# c #99BCCC", "J# c #9ABECE", "K# c #9FC2D3", "L# c #B5D1DE", "M# c #D3E4EB", "N# c #969EA1", "O# c #D4D4D4", "P# c #BABABA", "Q# c #899398", "R# c #A0BECC", "S# c #97BACA", "T# c #98BBCB", "U# c #9ABDCD", "V# c #9EC1D2", "W# c #A9C9D8", "X# c #D0E2E9", "Y# c #929B9E", "Z# c #D3D3D3", "`# c #B9B9B9", " $ c #899397", ".$ c #9DBCCA", "+$ c #94B7C7", "@$ c #96B9C9", "#$ c #9ABDCE", "$$ c #9CBFCF", "%$ c #9EC1D1", "&$ c #AACAD6", "*$ c #8D979B", "=$ c #D2D2D2", "-$ c #B8B8B8", ";$ c #889296", ">$ c #9BBAC7", ",$ c #91B5C4", "'$ c #93B6C6", ")$ c #95B8C8", "!$ c #97BBCB", "~$ c #9BBECE", "{$ c #A8C7D4", "]$ c #C0C0C0", "^$ c #7A7A7A", "/$ c #D1D1D1", "($ c #879296", "_$ c #9AB8C6", ":$ c #8FB3C2", "<$ c #95B9C9", "[$ c #A6C4D2", "}$ c #8B969B", "|$ c #879195", "1$ c #9FBCC8", "2$ c #98B9C6", "3$ c #9AB9C7", "4$ c #9BBBC9", "5$ c #9DBDCB", "6$ c #9FBECD", "7$ c #A0C0CF", "8$ c #AAC7D3", "9$ c #8B959A", "0$ c #696969", "a$ c #9A9A9A", "b$ c #9B9B9B", "c$ c #9C9C9C", "d$ c #8B8B8B", "e$ c #6D7274", "f$ c #859094", "g$ c #869196", "h$ c #889397", "i$ c #889398", "j$ c #889498", "k$ c #6F7476", "l$ c #8D8D8D", "m$ c #9F9F9F", "n$ c #A0A0A0", "o$ c #A1A1A1", "p$ c #A2A2A2", "q$ c #6B6B6B", " ", " ", " ", " ", " . + ", " @ # $ % ", " & * = - ; & > , ' ) ! ~ ", " * { ] ^ / ( _ : < [ } | 1 2 ", " 3 4 5 6 7 8 9 0 a b c d e f g 2 ", " h i j k ] l m n o p q r s t u v w ~ ", " x y z A B C D E F G H I r J K L M N 2 ", " O P Q R S T U V W X Y H Z ` ...+.' @.2 ", " #.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:. ", " <.[.}.|.1.2.3.4.5.>.6.7.).8.9.0.a.c [ b._.c. ", " d.e.f.g.h.i.j.k.l.m.n.6.o.p.q.~.r.s.t.u.v.w.c. ", " x.y.z.A.B.C.D.E.F.G.H.I.J.K.X G L.M.r N.O.P.Q.:. ", " R.S.T.U.V.W.X.Y.Z.`. +.+++I.@+#+X $+%+&+` *+=+-+;+>+ ", " ,+'+)+!+~+{+]+^+/+(+Z._+:+<+[+}+|+K.1+2+%+3+4+5+6+7+8+9+ ", " 0+a+b+c+d+e+f+g+h+i+j+k+l+i.m+n+o+p+>.6.q+r+8.9.r.a.s s+t+:. ", " u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+n.O+q+P+q.9.Q+R+S+T+U+V+ ", " W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@ ", " 1@2@3@4@5@6@7@7@7@8@5@5@5@9@9@0@0@0@a@a@a@b@b@c@c@c@d@d@e@e@e@f@g@h@i@i@ ", " j@k@l@l@m@n@o@k@p@q@r@s@t@u@v@w@x@y@z@A@B@C@C@D@D@E@F@F@G@H@ ", " j@k@I@I@l@n@n@o@p@p@q@r@s@t@u@v@w@x@y@z@A@B@C@J@J@D@E@F@K@H@ ", " j@n@L@M@I@l@m@n@o@k@p@q@r@s@t@u@v@w@x@y@y@A@A@B@C@J@D@D@K@H@ ", " j@n@N@L@M@I@l@m@n@o@k@p@q@q@s@t@t@v@w@w@y@y@z@B@B@C@J@D@F@O@ ", " j@m@P@N@L@M@I@l@m@n@o@k@p@q@r@s@t@u@v@w@x@y@y@A@A@B@C@J@F@Q@ ", " R@l@S@S@N@N@M@I@I@N@T@U@U@V@V@W@X@X@Y@Z@q@x@x@y@z@A@B@C@E@Q@ ", " R@I@`@`@S@P@N@L@M@ #.#+#@###$#%#&#*#=#-#Z@v@w@x@y@z@A@B@J@Q@ ", " R@M@;#`@`@P@P@N@M@>#,#'#)#!#~#{#]#^#/#(#_#u@v@w@x@y@z@A@J@Q@ ", " R@L@:#<#;#`@S@P@N@[#}#|#1#2#3#4#5#6#7#8# #t@u@v@w@x@y@y@C@Q@ ", " R@N@:#:#<#;#`@S@P@9#0#a#b#c#d#3#e#f#g#h#Y@s@s@u@v@v@x@y@B@Q@ ", " i#N@j#j#:#<#;#`@S@k#l#m#n#o#c#p#q#e#r#%#s#r@s@t@u@v@w@x@A@t# ", " i#P@u#v#j#:#<#;#;#w#x#y#z#A#B#C#D#E#F###X@q@q@r@s@t@u@v@z@t# ", " i#S@u#u#v#j#:#:#;#w#G#H#I#J#A#K#b#L#M#N#W@k@p@q@r@s@t@u@z@t# ", " i#S@O#u#u#v#j#:#:#P#Q#R#S#T#U#A#V#W#X#Y#V@o@k@p@q@r@s@t@y@t# ", " i#`@Z#Z#O#u#v#j#j#`# $.$+$@$T##$$$%$&$*$U@o@o@k@p@q@r@s@x@t# ", " i#;#=$Z#Z#O#u#u#v#-$;$>$,$'$)$!$I#~${$0#]$m@m@o@k@k@q@r@v@^$ ", " i#;#/$=$=$Z#O#u#v#-$($_$:$,$'$<$S#I#[$}$>#l@m@n@o@k@p@q@v@^$ ", " i#`@u#u#v#j#j#:#<#P#|$1$2$3$4$5$6$7$8$9$U@n@o@o@k@p@q@r@v@^$ ", " 0$a$b$b$b$b$c$c$c$d$e$f$g$g$($h$i$j$Q#k$l$m$n$n$n$o$o$o$p$q$ ", " ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/loadcertwiz.h0000664000076400007640000000505112231073120016001 0ustar rmurphyrmurphy/*************************************************************************** loadcertwiz.h - description ------------------- begin : Wed Aug 6 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #ifndef __loadcertwiz_h #define __loadcertwiz_h #include "extwizard.h" class LCW_Page; class notifyData; class LoadCertWiz : public ExtWizard { public: LoadCertWiz(wxWindow *parent, wxHtmlHelpController *help = 0, const wxString& title = wxEmptyString); ~LoadCertWiz(); LCW_Page *GetCurrentPage() { return (LCW_Page *)wxWizard::GetCurrentPage(); } bool RunWizard(); void ResetNotifyData(); notifyData *GetNotifyData() { return _nd; } wxWindow *Parent() { return _parent; } LCW_Page *Final() { return _final; } LCW_Page *P12PW() { return _p12pw; } private: LCW_Page *_first; LCW_Page *_final; LCW_Page *_p12pw; class notifyData *_nd; wxWindow *_parent; }; class LCW_Page : public ExtWizard_Page { public: LCW_Page(LoadCertWiz *parent) : ExtWizard_Page(parent) {} LoadCertWiz *Parent() { return (LoadCertWiz *)_parent; } }; class LCW_P12PasswordPage : public LCW_Page { public: LCW_P12PasswordPage(LoadCertWiz *parent); virtual bool TransferDataFromWindow(); wxString GetPassword() const; void SetFilename(const wxString& filename) { _filename = filename; } private: wxTextCtrl *_pwin; wxString _filename; wxStaticText *tc_status; }; class LCW_FinalPage : public LCW_Page { public: LCW_FinalPage(LoadCertWiz *parent); virtual void refresh(); private: wxTextCtrl *tc_status; }; class notifyData { public: struct counts { int loaded, error, duplicate; }; struct counts root, ca, user, pkey, config; wxString status; notifyData() { root.loaded = root.error = root.duplicate = 0; ca.loaded = ca.error = ca.duplicate = 0; user.loaded = user.error = user.duplicate = 0; pkey.loaded = pkey.error = pkey.duplicate = 0; config.loaded = config.error = config.duplicate = 0; status = wxT(""); } wxString Message() const; }; inline bool LoadCertWiz::RunWizard() { return wxWizard::RunWizard(_first); } inline void LoadCertWiz::ResetNotifyData() { if (_nd) delete _nd; _nd = new notifyData; } inline LoadCertWiz::~LoadCertWiz() { if (_nd) delete _nd; } int notifyImport(int type, const char *message, void *); #endif // __loadcertwiz_h tqsl-2.0/apps/loadcertwiz.cpp0000664000076400007640000002553712231073120016347 0ustar rmurphyrmurphy/*************************************************************************** loadcertwiz.cpp - description ------------------- begin : Wed Aug 6 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "loadcertwiz.h" #include "getpassword.h" #include "tqslctrls.h" #include "tqsllib.h" #include "tqslerrno.h" #include "tqslapp.h" #include "tqsltrace.h" wxString notifyData::Message() const { if (diagFile) { fprintf(diagFile, "%s\n" "Root Certificates:\t\tLoaded: %d Duplicate: %d Error: %d\n" "CA Certificates:\t\tLoaded: %d Duplicate: %d Error: %d\n" "Callsign Certificates:\tLoaded: %d Duplicate: %d Error: %d\n" "Private Keys:\t\t\tLoaded: %d Duplicate: %d Error: %d\n" "Configuration Data:\tLoaded: %d Duplicate: %d Error: %d\n", _S(status), root.loaded, root.duplicate, root.error, ca.loaded, ca.duplicate, ca.error, user.loaded, user.duplicate, user.error, pkey.loaded, pkey.duplicate, pkey.error, config.loaded, config.duplicate, config.error); } if (status.IsEmpty()) return wxString(wxT("\nImport completed successfully")); return status; } int notifyImport(int type, const char *message, void *data) { tqslTrace("notifyImport", "type=%d, message=%s, data=0x%lx", type, message, (void *)data); if (TQSL_CERT_CB_RESULT_TYPE(type) == TQSL_CERT_CB_PROMPT) { const char *nametype = 0; const char *configkey = 0; bool default_prompt = false; switch (TQSL_CERT_CB_CERT_TYPE(type)) { case TQSL_CERT_CB_ROOT: nametype = "Trusted root"; configkey = "NotifyRoot"; //default_prompt = true; break; case TQSL_CERT_CB_CA: nametype = "Certificate Authority"; configkey = "NotifyCA"; break; case TQSL_CERT_CB_USER: nametype = "Callsign"; configkey = "NotifyUser"; break; } if (!nametype) return 0; wxConfig *config = (wxConfig *)wxConfig::Get(); bool b; config->Read(wxString(configkey, wxConvLocal), &b, default_prompt); if (!b) return 0; wxString s(wxT("Okay to install ")); s = s + wxString(nametype, wxConvLocal) + wxT(" certificate?\n\n") + wxString(message, wxConvLocal); if (wxMessageBox(s, wxT("Install Certificate"), wxYES_NO) == wxYES) return 0; return 1; } // end TQSL_CERT_CB_PROMPT if (TQSL_CERT_CB_CALL_TYPE(type) == TQSL_CERT_CB_RESULT && data) { // Keep count notifyData *nd = (notifyData *)data; notifyData::counts *counts = 0; switch (TQSL_CERT_CB_CERT_TYPE(type)) { case TQSL_CERT_CB_ROOT: counts = &(nd->root); break; case TQSL_CERT_CB_CA: counts = &(nd->ca); break; case TQSL_CERT_CB_USER: counts = &(nd->user); break; case TQSL_CERT_CB_PKEY: counts = &(nd->pkey); break; case TQSL_CERT_CB_CONFIG: counts = &(nd->config); break; } if (counts) { switch (TQSL_CERT_CB_RESULT_TYPE(type)) { case TQSL_CERT_CB_DUPLICATE: if (TQSL_CERT_CB_CERT_TYPE(type) == TQSL_CERT_CB_USER) { if (message) { nd->status = nd->status + wxString(message, wxConvLocal) + wxT("\n"); } else { nd->status = nd->status + wxT("This callsign certificate is already installed"); } } counts->duplicate++; break; case TQSL_CERT_CB_ERROR: if (message) nd->status = nd->status + wxString(message, wxConvLocal) + wxT("\n"); counts->error++; // wxMessageBox(wxString(message, wxConvLocal), wxT("Error")); break; case TQSL_CERT_CB_LOADED: if (TQSL_CERT_CB_CERT_TYPE(type) == TQSL_CERT_CB_USER) nd->status = nd->status + wxString("Callsign Certificate ", wxConvLocal) + wxString(message, wxConvLocal) + wxT("\n"); counts->loaded++; break; } } } if (TQSL_CERT_CB_RESULT_TYPE(type) == TQSL_CERT_CB_ERROR) return 1; // Errors get posted later if (TQSL_CERT_CB_CALL_TYPE(type) == TQSL_CERT_CB_RESULT || TQSL_CERT_CB_RESULT_TYPE(type) == TQSL_CERT_CB_DUPLICATE) { // wxMessageBox(message, "Certificate Notice"); return 0; } return 1; } static wxHtmlHelpController *pw_help = 0; static wxString pw_helpfile; static int GetNewPassword(char *buf, int bufsiz, void *) { tqslTrace("GetNewPassword"); GetNewPasswordDialog dial(0, wxT("New Password"), wxT("Enter a password for this callsign certificate.\n\n") wxT("If you are using a computer system that is\n") wxT("shared with others, you should specify a\n") wxT("password to protect this certificate. However, if\n") wxT("you are using a computer in a private residence\n") wxT("no password need be specified.\n\n") wxT("This password will have to be entered each time\n") wxT("you use this callsign certificate for signing or\n") wxT("when saving the key.\n\n") wxT("Leave the password blank and click 'Ok' unless you want\n") wxT("to use a password.\n\n"), true, pw_help, pw_helpfile); if (dial.ShowModal() == wxID_OK) { strncpy(buf, dial.Password().mb_str(), bufsiz); buf[bufsiz-1] = 0; return 0; } return 1; } static void export_new_cert(ExtWizard *_parent, const char *filename) { tqslTrace("export_new_cert", "_parent=0x%lx, filename=%s", _parent, filename); long newserial; if (!tqsl_getSerialFromTQSLFile(filename, &newserial)) { MyFrame *frame = (MyFrame *)(((LoadCertWiz *)_parent)->Parent()); TQ_WXCOOKIE cookie; int nproviders = frame->cert_tree->GetNumIssuers(); // Number of certificate issuers - currently 1 wxTreeItemId root = frame->cert_tree->GetRootItem(); wxTreeItemId item, prov; if (nproviders > 1) { prov = frame->cert_tree->GetFirstChild(root, cookie); // First child is the providers item = frame->cert_tree->GetFirstChild(prov, cookie);// Then it's certs } else { item = frame->cert_tree->GetFirstChild(root, cookie); // First child is the certs } while (item.IsOk()) { tQSL_Cert cert; CertTreeItemData *id = frame->cert_tree->GetItemData(item); if (id && (cert = id->getCert())) { long serial; if (!tqsl_getCertificateSerial(cert, &serial)) { if (serial == newserial) { wxCommandEvent e; if (wxMessageBox( wxT("You will not be able to use this tq6 file to recover your\n") wxT("callsign certificate if it gets lost. For security purposes, you should\n") wxT("back up your certificate on removable media for safe-keeping.\n\n") wxT("Would you like to back up your callsign certificate now?"), wxT("Warning"), wxYES_NO|wxICON_QUESTION, _parent) == wxNO) { return; } frame->cert_tree->SelectItem(item); frame->OnCertExport(e); break; } } } if (nproviders > 1) { item = frame->cert_tree->GetNextChild(prov, cookie); } else { item = frame->cert_tree->GetNextChild(root, cookie); } } } } LoadCertWiz::LoadCertWiz(wxWindow *parent, wxHtmlHelpController *help, const wxString& title) : ExtWizard(parent, help, title), _nd(0) { tqslTrace("LoadCertWiz::LoadCertWiz", "parent=0x%lx, title=%s", (void *)parent, _S(title)); LCW_FinalPage *final = new LCW_FinalPage(this); LCW_P12PasswordPage *p12pw = new LCW_P12PasswordPage(this); wxWizardPageSimple::Chain(p12pw, final); _first = p12pw; _parent = parent; _final = final; _p12pw = p12pw; wxConfig *config = (wxConfig *)wxConfig::Get(); wxString ext(wxT("p12")); wxString wild(wxT("Callsign Certificate container files (*.p12)|*.p12|Certificate Request response files (*.tq6)|*.tq6")); wild += wxT("|All files (*.*)|*.*"); wxString path = config->Read(wxT("CertFilePath"), wxT("")); wxString filename = wxFileSelector(wxT("Select Certificate File"), path, wxT(""), ext, wild, wxOPEN|wxFILE_MUST_EXIST); if (filename == wxT("")) { // Cancelled! _first = 0; } else { ResetNotifyData(); wxString path, basename, ext; wxSplitPath(filename, &path, &basename, &ext); config->Write(wxT("CertFilePath"), path); if (ext.MakeLower() == wxT("tq6")) { _first = _final; _final->SetPrev(0); if (tqsl_importTQSLFile(filename.mb_str(), notifyImport, GetNotifyData())) wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), wxT("Error")); else { if (tQSL_ImportCall[0] != '\0') { wxString call = wxString(tQSL_ImportCall, wxConvLocal); wxString pending = config->Read(wxT("RequestPending")); pending.Replace(call, wxT(""), true); if (pending[0] == ',') pending.Replace(wxT(","), wxT("")); if (pending.Last() == ',') pending.Truncate(pending.Len()-1); config->Write(wxT("RequestPending"), pending); } export_new_cert(this, filename.mb_str()); } } else { // First try with no password if (!tqsl_importPKCS12File(filename.mb_str(), "", 0, GetNewPassword, notifyImport, GetNotifyData())) { _first = _final; _final->SetPrev(0); } else { _first=_p12pw; _p12pw->SetPrev(0); p12pw->SetFilename(filename); } } } AdjustSize(); CenterOnParent(); } LCW_FinalPage::LCW_FinalPage(LoadCertWiz *parent) : LCW_Page(parent) { tqslTrace("LCW_FinalPage::LCW_FinalPage", "parent=0x%lx", (void *)parent); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("Loading complete")); sizer->Add(st, 0, wxALL, 10); wxSize tsize = getTextSize(this); tc_status = new wxTextCtrl(this, -1, wxT(""),wxDefaultPosition, tsize.Scale(40, 16), wxTE_MULTILINE|wxTE_READONLY); sizer->Add(tc_status, 1, wxALL|wxEXPAND, 10); AdjustPage(sizer); } void LCW_FinalPage::refresh() { tqslTrace("LCW_FinalPage::refresh"); const notifyData *nd = ((LoadCertWiz *)_parent)->GetNotifyData(); if (nd) tc_status->SetValue(nd->Message()); else tc_status->SetValue(wxT("No status information available")); } LCW_P12PasswordPage::LCW_P12PasswordPage(LoadCertWiz *parent) : LCW_Page(parent) { tqslTrace("LCW_P12PasswordPage::LCW_P12PasswordPage", "parent=0x%lx", (void *)parent); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("Enter the password to unlock the .p12 file:")); sizer->Add(st, 0, wxALL, 10); _pwin = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); sizer->Add(_pwin, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); tc_status = new wxStaticText(this, -1, wxT("")); sizer->Add(tc_status, 0, wxALL, 10); AdjustPage(sizer, wxT("lcf1.htm")); } bool LCW_P12PasswordPage::TransferDataFromWindow() { tqslTrace("LCW_P12PasswordPage::TransferDataFromWindow"); wxString _pw = _pwin->GetValue(); pw_help = Parent()->GetHelp(); pw_helpfile = wxT("lcf2.htm"); if (tqsl_importPKCS12File(_filename.mb_str(), _pw.mb_str(), 0, GetNewPassword, notifyImport, ((LoadCertWiz *)_parent)->GetNotifyData())) { if (tQSL_Error == TQSL_PASSWORD_ERROR) { tc_status->SetLabel(wxT("Password error")); return false; } else wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), wxT("Error")); } tc_status->SetLabel(wxT("")); return true; } tqsl-2.0/apps/left.xpm0000664000076400007640000000116512231073120014763 0ustar rmurphyrmurphy/* XPM */ static const char *left_xpm[]={ "10 10 29 1", ". c None", "d c #000000", "h c #020202", "y c #050505", "k c #070707", "v c #0d0d0d", "n c #111111", "s c #171617", "p c #212021", "c c #323132", "g c #474647", "x c #595859", "j c #5d5b5d", "u c #696869", "m c #727172", "r c #797779", "# c #8a888a", "o c #8b898b", "e c #939193", "b c #9e9b9e", "a c #9f9d9f", "A c #a6a4a6", "z c #adabad", "f c #aeabae", "w c #b7b4b7", "i c #bab7ba", "t c #bdbabd", "l c #c1bec1", "q c #c3c0c3", "........#.", "......bcd.", "....fghdd.", "..ijkdddd.", "lmndddddd.", ".opdddddd.", "..qrsdddd.", "....tuvdd.", "......wxy.", "........z."}; tqsl-2.0/apps/key.xpm0000664000076400007640000000427112231073120014622 0ustar rmurphyrmurphy/* XPM */ static const char * key_xpm[] = { "16 16 100 2", " c None", ". c #090902", "+ c #0E0A03", "@ c #000000", "# c #000100", "$ c #020202", "% c #010102", "& c #F5F563", "* c #F9F256", "= c #A79B37", "- c #9E9E3C", "; c #9F9A38", "> c #A1972E", ", c #33310B", "' c #000003", ") c #FBEF4C", "! c #FFFF61", "~ c #FDF251", "{ c #CCB439", "] c #C7C13D", "^ c #080702", "/ c #E7E050", "( c #FDFA50", "_ c #FFFF64", ": c #E6DE4C", "< c #C9A530", "[ c #AEA161", "} c #C5C13D", "| c #67682D", "1 c #ECE650", "2 c #DFD642", "3 c #EDDC47", "4 c #E3D742", "5 c #CDB332", "6 c #90902B", "7 c #C6C057", "8 c #CFBD59", "9 c #D7CE46", "0 c #D7D344", "a c #E1CB49", "b c #FFFF60", "c c #EAD848", "d c #AA8D2E", "e c #3C381E", "f c #FFFF7A", "g c #FFFF6F", "h c #E7DE50", "i c #ECEA52", "j c #DCD74D", "k c #F7E75A", "l c #FFFF68", "m c #E1D755", "n c #939241", "o c #FFFD6C", "p c #F8F26A", "q c #F8F46B", "r c #E0CD56", "s c #CBC356", "t c #A09445", "u c #D8C056", "v c #88863B", "w c #090906", "x c #9A913C", "y c #FFFF70", "z c #F0ED6D", "A c #A68F3F", "B c #544026", "C c #131010", "D c #050508", "E c #06070A", "F c #0B0A0A", "G c #0A0A05", "H c #867E36", "I c #ECEA6A", "J c #E9DE65", "K c #232017", "L c #1A1812", "M c #2E2D11", "N c #ECE166", "O c #FFFF76", "P c #EDE368", "Q c #282316", "R c #989543", "S c #FFFF78", "T c #E5DF65", "U c #232014", "V c #0C0D07", "W c #6B5825", "X c #FFFE73", "Y c #DED162", "Z c #1C190F", "` c #A49D48", " . c #FFFF77", ".. c #D5CB58", "+. c #140F0C", "@. c #040302", "#. c #D3D161", "$. c #BFB356", "%. c #0D080A", "&. c #070605", " . + @ # $ ", " % & * = - ; > , ", " ' ) ! ~ { ] ^ ", " @ / ( _ : < [ } @ ", " | 1 2 3 ! 4 5 6 ", " @ 7 8 9 0 a b c d @ ", " e f g h i j k l m ^ ", " n o p q r s t u v w ", " @ x y z A B C D E F ", " G H I J K L @ ", " M N O P Q @ ", " @ R S T U ", " V W X Y Z ", "@ ` ...+. ", "@.#.$.%. ", " w &. "}; tqsl-2.0/apps/key.ico0000664000076400007640000000706612231073120014575 0ustar rmurphyrmurphy &h( @*VRrvn>R.*nf2&>JjFz2z޺Vzb*&F fZNNB.6JFF^Njj.NVNBJ~~ZBBB~VN*F>^^^:VJj&N~*6*jFJ~zJ&::fF2>Fnn~::J.B^J>>>NN^RFFbN:>:bV6>VnzRR:V*ھRRZZ:JVºFn~>Jb2*."BNB^J6VVb>BVJR2JBfnF:>JJRZ^JBJzNrBJ2266:JFVb.bJNvBB 22NrvvJFR.:2N:6*FNbbVJFBF>FJF2RJ:VJNFvzJfB:>F FZFBFbjRJnnN>N""..F>>RFFVVZZbbJB**BNJNNJFʔPLO 7:Qf%ŧuоj%D@7~n^تb\o[a˖FJ.krcPΜ#_zb̘Bl!{TIAG4${0 v ;i,h#UwNΝem5} :j5b0 '3Z8*=mm/HXAW9MS +R])0-ppJM K(@2>>8]<_/.B(Y`X tqsl-2.0/apps/key-new.xpm0000664000076400007640000000503112231073120015404 0ustar rmurphyrmurphy/* XPM */ static const char * key_xpm[] = { "16 16 122 2", " c None", ". c #670003", "+ c #650003", "@ c #5C0202", "# c #6F0001", "$ c #DBBB83", "% c #C2A774", "& c #AC936C", "* c #B09772", "= c #8D7356", "- c #C2A67C", "; c #640002", "> c #950004", ", c #7E0001", "' c #810306", ") c #C7A873", "! c #D1B17A", "~ c #B79865", "{ c #AA936B", "] c #C2A67E", "^ c #840003", "/ c #6E0002", "( c #500000", "_ c #980307", ": c #B8966A", "< c #BCA371", "[ c #B6996D", "} c #AF966C", "| c #786A52", "1 c #A18C6B", "2 c #7C0002", "3 c #7E0002", "4 c #6A0003", "5 c #950102", "6 c #988262", "7 c #C3A56C", "8 c #A4885F", "9 c #BEA070", "0 c #C1A36F", "a c #A89063", "b c #BDA378", "c c #7D6F58", "d c #920104", "e c #850304", "f c #3C0000", "g c #A28258", "h c #BB8C5A", "i c #BAA06D", "j c #A58A60", "k c #C3A677", "l c #AB9165", "m c #796850", "n c #430002", "o c #7D0002", "p c #830203", "q c #71493B", "r c #8C291E", "s c #8B3123", "t c #A0412C", "u c #AB9468", "v c #AE8F64", "w c #BFA370", "x c #D7B57B", "y c #B2976C", "z c #4F0000", "A c #813C32", "B c #8E3128", "C c #8C1D16", "D c #BC9F6C", "E c #A16F4C", "F c #BFA06E", "G c #A48960", "H c #8C7558", "I c #B7986A", "J c #90795B", "K c #CBBE93", "L c #B96D55", "M c #830000", "N c #980D0A", "O c #A25B40", "P c #605642", "Q c #CAAB7F", "R c #CDB18B", "S c #B5996B", "T c #976446", "U c #6B0104", "V c #810000", "W c #B69E73", "X c #BFA57F", "Y c #A38E61", "Z c #BC5E3D", "` c #653329", " . c #530606", ".. c #7F0406", "+. c #740305", "@. c #590002", "#. c #AC9068", "$. c #BBA17A", "%. c #9E8156", "&. c #C0A170", "*. c #502C26", "=. c #3F0000", "-. c #510303", ";. c #8C0002", ">. c #9F845F", ",. c #AE976F", "'. c #987D53", "). c #B59462", "!. c #6C0002", "~. c #907858", "{. c #A68E6B", "]. c #90754C", "^. c #B39466", "/. c #7F0003", "(. c #A5906D", "_. c #8E7247", ":. c #B19164", "<. c #8B0003", "[. c #7B6647", "}. c #9B7F55", "|. c #420002", "1. c #510002", " ", " . + @ # $ % & * = - ", " ; > , ' ) ! ~ { ] ", " ^ / ( _ : < [ } | 1 ", " 2 3 4 5 6 7 8 9 0 a b c ", " d e f g h i j 9 k l m ", " n o p q r s t u v w x y ", " z A B C D E F G H I J ", " K L M N O P ", " Q R S T U V ", " W X Y Z ` ... +.@. ", " #.$.%.&.*.=.-. ;./ ", " >.,.'.). ^ !. ", " ~.{.].^. /.+ ", " (._.:. <.3 ", " [.}. |.1. "}; tqsl-2.0/apps/import.xpm0000664000076400007640000003007412231073120015344 0ustar rmurphyrmurphy/* XPM */ static const char * import_xpm[] = { "48 48 468 2", " c None", ". c #B9B9B9", "+ c #C2C2C2", "@ c #C7C7C7", "# c #CACACA", "$ c #C8C8C8", "% c #B8B8B8", "& c #CFCFCF", "* c #D1D1D1", "= c #D2D2D2", "- c #D4D4D4", "; c #A2A2A2", "> c #C1C1C1", ", c #D7D7D7", "' c #E2E2E2", ") c #DEDEDE", "! c #DCDCDC", "~ c #D8D8D8", "{ c #D6D6D6", "] c #CECECE", "^ c #B3B3B3", "/ c #A4A4A4", "( c #C5C5C5", "_ c #D0D0D0", ": c #B0B0B0", "< c #ABABAB", "[ c #C9C9C9", "} c #DFDFDF", "| c #E9E9E9", "1 c #EBEBEB", "2 c #D9D9D9", "3 c #DADADA", "4 c #9C9C9C", "5 c #C3C3C3", "6 c #BFBFBF", "7 c #9A9A9A", "8 c #E7E7E7", "9 c #E8E8E8", "0 c #DDDDDD", "a c #DBDBDB", "b c #BABABA", "c c #CBCBCB", "d c #A5A5A5", "e c #ADADAD", "f c #E6E6E6", "g c #EAEAEA", "h c #C4C4C4", "i c #A6A6A6", "j c #989898", "k c #E4E4E4", "l c #E5E5E5", "m c #B1B2B1", "n c #848584", "o c #BABBBA", "p c #C8C9C8", "q c #B7B7B7", "r c #D5D5D5", "s c #C6C6C6", "t c #9D9D9D", "u c #E3E3E3", "v c #E0E0E0", "w c #7E7F7D", "x c #B2B3B2", "y c #BBBBBB", "z c #C0C1C0", "A c #C3C4C3", "B c #CCCCCC", "C c #C0C0C0", "D c #B2B2B2", "E c #DBDBDC", "F c #CFD0CF", "G c #BDBEBD", "H c #CCCDCC", "I c #E8E9E8", "J c #ECEDEC", "K c #F3F3F3", "L c #F2F2F2", "M c #F4F5F4", "N c #F0F0F0", "O c #F8F8F8", "P c #D3D3D3", "Q c #959595", "R c #E1E1E1", "S c #C0C0BF", "T c #707270", "U c #B5B6B5", "V c #CACBCA", "W c #D0D1D0", "X c #D2D3D2", "Y c #D7D8D7", "Z c #DBDCDB", "` c #E7E8E7", " . c #EEEEEE", ".. c #F1F1F1", "+. c #CDCDCD", "@. c #DCDDDC", "#. c #DEDFDE", "$. c #E3E4E3", "%. c #E6E7E6", "&. c #ECECEC", "*. c #EDEDED", "=. c #EFEFEF", "-. c #F5F5F5", ";. c #F7F7F7", ">. c #F8F9F8", ",. c #FAFAFA", "'. c #FCFCFC", "). c #FDFDFD", "!. c #FFFFFF", "~. c #7B7D7B", "{. c #999A99", "]. c #BFC0BF", "^. c #C5C6C5", "/. c #C9CAC9", "(. c #CBCCCB", "_. c #CDCECD", ":. c #D5D6D5", "<. c #D9DAD9", "[. c #EFF0EF", "}. c #999999", "|. c #D9D8D9", "1. c #DAD9DA", "2. c #E6E8E6", "3. c #E6E9E6", "4. c #E7EAE7", "5. c #E9EBE9", "6. c #EAECEA", "7. c #A9A9A9", "8. c #DDE0DD", "9. c #E0E1E0", "0. c #E8E3E8", "a. c #EEE5EE", "b. c #F2E6F2", "c. c #F3E7F3", "d. c #F3E8F3", "e. c #F0E9F0", "f. c #EAE8EA", "g. c #E8EAE8", "h. c #F4F4F4", "i. c #8B8B8B", "j. c #DFDEDF", "k. c #DDDFDD", "l. c #E2E1E2", "m. c #EDE2ED", "n. c #E4E1E4", "o. c #C4DDC4", "p. c #A1D8A1", "q. c #8CD58C", "r. c #89D589", "s. c #99D999", "t. c #B9E0B9", "u. c #E1E8E1", "v. c #F9EDF9", "w. c #F6EFF6", "x. c #EFF1EF", "y. c #D6D7D6", "z. c #A0A0A0", "A. c #ACACAC", "B. c #AEAEAE", "C. c #ADB0AD", "D. c #BDB0BD", "E. c #AAB1AA", "F. c #74C374", "G. c #31C731", "H. c #05BF05", "I. c #00BD00", "J. c #00BC00", "K. c #00BE00", "L. c #1AC41A", "M. c #5ECE5E", "N. c #9EC19E", "O. c #C5B5C5", "P. c #AAAAAA", "Q. c #9F9F9F", "R. c #00B700", "S. c #00BB00", "T. c #01BF01", "U. c #02BF02", "V. c #00B800", "W. c #00B500", "X. c #A7A7A7", "Y. c #A8A8A8", "Z. c #05BC04", "`. c #02BC02", " + c #02BD02", ".+ c #03BD03", "++ c #02BE02", "@+ c #03BF03", "#+ c #01BE01", "$+ c #02C002", "%+ c #03B502", "&+ c #03B602", "*+ c #03B702", "=+ c #02B701", "-+ c #02B801", ";+ c #02B901", ">+ c #01B901", ",+ c #00B600", "'+ c #01BB00", ")+ c #A3A3A3", "!+ c #BDBDBD", "~+ c #05B104", "{+ c #05B204", "]+ c #05B303", "^+ c #04B303", "/+ c #05B403", "(+ c #02B401", "_+ c #0CB70B", ":+ c #84DA84", "<+ c #A0E39F", "[+ c #48CA48", "}+ c #00B400", "|+ c #05B804", "1+ c #01BA01", "2+ c #8F8F8F", "3+ c #939393", "4+ c #08AC06", "5+ c #07AD06", "6+ c #07AD05", "7+ c #07AE05", "8+ c #06AF05", "9+ c #07AF05", "0+ c #03AF01", "a+ c #14B513", "b+ c #E5F7E5", "c+ c #7FD77E", "d+ c #00AD00", "e+ c #08B407", "f+ c #04B403", "g+ c #04B503", "h+ c #0AA807", "i+ c #09A807", "j+ c #09A907", "k+ c #09AA06", "l+ c #09AB07", "m+ c #05AA03", "n+ c #15B014", "o+ c #E0F3DF", "p+ c #7CD37B", "q+ c #00A900", "r+ c #0AAF08", "s+ c #06B004", "t+ c #06B104", "u+ c #0CA309", "v+ c #0CA409", "w+ c #0BA408", "x+ c #0DA50A", "y+ c #0DA60B", "z+ c #0AA608", "A+ c #0BA709", "B+ c #07A605", "C+ c #18AC15", "D+ c #E3F3E3", "E+ c #7ED17D", "F+ c #00A400", "G+ c #0CAB0A", "H+ c #08AA06", "I+ c #0BAC09", "J+ c #0E9E0B", "K+ c #0E9F0B", "L+ c #0D9F0A", "M+ c #0EA00B", "N+ c #079E04", "O+ c #039D01", "P+ c #0FA20C", "Q+ c #0DA20A", "R+ c #09A106", "S+ c #19A817", "T+ c #7FCF7E", "U+ c #009F00", "V+ c #0EA60B", "W+ c #0CA70A", "X+ c #08A506", "Y+ c #00A200", "Z+ c #09A707", "`+ c #109A0C", " @ c #119C0D", ".@ c #089904", "+@ c #3DAD3A", "@@ c #5DBB5B", "#@ c #009700", "$@ c #119F0E", "%@ c #0C9D09", "&@ c #1BA418", "*@ c #E3F2E3", "=@ c #80CD7F", "-@ c #009A00", ";@ c #14A411", ">@ c #029D00", ",@ c #21AA1F", "'@ c #6FC96E", ")@ c #0DA30A", "!@ c #0BA308", "~@ c #0BA508", "{@ c #12950E", "]@ c #12960E", "^@ c #11960D", "/@ c #149810", "(@ c #CDE4CC", "_@ c #FFFBFF", ":@ c #75C273", "<@ c #049400", "[@ c #0E990B", "}@ c #1EA01B", "|@ c #81CA7F", "1@ c #049700", "2@ c #069904", "3@ c #2AA827", "4@ c #D1ECD0", "5@ c #67C265", "6@ c #019A00", "7@ c #10A10D", "8@ c #0DA00A", "9@ c #149110", "0@ c #14910F", "a@ c #14920F", "b@ c #159311", "c@ c #0C9008", "d@ c #5FB35C", "e@ c #F9F6F9", "f@ c #91CC8F", "g@ c #079003", "h@ c #1E9B19", "i@ c #E5F2E5", "j@ c #85C983", "k@ c #008B00", "l@ c #45AF42", "m@ c #E4F3E4", "n@ c #C4E6C3", "o@ c #1C9F19", "p@ c #0E9A0A", "q@ c #109B0D", "r@ c #0F9C0C", "s@ c #168D11", "t@ c #168E11", "u@ c #178F12", "v@ c #068800", "w@ c #7ABD77", "x@ c #FFFDFF", "y@ c #A7D4A5", "z@ c #21971D", "A@ c #E1F0E0", "B@ c #78C076", "C@ c #4EAE4B", "D@ c #F7FBF7", "E@ c #DDF0DD", "F@ c #259D21", "G@ c #0A9205", "H@ c #14970F", "I@ c #11970D", "J@ c #11980D", "K@ c #188813", "L@ c #188912", "M@ c #188A12", "N@ c #1A8B14", "O@ c #0B8505", "P@ c #99C997", "Q@ c #C7E3C6", "R@ c #E9F3E8", "S@ c #D2E8D1", "T@ c #F1F8F1", "U@ c #F0F7EF", "V@ c #3CA338", "W@ c #0A8C05", "X@ c #179313", "Y@ c #13930F", "Z@ c #1A8414", "`@ c #1A8514", " # c #1A8614", ".# c #198613", "+# c #14840E", "@# c #B6D7B4", "## c #FBFCFB", "$# c #FEFEFE", "%# c #FCFDFC", "&# c #57AB53", "*# c #098504", "=# c #1A8E15", "-# c #168D10", ";# c #168E10", "># c #158F10", ",# c #1C8016", "'# c #1C8015", ")# c #1C8115", "!# c #1B8115", "~# c #1D8316", "{# c #188112", "]# c #21861B", "^# c #D0E4CF", "/# c #F9FBF9", "(# c #75B671", "_# c #0A7F04", ":# c #1C8917", "<# c #188812", "[# c #1E7B17", "}# c #1E7C17", "|# c #1E7D17", "1# c #1D7D16", "2# c #1F7F19", "3# c #167B0F", "4# c #358C2F", "5# c #E5EFE5", "6# c #F8FAF7", "7# c #93C390", "8# c #0D7B07", "9# c #1E8418", "0# c #1B8314", "a# c #207719", "b# c #207818", "c# c #207918", "d# c #1F7918", "e# c #1F7917", "f# c #227C1B", "g# c #14740C", "h# c #4D9647", "i# c #F3F7F3", "j# c #AFD0AC", "k# c #15780E", "l# c #1E7E18", "m# c #1D7E17", "n# c #1D7F16", "o# c #22741A", "p# c #22731A", "q# c #21751A", "r# c #217519", "s# c #25781D", "t# c #116D09", "u# c #6FA76A", "v# c #CADEC8", "w# c #21791A", "x# c #1E7716", "y# c #207A19", "z# c #1F7A18", "A# c #1F7B18", "B# c #246F1C", "C# c #24711C", "D# c #23701B", "E# c #23711B", "F# c #23721B", "G# c #24731C", "H# c #1F7117", "I# c #23741C", "J# c #1F7217", "K# c #23751B", "L# c #217619", "M# c #217719", "N# c #207819", "O# c #24671C", "P# c #266D1E", "Q# c #256C1D", "R# c #256D1D", "S# c #256D1C", "T# c #256E1C", "U# c #256F1D", "V# c #25701C", "W# c #206D19", "X# c #215819", "Y# c #27681E", "Z# c #27691E", "`# c #276A1E", " $ c #276B1E", ".$ c #266B1D", "+$ c #266C1D", "@$ c #246B1C", "#$ c #25631D", "$$ c #27681F", "%$ c #28691F", "&$ c #28691E", " ", " ", " ", " ", " ", " ", " ", " ", " . + @ # # $ + ", " % @ & * = = - - - = @ ", " ; > * * & = , ' ) ! ~ { ~ ] ^ ", " / ( _ + : < ^ [ } | 1 | ' 2 3 * : ", " 4 5 ] 6 7 @ ' 8 9 1 | 0 a _ ", " b c $ d e { 8 f 8 | g 0 a h ", " i $ [ h j ; _ k l 8 f 9 9 3 2 m n o p ", " q [ r s t i = u u k f f 9 v 0 s w x y z A 5 h $ + B ] ] + s ", "j C [ ~ & D y ~ v ' u u k f k E F G } a H ! I | g 1 J g 3 2 2 g K L M L N O g ! ", "; h B ~ P # : Q j q * ! v v R u u k l ' S T U V V H H F W X r Y 3 Z ) v R u l ` g 1 ...) ", "i ( +.- r = +.( C $ - a 0 0 } v v R u k ) r 6 ( @ $ [ # c +.] & _ * = P - { , ~ 2 3 a ! 0 k [ ", "i ( c P = r r - r , 3 3 a 0 0 ) v v R u 0 , . s @.@.#.v ' $.l %.9 | g &.*.=...K -.;.>.,.'.).!.& ", "; h $ _ B # B B & & _ * P P - { , , a v a - ~.{.z ].+ h ^.$ /.(._.F = - :.Y <.a 0 } R u l l [.r ", "}.> h ] s 6 C + h ( s $ B ] & _ * = r ) , ~ ~ c B +.] & _ * = - r { , |.1.3 a ! 0 ) } v v g # ", " b h # @ + 5 s @ @ $ # +.& & _ = = { 3 r , ~ ! 0 ) } v R u k l f %.2.3.4.5.6.*.=.N ..N ,.a ", " 7.( h # # B B ] & _ * = P - { , , 2 r - { , , 2 3 a ! 0 ) #.8.9.0.a.b.c.d.e.f.2.g.1 h.{ ", " i.6 5 s [ # c +.] & * * P - r { ~ r r 2 ~ 3 a ! ! ! 0 j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y. ", " z.@ + ( $ # B & _ * = P P - - * - +.d 7.< < < A.e B.C.D.E.F.G.H.I.J.J.J.K.L.M.N.O. ", " P.[ h $ B & * P r r { { r * * r Q. R.S.I.K.T.U.U.U.K.I.J.V.W. ", " X.c ] ] * - { ~ ~ ~ { - ~ { Y. Z.`. +.+ +I.I.++@+#+K.T.U.$+U.++ ", " 7 > r 2 3 ! 0 0 0 ) ! $ t %+&+&+*+=+-+;+>+,+W.V.'+J.J.J.I.I.K. ", " )+!++.{ 2 { & C i ~+{+{+]+^+/+(+_+:+<+[+}+|+-+-+;+;+1+1+ ", " 2+3+2+ 4+5+6+7+7+8+9+0+a+b+!.c+d+e+^+f+f+g+g+&+ ", " h+i+j+j+k+k+l+m+n+o+!.p+q+r+8+8+s+s+t+~+{+ ", " u+u+v+w+x+y+z+A+B+C+D+!.E+F+G+H+l+I+4+4+5+6+ ", " J+K+L+M+N+O+P+Q+R+S+D+!.T+U+V+W+X+Y+Z+h+i+j+j+", " `+`+ @.@+@@@#@$@%@&@*@!.=@-@;@>@,@'@)@!@v+w+~@", " {@]@^@/@(@_@:@<@[@}@*@!.|@1@2@3@4@!.5@6@7@8@8@", " 9@0@a@b@c@d@e@_@f@g@h@i@!.j@k@l@m@!.n@o@p@q@r@r@", " s@s@t@u@v@w@_@x@y@z@A@!.B@C@D@!.E@F@G@H@I@I@J@", " K@L@L@M@N@O@P@x@x@Q@R@!.S@T@!.U@V@W@X@a@a@Y@Y@", " Z@Z@`@`@ #.#+#@#!.##).'.$#%#%#&#*#=#-#s@t@;#>#", " ,#,#'#)#!#~#{#]#^#!./#)./#!.(#_#:#<#K@L@L@M@ ", " [#}#}#|#1#2#3#4#5#!.6#!.7#8#9#0#0#Z@Z@`@`@ ", " a#a#b#c#d#e#f#g#h#i#!.j#k#l#m#n#n#,#,#'# ", " o#p#o#q#q#r#s#t#u#v#w#x#y#z#z#A#[#[# ", " B#C#D#E#E#F#G#H#I#J#K#r#q#L#L#M#N# ", " O#P#Q#R#S#T#U#B#V#D#D#E#E#F#W# ", " X#Y#Z#Z#`#`# $.$.$+$Q#@$ ", " #$$$%$%$%$%$&$Z# "}; tqsl-2.0/apps/icons/0000775000076400007640000000000012231073120014413 5ustar rmurphyrmurphytqsl-2.0/apps/icons/key64.png0000664000076400007640000002450612231073120016072 0ustar rmurphyrmurphyPNG  IHDR@@iq AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~IDATx{ tՕWRwK־Y66ى !$,ɂ!' `fd0'fqlɶlɲ[zU]Jn,` ;Uկ^+ȲO M${|ZJ?kuL|RkwE.܆O>/[Lߨ`er$~ڔ슕=mU3}ߦmEjt͖dTn^qŊgz ee:F+K0> (AY4#u)E{K23D!'Q@o- Ԭ`~\eyMw'ьW,s \4)^b'kVM[sѕW?[+Z|C#a!-R2 6L;dXƟ<)<'7M~/\׌\U+t)MAk0c`ȋϋogB gXLR3F )ZbŊ"-|J"$|-+2TSAJ|6&?oᑓCpֻ7=ϰaʀZRd6R2LM=pfQ]]?9ꅤ#!ahx!?bj2czUr\N*xh9vr'LIle5&bS,N;K c@^E|k` b H 84e''"zq^6ʞL &1^Ո0LA\? gV*BR Y`T >:1t̒ΙS A` 2(^sEs0Km<1P2G/eyg,환̟}XI-C A3A kfD$A]2eWVɠ15}Iύ>:^iqw^,I׋{RȠM^$SIh:X,TGM4;ӊra3"GݡÆ"{`t}/X?=o!D"D`P*`;^qChLjS1~x 1qo|^SÔB (;ۀ5ŽvFԨSAPDכH$:-oh##] fc"ryfI&P0}AɄDBc4i)cv{&g}3ܞBocbns )ĥr2y_]yfnȪ\90,!E9E 2-f,o{$"D}CY:8$1%n$ )b9d0/q$$%NOЃyN4Doh²Ճ>rHN= zJ {J&D-G޽uNCwvt`|#pļG<TP$G!H!-Ak'IP؜8&=YU9m'ǛpEځ(+M]hiƐ۫ܜ,EY&i E+"a 6Ye.oW_}(^Vg p̢1Qzɛ4FɣLOBlb &Ϋ #L_Xc?w.e_ơuXp|4!#7BD0 pe<OCKsd1FX -'^+_I=E'pΝ;dnwܚM8Z[ihokbh *H ;1 %,fD)|Chy+M&EwGw Ҝ/BOEf*t\zp3{Lѥ;45Am~a_zpx/oa2ɲu(EñdX}NSbwf"˪a C~ @є%epv,5hUV{v6Z782䓭 x{>c nSS.ijKD0ۿװk}'a!'=#T&GG.%aeiFA.G?LއVQz{OS!@zb )FH 4` 4A\RIE8~]v 8?*48wZTPF-!aNU lbc sRt84}^v (v~BsR&;wi4$қ{p6StO{02-_lC  m",InlُP =AG"z|m8,Ev5s},.rY9k:-y_b{Z10Kv@ɋ &xYn-8H$]p1҉ o6طIrD2OH9EM0F_3έƎwS8p0$EN:J(w˖1EB0D#10 O%}?v]iW&;nz;O &JS"A9y#a#x_w[|T!YX"̣Z3zdU?Λ_;: ˦JEskp5!vʉi ("N +Z`AKaGPM}"Y _Zt?]7  Ru> %B,(Wc9x"ٗɝ!O D~D(ڝlYwO8?BT*e1:eW6l]vsqHn".d)u{K͠>QT\H"Qفlz9hjj0uD~~I<Ϳ{u$8{J cc$.7bS :5l/F%1Q{k 1` O.Ekp ha+/Nw P1BGI gWW*axQس(}8θ )F u)*-`" 6?VKR3إ57\Hi3Szk~EGg_gC@sg'5yW$!8vky k4'r10'2@בzW^pF%%6G4 [1gLe,mo8X+0Џ,RA^;gŗ<|0ź/ѓ%d6- C :Fv+S(05>t%ZTL+SN>P(_57 m |cŃW$Զ:o$+M~?OrCwGP͂U5faf}wvj&j./Eu2 I/յc6lY򍒅W?ۙ}2 LUؑ=0M7+ĦOh=~q^)tJ:#,~ /2jPLqU, ]ųX r^8wSXe?yUgtβ,_`hzs%~ ׋8_jUA^G7$0>V}UUa7= {lnxl{ܓ[ck yj5 `9_o'mr nj/#2B0ST8Nb6~g\cwZޚ6l%ēF%oM)OʱㆁEuWp.~M5`,kscZi>3/ulMG´-BgP_F^%W".FiοQ[bL% hPOYIM{ib˖%Q_ c{JsEX3#p5g~ߦtt3@3k^nfn{*Μ͙`;O<󼢺OB3&=Ldng@?}n=uPnhEY;ʆ5~mK_Lґ'H:ꄗ])DJo\5=ܠka 8zclc;-*ڶ=kEJX[^gÞIoFF cpCSȊ,O>7ӀM{ FqHPʨX~TCax܈V@`L4g)`kVf*5:;:"ⲅBY/9" ?mkduM(Hǔ).W622,d\#$ ,R1\C/ݟKlʏ|/'[4BD#D PKs#A6>=Ei}u-#kT fe$Z<.n7@gR&/z=s.#߭lAͯ_Prcl:"eO%/")/IM3]Qcg9kS7޾58trM@4(*gv^}߱Ɂަ0 0ҝ=vmHt:E5Q+No-/1|yr$ǔ49'şymF_=Y`˟l\3)&d*<31թ41utuyd(aQQ8QYao`Sm 5Vh,Վ+%8O/Jǧ==Ϗ5jy<$FjC "MD`ϑ+'6=ka0ۋԯhe*=;V5*LGw/qdH#(+Cvg(X^xgLmr5TK`[q|~u1Hz?DV&P| b*KE?;<}esKݵ6š@4.6t0XUVry5b̼Y߹t˝ZK+SPLY O9(IIg%3],uvW) eB)])007(zfj![aMꩉS55^!)('ߧM۶ F:r}*I1ŕAn6.utTPp(G2lʪYGwN3N(AQ! Q0\pѧ#&: ^a6¢"/Gf&sifm.ϡwg1':R{Nx|XĖXZ3ܳB^@u"sxdD٩`6lDbEz `X.QZBNLػ0wYVmy5rBsM uQH_r2vIv]Xd{ctrO7lm S4͇:{Gv5ū'0x)epR8뼁B֠GjE=~ނ1EjLQ }"҅9jj{!;?y&t ה"2@c`-]Ɠw\H/  %v3?hx{oM2VGBmOn}jd3q'f If* Gn%K*k,t7} A^N+`^N_eŏn^cCg=}g}LxC!TF"R]a}AN:نfU< VpZ>/^| k~ C*ZN⼎i<_qM-[`=`gHX2o)4udv2:^>wUkY'E;f %1ĊȺGt*!/T5Tfуfnjά+O W̨C#l\R"6Ykw?05+\zW׮Bpņ@9Sa濢 YNɰRg0Qhmmئ:@DP*K,yD sԡIa=9|CcU /al/MwFOxa6% xxFU R[koT>g/p4cHݷ7=dD4ǜl7!='oIENDB`tqsl-2.0/apps/icons/key48.png0000664000076400007640000001634412231073120016075 0ustar rmurphyrmurphyPNG  IHDR00W /iCCPICC ProfileHǝwTTϽwz0z.0. Qf Ml@DEHb!(`HPb0dFJ|yyǽgs{.$O./ 'z8WGбx0Y驾A@$/7z HeOOҬT_lN:K"N3"$F/JPrb[䥟}Qd[Sl1x{#bG\NoX3I[ql2$ 8xtrp/8 pCfq.Knjm͠{r28?.)ɩL^6g,qm"[Z[Z~Q7%" 3R`̊j[~: w!$E}kyhyRm333: }=#vʉe tqX)I)B>== <8Xȉ9yP:8p΍Lg kk Ѐ$t!0V87`ɀ2A. @JPA#h'@8 .: ``a!2D!UH 2 dA>P ECqB**Z:]B=h~L2  5pN:|ó@ QC !H,G6 H9R ]H/r Aw( Q(OTJCm@*QGQ-(j MF+ 6h/*t:].G7Зw7 Xa<1:L1s3bXyeb~19 vGĩp+5qy^ oó|= ?'Htv`Ba3BDxHxE$Չ"XAP44077&9$An0;T2421t.54ld+s;# V]=iY9FgM֚k&=%Ō:nc1gcbcfX.}lGv{c)LŖN퉛w/p+/<j$.$%&㒣OdxTԂԑ4i3|o~C:&S@L u[Uo3C3OfIgwdO|;W-wsz 17jl8c͉̈́3+{%lKWr[ $ llGmnacOkE&EEY׾2⫅;K,KhtiN=e²{^-_V^Oo§s]?TWީrjVQ=w}`嚢zԶiו8>k׍ E  [ly邟~_Y53rW򯎼^{7so}x>|쇊z>yz7)bKGD pHYs  tIME 56IDATh͚yp=ftKealc!@aC8C\! & X`!! (Lb %Y4FCS3!Ęjyާ߳nXx'_n,k :QRuƒdX dLUVC*yF&!zX< T|t5AŸfdlQ!J$*}= Ü`A\* ta4x: D5A>(WK;N*"d.*.@A*d42DFB"8f 騪D8oh8q/OӪK^8Gq87\y_WnSwmAФcxh;Sxgk~"ah%֧rY- Y<ŀkBn`qZO=ڳIj#Lsj:,oV\"tHz=<}2[78D'\`04.Jĵ\M(d2Iaڽ,9EOLvŗxVs1L}݋o?ר,_ 00Q&CAq#=~4,i&JcL#ϦM l~s +ލD")fUBYtH'turǎ Z+ˮ3˙pp;D D__?PjZ?8LQQm9pWMH_@{FɬA#jfρci?8&dɖ1It 'Vl2(=̝7vt]`; F8z&CaAAlYY|/w;e4:NCy\]?0|@1Nd `4@JQ:9Jr)(g(bu#((̧x$Jia>@wn.{6zo1}$&l~Z' RpJ緼.VcgTUpH8k LL}I͢ 2SAiihF7S*J{uL+gfr6$EfjU]]UV1{V5^P(HFغi #!0ȫ-;#Kµ[/y(DY,1]"]aEy\>?f)fI<9%E,Z:{p%salYYo& PS3p0H{UM(.*[G$?֍madI\eƊ+f@*DHP$l\wgwŒI.d:RQU]UU%o{}ql|e SUU失 5$//E1J z/lNH+W\qC Μ" V%Y]fTue4!/Oi8<7pSѣqdlPdiTtMXr)>˴RJ T:e#?YFc4t_:+ASX;.2eGP` 2 /~o߄,.Im6|X MCɾL]A|TF,Ƕݜ{B:1L8VfdhhK^7g 1Y2?:<`}m_{3D^B'6-{xe=zGaYB)VOa杜}`IOc4 )DrsCI$$N{ aS~ҡZ|+ Fq*;7_ÔŐeÖ[2(.$ 2)4!Fii>8%E.sdd)XL2DYar=.M`Zi>{̼k7uoFH8@β2*˘^QΝ+$c˛_,^};srQyI ֽ-pWLyφ{&l:nccd,at(|9_L2¾z/[qXXu篼9^˿}<71-=gy[N <#'ow;v,6lN6}njiGj)p,8 ³ӗ~ﴹ ;Suj:f[$}6>Zv 2sEH s+X$LAS/h vJSY<u'J΀! 2D3*\eAR?y.Ezz*& ~%zZ(A22~_Ze]MYxr$ L%QQ F?^M?!pnH%2c|N3B}灞COGIeT f Ey$Q;Z d2qQX\AW;v՟m*X;wUާ"փփE0I+qב}8?+T`"j ==$"Xd\uHVsKλbҋ~z:b^{ Ȍ[D@WO@gv*fC39kܗL%Q,E%$Q|^/X SXLyzž<مKM FyoFg5&z1s@ŬsصN&]`2/#m?BQ)>m6Q0ӄz>u)pMo & zDkO@Ccs7vk:2to[;=~?4vusD dy]\dD iP(wkƺY&LFHYG# uo3gJ,YIݛO2zJUH8n*V!tl *j κoyit#V {J4?|we'@T~fs`'4vh".dٜEW (ҩ3sgWl)ˮj0vn|z8\L.t`ӟBs>2qw<G20st2m-x{1bZy3g mϼx=v $D.4!FNL`]~-럆?%bPLY.f>p(L _lʫ7˖IKoad| 5!w^yᠿg фbdd֖fp$j*):n>01]W#s's9OICW3gm?áUMowzyK}=_i8e!1QHI5\|g `0IKSSV@q4ع!f;E_K<QT=lQU]A<"8e)-̦bx44ytFvoYWD&la1; a3:: ZZ:8j.V^>:ڡ)f3Ο2ё"H`%T<7 5,ڥV^j|}͓IH _EuV2꘮(S:8PVzZiid(mTSZUÑV:}򚅗-[yy$0GnaW.1%rMdM|Xw=Gp[EnJΤSӹ+\2QRBcbSHyDҨ{P4ypX6n_]]z܅KDĨæ$O /t|2n2GvYeS9~|gXu܅KBhH) ϲ>*p,zeBJ;sn;WP6pu VIENDB`tqsl-2.0/apps/icons/key32.png0000664000076400007640000001266312231073120016066 0ustar rmurphyrmurphyPNG  IHDR szz AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ -IDATX W t;elI!OYDDEN-iG[m-؇k)S`iZ9Z# h) w} =;{?wio*ʔ,,뛨3zEI<92T?,GG(p^ ȀUL2NJE }2kQ`_@ӆF\õX߳_9g,DFF♾`b;aܪu﮼iޜ֔\]fU^͚ -[9Eu!d2l:v6 ~   $%7ec>{oy_QQbLK7S`8M!HIV0aMFlilAP=|'tT8 WNNuq ; $ ="z T٬y3BT j@KAꟁ&Z,#$ "[u,Hf-((ݏ"ljإi~ºڍa)7` E;k8*$-UfnZ=r7$1ERVD21Hee%fV0I. kz^kj$Q/.,iQMk˔!2xG'׾D*wC 0bI,(tv ƘQT^Z=WAH5Xc~3SӦg;槻 jؗ9 d{;S=l?tNw/wU5f3@i,T~+#9[Xp=kQ܌ť*HlUOqҤIep_=q$S2ަL,.Ubvw4ttCwa^ޡz / vl!f6r>?>;PpZ5>S sXK:,c Pux^'v3RARi|r+Ⱦ>nws[o_xA0褠BF1M ):ACKQ3%MgO)G[Z٪b<}tnϾg^r9x/0%BIhU|QRi{PbUDF4Nuak&zi^`0opL;80M/h3/^7/z@|j=׭8Sj?ʖm0% $!i4" Us83nR][c<:tQ5/A()HDL]p3Ar@,wFƎVTLnڶݗ[Xo^:DaSTaASEsp`x̛w͒76Tya8 }c==]8OVV4ULIENDB`tqsl-2.0/apps/icons/key16.png0000664000076400007640000000703712231073120016067 0ustar rmurphyrmurphyPNG  IHDRa AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~IDAT85SklUݙ}1ۖ1]BmbkJlDcHDjLք&> jjhn[v~I&gs~9B$Df'NP9w`x+OvuSzJ%z:[a_ȝA+ tLr>=\8Y4P@P4=8t>nR Uvr?,Xf&lk64vkG$jZa"E_JItuI;~'x{% ' Ryy 3 j}l 1ѠTX `=r"I"8 1m$dޯpZkal(ZԜ6r8K%.VGWX=&`@R!--2k7 sgd5d١BI),Qns ɻ]-gx }dkM4X.}nBˉt( [mo>~IDՅ5Q{7Nz*|?*}S LxևgQmg;4Le1ԺWUt$.7j,jT8onkzm U siV(<-(HFG% .q({kdٜ{vm9|`PЌOG#3 1Q1h}USs9ṩzޑWϡȌP#Y. yXjfj:Y_]Q~]?}dq!Bqa8C Ygg~!X#IENDB`tqsl-2.0/apps/icons/key128.png0000664000076400007640000007620212231073120016153 0ustar rmurphyrmurphyPNG  IHDR>a AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~@IDATx}\>3nqW!bMR} m)RAh#l63r̲о;ss߹,*ʥԍ:srpP#~G3;1~N% =X+.v ~6,/)Ape_ClSU V0e˖eaUEEK֭Z׸ޛo#-)- ~ոsA@8p^ ~>?zd~J|(n ۷n=cA?Å驧ԅK;}f|ʉOȅzë+z{J>s_ Vߞ3i;Ff%z),,Ն )|&U( cnyVQQQ\EX'G8@yp"|?;qD޿T({7SRࡾ)&.<_q8 `fɃvG!&:.u u!O{ɼM{Vn{#D HVFLjXu*P_hkqGt$հ S>(4hcȑL:eܟ-ݼys}Prvr2eJ211K?|H1/V`kJh@\4 5S* 3f#[:67w\H3_%SYD96%f(ML&Dz܀9%o$J~U0UQ=+XL45ǁ#']lAjjYFK%Zrv#Jh+VljUȫ~{eK5}{ڷJ܍Y+ Dž&H^^~ѪO9e/3(AW#de4$Eސ9GhRbdR*"`hH_/\Ĕ m\\28UʃU4Y$JS+Hs14X&-A"*ӦmQ'˭ UxUJq#?[2ڨQUPYi$K$BSyC~jo.Oh$6 uRRmm,SDt:}٥' }yE[n%qԨSș6|pRV4,u$/ȑPXffHFA#ݤT`IZhnPUT<9cʤGE#%!@IBGx$ӷ 5tSFUAEQ`)SaJ! i#G% có@ }n"Zi;Mpxێ#WǂqYzb9eg%D%! iF9 D(䌼jmJ˪-FqGTVcKTשЏ2$v\@io~jK^.ݷ9GjW:m`UIpXV$eiyVd0i41j5H̒l̎dYDuJ?UD >uE#E#@lf+ d@?n{X̀? `KB'@T? c\X̀;c#"Ϫ@<r)h=)ˤ%#A/ k}wLZ%tYىXfFh% CZmkm%oCd<؂NT3(N7}#4`͚1UjU@WB3&. I&L3_jnQd%BSQsmUtc"se"D:-*n7St5'%8ۼ\,# JÀPE 29 c^ި&;0>|X5b6UASX%!7z1v3(JBcP賐&8pq9K3/>2T~NKeR#yUA  N Pgg;)U:YE@X2ZlCI'ш2z賵)ŚD\3Q6Rg{'T fwH\Nڿgأ VuZ]t%/hOv[sR# 6\>$?i2Z+C\5zOoI_gN:y+(yt 8a?wѻ8GTA4A+5UMC|_$MprH@0 V~WE z!`~ɷ,rv|4bZG % ,xp%`"I9K!EBMf6mI@9!ЊגQ bNo G+4Qր_aOh)kCm]]n꫍b֬Yك{YӒYI +lf&){Iz)&P<̐F鎑ӱu!kiW:W&γ͞:YY&/2mb&r$ey¾`K::tFcیV3y}>V;+S`Ao֠TjH2B5AF0!7ڹc?顫 ڽ=!C( V=vgVvJs֭l= HwQXo-}ԁvQ\2JͶ!RSٰe<5\xrb,IiSM,$}6if(ϋJk=&e G}؂l;=H}yAQ =?# @,CTd &(N=s7ܿ|>.9v׬ j]\XniXpH4v1h X^Qiu@0M=Dڴ4Lʲ;wt*zQcs >E7_F+Տ{z8/(׭[x7͹lҕֵK:Jrʰ*oU?> 6= _@ݚED*$!/9{)1$tu̹[tuƝ)bn`Ѱ,wݦ C+LF~YSYU=Z = 9Gc+Ni{^΃x_,If6TpAYua,[:=㬠{ z{W1ĤZQ;n8u'Z H $r4h넍͜A> L@C0y]mmtALvuТjo/E2>ҺZ/"LSBs7=e]v:=lj!hMAOW M!''L)j#u4Ј!:ݑDM 5^L.DzgVEz2:c\/,/wq-ΪWZ5yy:;#QZ %L]jo풭vSޥg؅@$FWp8R_,1Tӭu.`{w.g~6#3$FF Mҵh6 qڨwR!*jufwY :DcY@E'ՑRHrS'Kh]u~t%JM.?2hӮ픑:N1|}J#WGgLweJEƇ{13qLI٭) s-=tb&Ҙx`שr ϭ@4$L4z P T.y?# 5v1]\=U\d AQ[XX!(Lh$Nb 0vڜ[Dy,dA#G~4ȽV}Z'ekX !4֭M;v=)ʫh`a6 W@{!Cw"h6227RmwY)dvp!$Ym.,5 Ε+*/wr1Cr$#4'hѽX;G(֖(6s~1LҨV`l?΂؏ hcuk.pZ}aW1`5ƆHMU$EH`.MDPg jTatR(죺&+M̄`L:L|,Nֿ D;l(tMļBk4Դ%8aTw^KQ`(D`*H lˈ)JϜ]&D=tC:0qLZ /3/`/Q@#b vP|<eL>38(ׯ_xIm\]Q$2L4Ғu1kl 2ܳvwQC}]~$%Puu3u8}d =#ƏA$3mܸRĩ2L;ɑI>ڵyt1ږAk*w'}+4Y#M^uR[K90d.ВPRUzpűJy_"HҘ$gilF5GwdzyqT;dW1FǖNj)bJJͰ.,yZس[{[Ut嵳)=EC;G5Dn/O8jj^ @-J2ғ dJ ={ ҩOwX%?\NZ2h t|>uVQ o=wlbӰj`Ѱd3{3x+Q/\xH*fGY8o:߃^(Qcnb:qh?/-` 7=QMV@ + TRRKk ULGu4pjnj%#,#6  Ɔ|$ҾŔU/ûЁ) o& E5“k̍! D.];zxfdP0 u$ٚ^y7ddH P\xaT*#|ԉn]7 [~y XQG7ahɲ>[\0{1Fh:5?X 332`翊?Fo-FBٴTO)I9tj!G|Q}ʥLڳ4~`98_Z[VbH2hAڲ}t[>8\냃JI]p];2#^Y5 𴗂 u{6ް{%BE6xGF#ƅгRYbZN34!Y Yi\uU4x8ۨ1Zy̤an<2XԴ%D5, Lw޵S3(ĪRfNLX)売 &Lʊ)ޣ0hiׁHN$H96/GM_ȸ< wz⼙io8aN,-Hl?V}4/!;H~81E70< <&_P sqqL,̬wz?c٫sSSS蚹*R/*ewAM-$};]={. 0ܴRB s˼߇IBAm<}`^CU(?'b-EqϔW@H,B̡@&i@]+Uos M|?/_0cJDjfv~c^zaҪ~,*8zƟNX;;x0ݼ= uu _W} a9c{ n\=Ǐ8q  zWB+7k_w|ɇho dJzxjh+VeѩSZ[Jt[{;&gK#;:jwh֭x "^5ݍSE:V.w(Ef];JRVv:,0Py2zs7xefI6`WP$ X`O_JA{-员]Vj@{ |>ҍGϾ۟X/Un[wbOHV0ݶCMsЭw~pj-y-{),zTYD-t 4xH?*ڷG54 Ӛ飏6b:(=ICGV$EaqtT:;jwf֬qXS! c40?SZϵVUf[*j`6ɋAy^Ooinj^k#R墅xe(%RXE';%I3B.6z~B6/焳kܘQ?/H$wz ULC PfZc"߾۩| τg]AӊOQu}**G${ڵ`@VIt߽w9+ISf΀uMPIJ`QJz*%!ƍMADDE aKM >[mB@B?!y*yO⺂I/´`e;`ݗ"i"{Hvǖ3}ګK# NHBGSAٌ@<:zIl4}4(^Ck/=r8)DچX0B0,+ИE[~NQ?6]e844Q2j* >  B"/0S)3A"A3 Q;Ȓ` Pr/m{lێ~ I2;w,^,|I9fx 뼢/ #XWCK!C(|5Md>ȿ@KgĢ051cK}PYU3yNDdw V|3;I)v8~{e@Tz{FjBGKS;,(;ذ1 WaA/сe6v6Ѣ@8(=t0| yaQɣR覅yEؕdӁS5D?Z [B`ڌA+חνqҊ_B Q(Tngn zθ<w>DG7\R.Kv);]OSP`6#?#@֯_ޞ=dF )0Z)''lPT!>lJޘ ;PNvPKfrulu{CQCe- 8 `ܸz=VfYa<^,hZ ˃=s'ʨ,%>E]G0lױj*h'L͹d3p-m34ft|]T-m߹WnUd$ZTU{Sͽr_,X`$# -_ͱdc]=> e!lF@{]\ծxf|fύxOqGAZxt:ֲ>׏3iţ-5f V+">P?ax+ b5,M2T9Q#suHqՕ͐RA5/A9^VRuьhِ) }{m즡#!\M& {ӡEpC'+BGZ""U+˨ډ { NT6P+d;)v; 8>&u&愅Xy$,,9MZc?V8o\PbJP 5]"DPK=Xw` i^=QW?f6h?vn7O-T8upޔք !.6%U gV#A Hpw":X C`;@4w\ZrB嚃z?YI^W]^Lkn.lom$+ 2P 3TGӫ &+D'NTCU3g  MԎͤ҈#hἫ)%X"(Ebο?XӐe\EYʗaHaDt4. $}֎X/naN C Ŧ&z8bU7rwq5O#'y'42Xg $ -K%7հyӃU>?/E &ڗwHəyҔiPT4^HXuuNl=jX|X,BNi3'{G GAso^!0>߰:\ndYx#}Ɉ7h$# ;iڴp$e\ͩ * /&8./`Ac1_wt< :DnP/٬k"ȔSRa@$57qQIߖD+-ǁH`!刬~uY  c%7d"YFꋜ1K5B|V!#Yyz?\_𯟔(ՉFN>=@0hI -9L+S'aI@d4uRuh뺝 ! 'goW#,vԫWg2d GzvR:qbq!$F 적@ր 9`O:"}>(F$QC-& /*]He[$k7Ӱ[2-9) l&P,XiO:h24V=n"c`E<+mQY_v==ƽ-Ď8c/<ĢLlڸ9JIS&A/Aeӣ!qt X3w>KXQkS_Ml&ߕ gӄ+w>fcO`w}:FfkX#e{`%TE'NAMI ^8`_ho`W?i /?*ȃ\}qւ8JJ,n>r#v/&/lH`4{Vz7SCy{C% :C7pYfFj|&:]vd-.#UaJPB0f1kO'g`UH}c/ND~mi>qP6 HvYҊh8b婱̝dۡE kPA28'4KGDY D 7y8b|*XV}V ^)in u(i>jr rO> bi1D%e D*Bz1dw qR -% d/lcx܅!lK@߇" ֺaX*BK`r.(B*`e!,׬7q# 4>IEc 0w@ |fOjFDJJȿ5NZ^ѷ.-|qq{hc哪+kaU)@S(*}OD \kWQuKm?TLӭtbRaۗjd ›& 6&$ Ⱁ k6ޟ)b?>#.{hR#Tb)zd@<@GgTzց 59C@^ILL?f ۱YJF=6Ø'_߼vϞmͱ2@b_P\&Y `VLaAq f1B`?40򊎯n`Zęmn#FjxOxiׇ>Z_T>|D_pdJxwa 6rEv" A>HcI3Nct dq[Q#dID Z6˱JH٦4e`9 iOHĀ!‡%#P<\L>LF,D=33O6UiɌ=^X==`+̇c@Ύ8R^[; kb;uA;nU̡fI)Z Dͦk7:M;vtMm̞ZN޴iSg<1Y090Y tρ#Qnfͽnp/mv>[1͙=E@ MnXV0%X(/? v2BRKQA Į'd!Pj]__$BfwZ-Ͳ-!E1}w*?a}K,J,Ћ.f, ?y >]|hagW` Ǒ rk.5#4!g܀,(^zo~z M@565@|g`j ֽ3hVqbKFBh- X&b\4 =I<ȋ ռ3Nw3ɏ|b`,?nG78fa]%$ѱi[+ # 1,9w^I]u%G4D#/xP7cC4hx _EɰQ !^MM (m05sƢ0X5|RG\W)*p~nUU@̓p[=Ԁ0* D `'0 lϱ}B\PO|38ѥq#\6/D DR9Wi3 4>ʩ9 |1vD qc㲡ϮŪ/``.RhfJq;D4@*D_"DҲR ZZ|y}B.˭KJF0FǛ1A H.JOEXS(n%K6*;]Òj|pA>M5^E!*F ̢8'49!M#B .RzEV6(&CHEO\UW܈ ^,pe*(I,KE(! N\"7;x *JmhgW"PHCO}Zo{}Yz:~Ь+FWL젒Ӥ^ !Ko_ zȑN%-ztFӡg'AiP`Ió`$jkaqS'9A\Q"x?o7n(ϟcv,.ojo ıI ;8Q ^*`Vl@:bP?|~ IgPNӇ/:dԨ+y 0%Hq\h _3%58N0|}A/FUˈ$tX?C/𓽫w8@}Ʊ/`pGSm'Ȫ3!BGv%$ Hngm=e OPmD!@%#?-`@1N* ap z#d>y CEÇ*DS>mg%QcK CV l !dG>bD/7 =ss%,`\KpCBJ7:ur?e-F<߃12+/x~9HK, uJJGJ^rT6m=Qf-yLtQ Ov*:YLɰi!1aP"XV=x:1a [ѩu}jXA`$wc=8ǙƒSBVSɰߴ8_@>^6L#GC|d찙e X 9ԢVĪ)[*` l>2@843>| #Fʇ5Yxb|<";o޸w~\(>Y9NŎd*XٴRm'1IDAT?7PI} %!f 0+D5G,HVa2|,=E)RԞF09@:C flR Vl'u+8:f~;Rk6':-DAw ;Z$Ƴ'!tA/9P\hGD54;icHt~S(]`BnX!9,m!/`!V  nJr$mJT5;<4~8~$B {T<;ssV\{1Tpd!FAXv!:*X2-twn MnDw۰{K.oYS|a_t9C~5y?6#e^@c 6=ak1pO"Դ#zm@@1剮_f924ʆVRSSP&l aDYjo}p ifܱ9Y b7=,r%i]{&gmA_ôiWy\-R8Հ *@J5&+!@ug n1(ǁ,^+SҰ!D~Q$tw0natl-3o}j*C\ $ r680E8xe9bʢ6.y"4S#3b7^qϼJCgG([KES:Ն5ۤ$G$9=Y,c!1ɰGOƒ.4.!x<|(@J N~LPn'"Vu}w><X*8G|旓 dрM0XXMc͛'  ˏs1w"4#0sT86ӍEd*#RlD0ƻo}$WvJƎe3W%*i%d] YA9;@~Xgy7{줟7wOLOӄ=SȅoWO[um5Hzo*:U>9`*>8e3? pd` ŋgǬ- vE<\тb7:tWHzz.(ҍw,@Ա`R~THCz ;vyD>7`^+l hgSnn>Cŵ8{kf 7h*,,LūlB۶ms2fG `2d ¦СCOfo);qTqŏhcqlַyO~0fՇ53lGض4&ɃVx*Ejjh۝?fďڄ-b$e>Y͆. ur[A8UQ| M $a`_{xI=  sC1$ PV+Zn"8r<ŚT:qO"@8 Q,3[|~A^nU,)/~ū"laμa֯Tݔ<؃=/؝JP(oEUaƢI-쿪tfS=ZQu?/,mOYW=_q]ž_|#/T?D`l ?Y=o@[VzKSx6rlDAzZu2/~1&cLKJ1{#ݔylo|ҧN:!'=mMOO)@"3E#>so`Lgԏc^JKILat? FN_ދT{DA=4,nMtὕP qgعsF-SFDa;R _~;vp:ELJs H٣_ZQ "{n8eG}"i$l@2&iy/l Zez唅d 导O2xEC/mjt@$߼7ca_- `q sHӭ➞|i @/ KV^䌴}}0(\Zy fJ2'!̄o#g1,ɋ !Ya>AO\BdDQDB+#ߘRf42y4|' `-6-ӑmivzUYA<(zf F;dޞu:}7TW Ӈ6wmKd~~5.'V/OWBvLY ZF`frESoJ#fw.L;ʣQz/tdlQx.m:mبHYi)5 :u[_WC6Gdt%ᅤZ@)f< c%p` T,#5rg:C;8O&p6W0^ E^d{A.¯Ո1!RlH^+̭]WU\2BK /\w /?\6gu72-ial'%Jjލe/$C4KLl{ӈ&d2J5Xp Hҏ?^zoIΞBfl-d9LRj=\X(;D[AŎX*|xώ j_ FJjZCn6u > V+H*s?GP2~d.-+Ɉ~ԅh,;^zϿ8 ;qCǯa\WAx3pⷂ_pؽLj}r|@=ڨ#y }D.[xSvp0Tq⭙Ł6} b>D582w>',v/?#2}Z?X*أy,َ\~HcxK+WY/΂} XU;I HW6 *;>!U 9R BL].Ҙ43=nAĦ"1$--u c;cWٿ -%Y>!2ioG5R2!4hQ vɶc9 D  KeR6 ̱Sl$0Mɷ'%~eVL.-x'r,l5r3"^< A:ߌS><@&8Ƿ8 VoT)`;- mxc騂E އʿgkN[WUe0NlRðTa+Rub gF$K2^TmUNkL*;ݧ$=e& lb(IHX4$ IBhC'vhHf4!L:,5&%8$! `0 -YXoo[o{'Y1)`^w|xkETuMiF0Hm%@%;O'ጹBtV"DV5PCrgB <P;H>y E"je$)Y+ڤVr I!/Vi%Ug6JeZE}2,KA[_+vpg0jiQbq[fۑRȹή.~,N 9 &3襰T(0'~yP6.VD7|}i'8o$IN&`ɽ#;sݷ\#/fN}:h )| iLRA `H!2k@ss$EF3*(c ^ @6,|lJwv#ð4n Ae#m\7xԕRe Ï)ۂG UmMH#)*EmϢJI!{Xe.Ꝟg&#t1Vh΢݌iǐ)=@8=zg*=?6>haC|1 :pSR *25Hݼ uR÷_&CFF;`xʯVO(vjKu92TZrȰ!K,J tȣeaWA&`W"$!B R #Ēox#gLRa^Bih^B o}o~9+ 3Fb}+=U2za{,6(#*VvY7PK(n.շ2 S.іOcg[!4XQE4ۮ5PU Bl^$̮c6+LD%Z0%^0$! j\b[pwLqRlXRW%#C!s?gXoN&svE#86ʯWuU)ww(AB Y$*BU5qUCg,;B Qg רhOs[^+`2M_(MPJ(xe(>;P?jS'Oo B.z?_x3 ^|0O+'Z }֖7se;g?ê%`pD^jdqF6T\Vfе!‹V7R^U XlH εs~K<թeU3@Y{蛈q׫|nȁc=_ce^ZiFVU)sEGp!"]^:Eip &`GcQ~`Z|L/zgKjyۣߵ眓.(C?Jzݓ9gs/h{*omHФB] eu|]uczxdLu!m#vUjRN`RdN!;mF_TO/.!->ݏ=Mw'2p lj }aM-Bρ)C룤ˠ31Qý$b|'NzAC_OH[F&^)[2ʌM\uh 1@ugTMIqu, :jj\]ɫ;]9۝G)-1lGQ P ]@ayoT?7=?P٣BrUOP7͎cF?sU}&:,CݻwS[A|# %<4i6<ׄ^f*8Lz)o`&d6ϓŰ}\#p֗f4l?wO}goU^a\>jOpڍ P28nVɔ*@Rtxݴx`EziSe@#_硨BUD2YtYNBAu2w~w}!/golb8Vz.ReF~\]@e1fNNZ`EqLΘ]>o1?vQ'I|, m'ٴUn\;b6>*@"Ap#'U 왃I]?.a - >ѫDg& 8WS9 uqAL {=/6.y]wd_qǓdZq,b^1V@!ìr$ѹXܴ ߰ ֖ @tƺ[E-|E|m65.OI_#"E>G%hOuP+k;`ܖaap,() H)ř*gjպ @P g]}/v^q='t2iPwKGy,xaBdO a a*FB.z{-jF;DOf|gzОU@vОE+ o!t(?7 ܭ2jlEw!G$B(ISK}*^%*jKyP2Ǎpko|롑[Qak@~L6ʸg/&Ο9.Pg=ߐhG:?#W}?-W&G\ ?0dR͆ѦwEmb==NiV󳲲Q&ܯF֪EF$ǏO#--Ш}{'*~"L v4lt$~ua9 fk!`._ݲu]?<&{6 32EcǗMf와(_b*]R KuvubK"h Ys[;tz@b0Q7Ϋe#o5H.Ple>?f4wu;*7=ۻS? 6پ5šXJOS,y`)%\o۶m.~. )H0v3l 'g1cVJ/ f>]`a*ɜNfݧm!XD5L۰xlgRPhy9)`.A Gۆξ+fn>q;*qokDMeOox}?JWml{rj(nCʜIjPzV' 5@,ʬG'y6T&"a\q0XPr <ܹeiwP'2`v{p+i|Ow&n\,zO?#^"+$@!A|rctF l,ÐhۛR-.VY "Az Kte8u啬i|G|YB&(&rzF.~+! M˘e;;Afm'$p]6 5s<GU56uP m2D v-9EZ{ɤ6^*L˱ }ĤS^/c;B?o͠.O9E3@%%lyƪwhTp l pA]߽DYt`䃔)pS0@uyW!~O窕+O'247 F\!ė1IbӪh!@3Dx`Ƕ^Q71)ģgP~Oы33@~]!#T+*T˨U+fÌ>566Kׯ:0/U.lbMi[V-Sc>4ˈ?z`b2*Ըo[/ >%3Yvu>666ސgI *gCuܺDG&p$&lD!h/}*\`7RYUm\P͈ vhmm t-nsVdXawÄZeفfңcŚbJL7c5O > Nr @0y&'%9 \NbF^=2:em0[؆\m/G4ٝ+g4w@ LF(Hmyʎ訜iZ#Vjn& > ?{._Z^L&RKɣż\[moɣiS "SY _$ Hހpu N%4G|䄏a%.A=+7-59 Hۯlj2u5Wx=k7QHl X R0ILM\.bl+I). a1Znr'z@|m$DTY`>>0N-EgR7W5QzReA&H@pƌφnn=SėH 'wY/z%'A%\-ipҕ2$\ CϺ`Lǧls%ʧl9rp?|Pka2 H|cD0_: ]ttZPD`,n6n9o5lipRW)Dro(P IyҮPwgϹnȤ@q3g4 ㅺ|#GJ';/Cl0c7OTF ``VqTro@(!;m o4<r9s\ WwR^z;r?"D&YI )s4xְ ʣNDĵzӇvx]wsV# >=6<(1%<$H]Hc.sX@c0@?i62kر@#YsZ_}Q9sʁU9i3Y7Ffd60 OKE3UnrUB:10v O+o[n?/-Ci)^sԨƁ̥Εyff c@%]6V/9c43|<$td"|ǘSE&Ƌs@TߦjWEuA?69a䗺^}ɓdgU`2 e<^ ,iCB M$ڕ==mraauP#N(Tn2^޽32ҷL\!uE wU͛O7IvwGvpG, CϝMNu12P;!4^!*DĂ5ĮBT2B˾3;OFp*2,, @݄\& Dyŵ ڮLuO)g ` \Ş,}O -*׆k>7r󴎰j&b*Qc$ᙩΑ f : I#0DJq"cxzl!#P0TJNaBdhN35wfd83DyuO<&#S@rx3]Ks,gϧ2G1S55l VԹ ?-iJ\4:*Rlo^ʾviֿEi+î.LD P]VSRRO"vGvF( ["5(J yG%/[`%{O5aoĽ!R"lgn1wY dV!VeTr' xh|ǏЮ{KV8 ( e+E3,TPWZ|%akw\ÍZs_.Nbgq-"NNu&L3rCþ|hƯnoC7oB3u5j:|=3zݯ+;t9WޤVz8?-dK?ggb9԰*Oq%B7!C}jxhӰ l {i\s@&CG;vsxa,x"ӲN*&oH1dτ)2/HXbZszbmw\ 4IENDB`tqsl-2.0/apps/home.xpm0000664000076400007640000000517212231073120014763 0ustar rmurphyrmurphy/* XPM */ static const char * home_xpm[] = { "16 16 128 2", " c None", ". c #3C5795", "+ c #3B5591", "@ c #38518A", "# c #627EBA", "$ c #5C78B4", "% c #364F86", "& c #38518B", "* c #617EC0", "= c #3F568A", "- c #405482", "; c #5776B6", "> c #5E7ABC", ", c #3D558D", "' c #A5A8AE", ") c #C1BFB9", "! c #455986", "~ c #5572B5", "{ c #3A5490", "] c #3C5692", "^ c #999EA9", "/ c #E5E1D5", "( c #F1EEE5", "_ c #B7B7B8", ": c #3E5487", "< c #5B7ABC", "[ c #38528B", "} c #5E7BBC", "| c #3E5994", "1 c #9BA0AC", "2 c #DBD6CB", "3 c #BFBDB9", "4 c #AFAEA9", "5 c #DDD9D0", "6 c #B3B3B6", "7 c #42588C", "8 c #5977BA", "9 c #3A548F", "0 c #5E7CBF", "a c #3F5A96", "b c #9CA1AD", "c c #E4E0D4", "d c #CBC8C2", "e c #575655", "f c #B1AFA9", "g c #EBE7DD", "h c #B4B5B6", "i c #42588E", "j c #5A79BE", "k c #3B5693", "l c #5C79BC", "m c #405A98", "n c #9CA1AC", "o c #E5E0D4", "p c #EBE9E4", "q c #CECCC5", "r c #6D6C6A", "s c #767472", "t c #BAB7B1", "u c #E5E3DE", "v c #EEEAE1", "w c #B1B2B4", "x c #3A538E", "y c #5977BC", "z c #39538D", "A c #374E85", "B c #787D8A", "C c #E3DED1", "D c #ECECE7", "E c #DCE1DA", "F c #C7CBC3", "G c #C4C8C0", "H c #D4D8D1", "I c #E9EAE5", "J c #EAE8E3", "K c #87888D", "L c #374D7F", "M c #375088", "N c #959289", "O c #ECEAE6", "P c #EBEBE6", "Q c #EBEBE7", "R c #EAE9E5", "S c #9C9991", "T c #9E9C99", "U c #E9E7E2", "V c #ECF1EC", "W c #890604", "X c #8D0C0C", "Y c #8D0D0D", "Z c #8A0302", "` c #ECF2ED", " . c #A09F9C", ".. c #9C9B98", "+. c #ECF0EB", "@. c #93110F", "#. c #CA1D1E", "$. c #CC1E1E", "%. c #BB0D0D", "&. c #9F9E9B", "*. c #9A1211", "=. c #D42222", "-. c #D32021", ";. c #CE807D", ">. c #EDF0EB", ",. c #94110F", "'. c #BE1B1B", "). c #BD1919", "!. c #6F2422", "~. c #A4A2A0", "{. c #F4F2EE", "]. c #F7FCF7", "^. c #9A1110", "/. c #D11E20", "(. c #D21F20", "_. c #C20D0D", ":. c #F7FDF8", "<. c #A6A6A3", "[. c #585550", "}. c #595853", "|. c #51423C", "1. c #52120B", "2. c #591610", "3. c #54120B", "4. c #513D36", "5. c #595953", "6. c #5A5852", "7. c #FFFFFF", "7.7.7.7.7.7.7.. + 7.7.7.7.7.7.7.", "7.7.7.7.7.7.@ # $ % 7.7.7.7.7.7.", "7.7.7.7.7.& * = - ; % 7.7.7.7.7.", "7.7.7.7.@ > , ' ) ! ~ % 7.7.7.7.", "7.7.7.{ * ] ^ / ( _ : < [ 7.7.7.", "7.7.{ } | 1 2 3 4 5 6 7 8 [ 7.7.", "7.9 0 a b c d e e f g h i j @ 7.", "k l m n o p q r s t u v w x y z ", "x A B C p D E F G H I J g K L M ", "7.7.N O P Q Q Q Q Q Q Q R S 7.7.", "7.7.T U V Q W X Y Z Q ` U .7.7.", "7.7...U +.Q @.#.$.%.Q V U &.7.7.", "7.7...U +.Q *.=.-.;.Q >.U &.7.7.", "7.7...U +.Q ,.'.).!.Q >.U &.7.7.", "7.7.~.{.].Q ^./.(._.Q :.{.<.7.7.", "7.7.[.[.}.|.1.2.2.3.4.5.[.6.7.7."}; tqsl-2.0/apps/help/0000775000076400007640000000000012231073120014230 5ustar rmurphyrmurphytqsl-2.0/apps/help/tqslapp/0000775000076400007640000000000012231073120015714 5ustar rmurphyrmurphytqsl-2.0/apps/help/tqslapp/update2.bmp0000664000076400007640000061466612231073120020003 0ustar rmurphyrmurphyBM6(p}||ollQPPCBB/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)EEESSSooo|||pooUTT/,)1/-񢟝1/-/,)NNNnnn|||wvvVUUοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾ͿͿ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοο䢟OOOqqqa__-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾ͿͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοο٢-*'VVVRQQ0.,οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿοοοοοοοοο0.,HHH+**οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿͿοοοοοοοο̠222-*'-*'-*'ᥟohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<]7[6R+EECCB?I%ƩG20 @??????A H,leڎfې:fې:ff:fېfې:ff::ې:f:f:fې::f:::ې::ېfې:ff::ې:ff:ېohb-*'-*'ohb{{|ukdB_8^6_7R,ECCC?I%ƩG20 @??????AF)xVJ{{|ohb-*'-*'ohbnnosfgDb:`9a9a:V.EBCAH$ȯG21 @??????@F&{O@nnoohb-*'-*'ohbnnouijGe>dV/BF ŹG21 B@@@@@@AG)yYL{{|::ې:fېohb-*'-*'ohbښrQlEkCkBkAjBjBjBjBa:V0I31 BAAAAAACI+qjڎ:::fېohb-*'-*'ohbz\rKoGoFoFmFmFmFlEkCkCݳÃC,2 A@@AA@AE"M1ff:fېohb-*'-*'ohbǢּsvRsJrIrIrIrIqHpHoHkEoKrMqLrNgBW0T.P)N'K&M&M'O*T2YCң:fې::ېfff:fې:fېffffffff:f:fې:fې:fې:fېfffff:fې:f:fffff::ېf::fې:f:::fېff:fffohb-*'-*'ohb륓ՄbwQuNvMuMuMuMtKsJsKh?`8^9Z2h@jCg@d>b<_9^7[6[6]>pf:fېfff::ff:ې:fې:ې:f::::fې:ې::fېfې::fې:fې:fې:fې:ې::ff:ېfې:f::fېfff:ff::ېf:ې::ې:fېfې:ffohb-*'-*'ohbҕ}[zRyRyQyPyPxPxOqGڅdˢacF}u폏fff:ff:fې:fې:fې:ې:ff:fې:ې::fې:f:fې:fې:fې:fې:ې::fې:fې:fېff:fېf:ff:::fېf:ې:fې:ffohb-*'-*'ohb˫ߍm^YYWW|R\躧e9pGlCiBh@gBhIl^ٸff::ff::ې:fې:fېfې:ffffffff:fې:fېfې:f:fې:ff:fېff:fې:fېf:ې::ې:fېff::ېff::ې:fې:fې:fېfې::fohb-*'-*'ohb땕ٲnb][ZY|R˸߇eoFrIpGmElGmNp^ӕ:::f:f:fې:fې:f:fff:۶f:ff::fff:f:f:f:ې::fې:f:fې:fې:f:ې:ff:f:::fېffff:fffohb-*'-*'ohbؐػ|hca\[WhtJxOvMsMrOrTufᐐfې:ff:fې:fې:fې:fېffohb-*'-*'ohbѐ̿tifb]|RyM{R}W{VzWxXw^Ӑf:::ې:fې:fې:fې:fېffohb-*'-*'ohbؕҿ汜|qlމg܇dׅbЁc~a~hfې:ff::ې:fېffohb-*'-*'ohb배Ŀ뿿ohb-*'-*'ohb٩ohb-*'-*'ohbǨ{{|nnonno{{|ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'騤rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'ͿͿ̽̽˼˼ʻʻʻʻʻ˼˼˼˼˼˼˼̽̽̽̽̽̽̽̽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿ-*'-*';;̽˼ʻʻʻʻʻʻʻʻ˼˼˼˼̽̽̽̽̽̽̽̽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿ-*'-*'ͿͿͿͿ̽̽˼ʻʻʻʻʻʻʻʻʻʻ˼̽̽̽̽̽̽̽̽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿ-*'-*'ͿͿ;;̾̾˼˼˼˼ʻʻʻʻʻʻʻʻ˼̽̽̽̽̽̽̽̾̾̾̾̾̾̾̾̾̾̾̾̾˽̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿ-*'-*';;̽̽˼˽˽˼˼˼˼ʻʻʻʻʻ˼˼˼˼˼̽̽̽̾̾̾̾̾̾̾̾̾̾̾˽˽˽̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿ-*'-*'οο;̽˼˼˼˽˽˽˽˼˼˼ʻʻ˼˼˼˼˼˼˼˼̾̾̾̾̾̾̾̾̾̾˽˽˽˽̾̾̾̾̾̾ͿͿͿͿͿͿͿ-*'-*'~ ͿͿ;;̽˼˼˼˼˼˽˽˽˼˼˼̽˼˼˼˼˼˼˽˽˽̾̾̾̾̾̾˽˽˽˽˽˽̾̾̾ͿͿͿͿͿͿͿͿͿ-*'-*'~ ͿͿ̾;̽̽̽̽˼˼˼˼˼˽˽˼̽̽̽˼˼˼˽˽˽˽˽˽̾̾˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿͿͿ-*'-*' οͿ̾˽˽˽̽̽̽˼˼˼˼˼˽̾̾̾̽̽̽˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽ͿͿͿͿͿͿͿͿW`*4f (P (P")Q#*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fW`-*'-*'UբGW{ }WգGK NLz GKOҠ ~ |ULԢ J;ο;̾̾˽˽˽̽̽̽̽˼˼̽̽̽̾̾̾̽̽̾˽˽˽˽˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿ)-Ny}̳୵୵୵䭵孷嫸諹髹髹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹뫹髹髹譸孵䭵䭵᭶ᳺ᭲y})-N-*'-*'U֤GS{TפH ֤HK Ҡ z գHK ҠWKҠ KҡWӨJ ~YժKWK ~Ϳ̽̽;̾̾˽˽˽̽̽̽;̽̽̽̽̽̾̾̿̾̾̾̾˽˽˽˽˽˽̾̾̾̾ͿͿͿͿͿWZ~tp~p~pppooonnlllllllllllllllllnnooopppp~pt~ȞԄW[-*'-*'UգG } zWҧIWӧI I | UգH |KSҡK ӡ ~XթKѲLUգVzοοͿͿ̾̽̽;̾̾˽˽˽;;;;̽̽̽̽̾̿̿̿̿̾̾̾˽˽̾̾̾̿̿̿ͿͿͿͿͿ &Opzdqdqcrcrcrbtbvbvbv`x`x`y`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`y`x`xbwbvbvbtcrcscsdrdrp{!&O-*'-*'U֤GK ӡ {WӨJWԨJ }WҧI͌ U֤H }KTӢXYժKҲUڦI ٦Hο̾̾ͿͿ̾̾̽;̾̾˽̾̾;;;;;̽̾̾̾̿̿̿̿̾̾̾̾̿̿̿̿ͿͿͿͿ>XfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiRiShSfSfSfTfTfTeTcUcYg>-*'-*'U֤G ֤H {T{ פH }WҧI͌ } zK ҡ KӢVYժKWۨJ } Ϳ̾̾ͿͿ̾̾̽;;Ϳ̾̾̾̾;;;Ϳ̾̾̾̾̾̿̿̿̿̿̿̾̾ͿͿͿ;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\DZDZDZDYFXGWGWHWHWHWIW;-*'-*'UգGWϧI z } |WҦI̋ |WPIKMӡVKԢX| ŀVzͿͿͿ̾̾ͿͿ̾̾;οοͿͿ̾̾̾ͿͿͿͿ̾̾̾̾̾̿̿̾̾̾̾Ϳ 9XfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPkPkPkPkPkPkPkPjPjPjRiRiShSfSfSfTeTeTdTbTbXf>-*'-*' zVפH { J KS}TץIMSԢŃMRݪKMTՆTլMTխNOئDŽÁOPצRѬLͿͿͿ̾̾ͿͿ̾̾̽οοͿ̾̾̾̾;ͿͿͿ̾̾̾̾̾̾ͿͿͿͿ̿̿;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*' yV֤H } zUONHKέSKT蹊}PۨKNPץTܨKSԫLTԭNӉDŽDŽOOץSOգͿͿͿ̾̾ͿͿ̾Ϳ;οοͿͿ̾̾̿ͿͿͿͿ̾̾ͿͿͿͿ̿̿̿ 9Checking for Updates

Checking for Updates

If your computer has access to the internet, you can determine whether a new version of TQSL or its Configuration Data is available by selecting the Help menu's Check for Updates... command.

If an update for TQSL is available, the Update Available dialog will appear, showing

  • the URL from which the new version can be downloaded
  • the URL at which a description of the new version can be reviewed

If a Configuration Data update is available, the Update Available dialog will appear, showing the new version available and providing an OK box that if clicked will download and install the new version:
 

If no updates are available, the No Updates dialog will appear:
 

Click the OK button to dismiss either dialog. tqsl-2.0/apps/help/tqslapp/unlock.htm0000664000076400007640000000076612231073120017732 0ustar rmurphyrmurphyUnlock Private Key

Unlock Private Key

If a private key is password protected, whenever you need to access the private key you will need to supply the password.

In TQSL, you need to unlock the key when you save the certificate to a PKCS#12 file or when you use an existing certificate to sign a certificate request.

tqsl-2.0/apps/help/tqslapp/unlock.bmp0000664000076400007640000002347012231073120017715 0ustar rmurphyrmurphyBM8'.( %  ~~bbb::VV**ff¶BBvv""FF^^rrº~~JJ..nn¾22NN^bjnz~Z^ >>&&RV66ZZjjzzRRbbrvbfVZfjvz~nrFJNR&*26*.:>.2BF>B"&"6:JN¶VV22>>JJ²nnzzbb&&¾º ƾAAAAAAAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA,?P?P-?AAAAA,??M??M-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?"??????????????-?AAAAA,?!????????????????????????-?AAAAA,? ????? ?????????????-?AAAAA,? ????!??? ??????????-?AAAAA,? ????!??? ???????????-?AAAAA,? ????? ????? ?????????????-?AAAAA,? ????????? ???????-?AAAAA,?!???"??????-?AAAAA,?"??"?????-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?M??M?-?AAAAA,?N??N?-?AAAAA,?O?O-?AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA ? ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ?  ?AAAAA ? ?AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAAA??6??AAAAAA??7??AAAAAA??8? ?AAAAA ??????????????????????????????????????????????????????????? ?AAAAA ??????????????????????? ???????????????????????????????????????????????????????????????????? ?AAAAA ?????????????? ??????? ???????????????????????????????????? ????????????? ????? ?AAAAA ????????????????????? ???????????????????????????????????????????????????? ?AAAAA ????????????????????????? ??????????????????????????????????????????????????????? ?AAAAA ?? ?????????? ?????????????????????????? ???????????????????????????? ???????????????????????????????? ?AAAAA ????????????????????????? ????????????????????????????????????????? ?AAAAA ?????C???? ???-? ??AAAAA ? ????C???? ????? ??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAA??AAAAAAAA }{4YsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Prjz%x|yyAAAA YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Prjz%x|yyAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PryAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PryAAAA   YYsF8\ kk99966w] _an: 5oocpp( ZB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr +yAAAA   YYsF8 \ kk9 66w] !''^::`ooc Xp(B7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr yAAAA   YYsF8\ kk9966w] _''^:ooXp( BB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PrhhhhyAAAA  YYsF8 \ kk9966w] _a^::5ooXp( BB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PrmmmmyAAAA   YYsF8\ kk996w] _a'^:f`55ooXp((BB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PrMMyAAAA   YYsF8 kk99] +''^::`obXpB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PryAAAA  YYsF8\ k996] _an^:5obpp(ZB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr$$yAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg( ZZBB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PriiiiyAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg( ZZBB7 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr))))yAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr yAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Pr yAAAA   YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&PryAAAA YYsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Prjz%x|yyAAAA }{4YsF8\ kk9ed6w] _a'nn^:f`55oocbXXppg(ZZB77 llNN;11**EvvLRR<,"ttVVJSS=uu-UU>/HT2K##WIDD.GCC3!!Oq@@Q0[&&Prjz%x|yyAAAAAAAAAAtqsl-2.0/apps/help/tqslapp/tqslstyle.css0000664000076400007640000000076612231073120020503 0ustar rmurphyrmurphyH3{font-family:"Arial" sans-serif;font-size:24px;} H4{font-family:"Arial" sans-serif;font-size:22px;} H5{font-family:"Arial" sans-serif;font-size:18px;} p{font-family:"Arial" sans-serif;font-size:16px;} body{font-family:"Arial" sans-serif;font-size:16px;} ul{font-family:"Arial" sans-serif;font-size:16px;line-height:150%} ol{font-family:"Arial" sans-serif;font-size:16px;line-height:150%} table {width:100%;font-family:"Arial" sans-serif;font-size:16px;} td {vertical-align:top;padding:5px;} tqsl-2.0/apps/help/tqslapp/tqslapp.hhp0000664000076400007640000000030312231073120020075 0ustar rmurphyrmurphy[OPTIONS] Compiled file=tqslapp.chm Contents file=contents.hhc Default topic=main.htm Display compile progress=No Language=0x409 English (United States) Title=TQSL Help [INFOTYPES] tqsl-2.0/apps/help/tqslapp/tqslapp.chm0000664000076400007640000266043412231073120020110 0ustar rmurphyrmurphyITSF`[=p |{ "|{ "`xTa ITSPT  j].!"TPMGL'//#IDXHDRX/#ITBITS /#STRINGSTY/#SYSTEMF/#TOPICSX@/#URLSTRH /#URLTBL0 /$FIftiMain /$OBJINST?/$WWAssociativeLinks//$WWAssociativeLinks/Property/$WWKeywordLinks//$WWKeywordLinks/Property /about.bmpq6 /addcert1.bmpf/addcertaccept.htm K/addcertreq.htm /additional-info.htmso/backuprestore.htm] /cabrillo.htmcc/certaccept.htmM/certaccept1.bmpo6/certaccept2.bmp76 /certreq.htm:K /certreq1.bmpf/certs-icons.htmkf /cmdline.htmQe/configops.htm ,/configxml.htm! /contents.hhc /daterng.bmp#N /daterng.htm=J/deletecert.htm /diagmode.htmk/duplicate.bmpG /example1.htmS/expiration.bmpy/expiration.htm@ /expired.bmp6 /fileops.htm-/files-icons.htm29 /glossary.htmbP/installation.htmFG /login.htmnx/logopstab.bmpc6 /lotw.htm6 /main.htm6 /moving.htmk /netproxy.htm6i/p12.bmp#n /pending.bmpi /pref-adi.htm(J/pref-adi1.bmp'6/pref-adi2.bmp۰]./pref-adi3.bmp 6 /pref-cab.htmrD/pref-cab1.bmpA6/pref-cab2.bmpw>/pref-cab3.bmp56 /pref-opt.bmpm6 /pref-opt.htm8 /primary.htm5 /qsodata.bmpk /qsodata.htmLB /renewing.htm[0/renewing1.bmp56/renewing2.bmpkf /replaced.bmpQ6/secondarycertops.htm8 /sign1.bmp 6 /signing.htmd /signupload.htm$@/signupload1.bmpU6 /stnloc.bmp. /stnloc.htmRR /stnloc1.bmpmV /stnloc2.bmpCV /stnloc3.bmp™V /stnloc4.bmpo6 /stnloc5.bmp%>/tq5.bmpyn/tq6.bmpg*/tq8.bmp /TQSLCert.bmp׼%/tqslstyle.css v /update.htmfR /update1.bmpA /update2.bmpC6::DataSpace/NameList<(::DataSpace/Storage/MSCompressed/Content`p,::DataSpace/Storage/MSCompressed/ControlDataj)::DataSpace/Storage/MSCompressed/SpanInfob/::DataSpace/Storage/MSCompressed/Transform/List<&_::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/i::DataSpace/Storage/MSCompressed/Transform/{7FC28940-9D31-11D0-9B27-00A0C91E9C7C}/InstanceData/ResetTable@V4r 0\4c@` Uncompressed MSCompressed{7FC28940-9D31-11D0-nLZXC(-np1 L)E`(ns>ubwxx~yyz {`|b}Ć"°LF~nV ()B^FFfHdJXPTNYZazgxiHlBO[RbdkJ@>L n0>H,~8?FYnXr4t|l`D0:8r^dthN !$(f3"6DAK.Q`VZf~RJ~,p.JX0j\@v8:4 (-1"49j:LBEILzPtSW>dx8@0Ф>D4 p 8  b H  > % ( / 5 NI hb Rh k o Lr fy x 4 j * ~ T $  Ƴ ޸  l  z v  ? C PI P Y q u Nx y Jy z z } t , V T J  T   N P   BR HHA Version 4.74.8702$ Z=p main.htm TQSL Helptqslapp contents.hhc  T#SMJ$2TP3U1",qi$h$f p|ZV%·ې 2"/I}svrfwacvInr٥&4Y@@"r= UPѪ}ա(o>}y+/`Zك3E3`o@}ݻn#)ז%r#'7q`6Y3 @4@0!L \f.:StFO7wk~'7C4f6.m 7:P` |D?6!ďLۣ36lQ[}sZmmD GJ$|Pv#ՈoNPɗ״g6mH }.s~q~f ' *)k![jAH+jD+@~ <`Hl "R #D>||U/1Bw"Vxw;b$z*nj IyES{t-D7bo<>^~JPȈєlvECO4B AsA U,#$Q'$`):UH(<ҳ|=XC3-&7duF+KaL xc;77=/.I1=ukjTj vۘ?%_` m MlW6 [ilTSZрKHPōw_=fP NawnxLWG !%}Y{}jn ܑ:x2F ` \?{yC|Tb7PktJjoWvs"hǝu>.(=HLs}6|tJ6ZHzmgIKh<4mz訂#fc6Eo iS;-t_4px($sаGNH` δhw  ܁#S/Axk=H&ϲ ٻg虶 V(wX|p+8p" 7{[HC R)cQ?5009m <Cȧe@HEj?_j3_psnW7l3,(` 1 <:[D> rp{UhJ~Ond^}_-k=B Bh`K|1t+XõA<+pBhxS,N7Qmm "v̒ 3 MW^Yj>QBL 4HQ9׸.h`;?s [Q+ooW!GJ j; x$5(o;:lH88h';UԆq>;̤G@:Ql/;m?%m@oIV9BW4SnK2ptk$ނXgӓIdBJN xT^p:=VSiì8͖Z?{5 0% aO$9 ٥\Y +r6E d t78r()> G\M67ď;1E'D ]o%~q;QR7[bVa'iPi?L xvG'{vF*0\0`j)%Ji,M&#W:dph?,vhbh~{W̾5`:f )KkHGWvsqn!=W1 MpMOK8CCYKR뛵f´uBǟMsף~&b=pqR2q`VZz7wHڧ `̂k%ך xėy{c}h)0rCPVC-/] +%twE1D/Ӏ]g̫h2@zjMސM{JvZGFDD|SzgǦWe{1,_psuΊd(3[g]uoKQ7쓁/~dJSԖBnS%Y:@06pȗ-kJtL0ǏDkڌ:[ 9Mxr鸤T`I9K./J@9\Y}OЋ `W !k~jR標Wո.Q"}?q; &E Y34Ns9RwƃSXokE+|={jh>YA^$KƢ m.%AY 抹!pnI a=Z%䁙/g;]ܕ,@ڣ_num5W n<qW-GhR62ՏD (סd:Ouqy!$b7{9 VE+j{ [GOhKMh%-ꮔu{/>]go^NwK Ɔr‹p(ά /лg?HbS[m ǑULǟ-#2>Dd$=O0' +!}0 'i:|{Yg8R]\_h^tU"?@?7oq5Z&.YgS E$q n=\s₮-d^NzoW>'&ґp](dȿ8H2Ӛj<ܾJ~yi֎!p Rj_s]g{D'@uJ# qf}XX jMI7m7~} R EnEȖXQV*jjW/$ bЪUƫFWn#?DžAC=h#vO+P^{3!n؅St]\PBC"<˜$@/ySֿ|b+xA Κ.wXwQNQZ_kO:fq_ƱP}T{v|B.DC̬7IRCy,ي~6jْނu%1;-9QID]keUʢ]dkDҘTW/` |9՜vgpk\LAϿoXs#ZIp7*ʪ\/Q*[pL2U0 u"af)]׿ ݄<<ףKt;Hd_i(KM?zӅBmVcBS΅wqys v%(jJDQ =7?ao7D ZlÃ5:Tߥ 톜QDLv)xtj{D*>^CNͯE` O|._̙tDi'b~}OՑ~N0^id4 k: t.8 w;|4TY;)hrvZ<0.snj<"?@Mki%]-KÎSp{\R!Kj;BӲƒ%B?6 !C7]E$JJִC'/ *>V:˺x~6sNj|7C:#ah1|֢SaZe}(*/Dثx=gkLG{{`LHweIxJ 1).bw bԫ~`P_~3`xt 9 \Pz(EP6-:/ WU!#ڵP=X]pBN);q0Uyj]h'_݅ aT-J< V>3eN֓ g:u~˗fK`@eyee.Rj͟+>A9T,b}t~ zLh4̚.IJy2RIDSю bxZ_ފsݤMJJ3ƸȘЬJlh \?cį;-˾\6xjȎ1"LOs.drP<''~0rwAi96-1]y娘{q_}A[U0q˅C$ےruY˔4Ǯ_WiCiZ>d}XVӠE $w";@[bm05km DnDwGjG㍍d Y8waOc? x\zI88urxw ~b7l*@iE@^OOnޤJ5k;6ɵ"X9Cն_HpPȵʓ[ i0 XekاS%B31R^iF-k5VC rbwq >ɋ$Z7#ʦvfj0x9 C RJFl?sHYx;> C@*TBz>WRzMg_PBb!99GC #>k&G̅>A6>rp5}oj‚ak! >c ۂV`*S岼i:Fhm/7?Df_/ҿR_7#a&>A[c=k*JAָ@G_VE8l  IuAѴ7ܢ2o='t *^QRh4IEN~t+OEqRJ?vRϸ<ݒDn$3h<l}a1/o:>P4~2Ga'pH\Gn A99֘"#&1zzeOB4%t4VΙ= .NE Q;[G3j(0%Gcɪ*d)^_5KPvc:Vn$FH~G,uD|,,$1"Fll\Ѹ胳t<)Ty+71uei䮏8[i$xA X }YZZۃwjt03ܫ󣻯3PCoE;<]5aT!F:LG`*4~hޑZ2_eƬLqc0$yhYʢ-ۨIT CJB6e <V\%8dٳ35,NKZ}PX?RFjoVt 0duŎG#)Eug8ϒ;Att8n…\,3kSdB l8%~ܟ[ <5W&!nE,9s.51g߆Q=?o"Vd7óAHRO$b[fL#":Vߌ|{r&QF*F(.T[4 E-p%:^=-"U` 4' [S_^u-xǠ4QU5C {}.r QjV#:ܞ_czZz0ȣP-/ک~=in%lc̼*IJv(3mx(F (|Q2/xk@ZTwBTj[:+PlhڽqbD-qn|tlbѓ_ b9s{uIӠ6|f% /Z0\-K*H4T67YT,> }n lNXY0uyI,Cż)xB(]V=Cud-~o0ic5xnl[8$]e?4$2!c[ a{e+dn g`n=l|^IҾ5 z*%&A/l7_z4z{FK=*@PӔvAVbaHIkPטC+)7<0N *a7/ߐ[!y[bQWnQQI\$v ELA,(?#Wj9_eIe-z E9ɕCnD{0fg7j_Q9,!oeM8fcK=U}i|!`p`5U16|or&i}jdˌNϮu|柕dR_ϷSb3OmXH- ;W{Q$uln5.{:J }HmIԄĿBnt:?䖏z/ ~dmah hTٍ*xG^ wS^K*C7G]Nd4]_[ts +Y΁~FB($TMV/os^G>C+쒶Dڦ t|=pYbv CrK~[D_ೋ _ a_,! Z<.$]9D⸕랢p3(. L\}8ގKtNOx]6B'L]62 X"\' ) 4 q?,Ae2QlL9bYe+PbMMm_Ѳ@bl\mv{4#;0MVm2j> LnP©o謔hY\@^OmRrqe#68a`!/Di+r>喎8aM[đ&[G``Jc"c\~?f6D2lփ?J 4~wmkdLuu踪S mPb3s/ JڤU 0NqL`falw aQbZ*)#Q/BC5|q*Ymt[:Vr1O1I O>QO>L@Q5@`kZ}?A{sCu- |)Y碡tՍ?#wτBtLEfȈ[źCxD&Nv5c%T93U< FATW>`z ҅ٶj.gI[^4tbOMR_򅷴ζX]t5@_R^D(e|ΜqFe.!="1!ҦɨPc纬}a"l񌥷Kmb\ĔþkHV! 05lh?薣pnV3䪪NJ`GU,our*u2w[{`\hvPnyBf_wB9 i^~:B# u]Ȑ兛sVSEYS0D 7UbWl Xo0k;qFgC;hgNʳp6+J cGyqFK="tgtw#h4]?앵C_Zj:^}0 (G9Z특W )m떞Sϥ|R| 9v%DĦ[1kI5mymmbíE?u"[\rqIDv'׵/Ɉwc6C+cb*nHZ'!lV@ZVY\/Q-N}r Ithj&n'&`LޟV 0 aaԷE&ZLElpb7Nb[ g7_ FIo%c2a'{0Jב]{Fi>á ?I W]1H(pxnkl${*Ď݁Mbonw*ke`?S6^l?qj~Dl5U~_/VJY@ #aNݖ="݂idiKp2l)SS Js7VăU=k\p&s5Æ胀֍:}I/J}>hQ2K %!qOq8uMf-[-bV :+H>u}.cVeW._urUc>5z3]L#f>˦ow :̵ Pe^̘< ʠ9NRJ&E;ur{gǿzVVeR WޒHbg5͟:wqQj2W"N(0 -.BA::z[O,f<6@8chhwTNQf>f~5cX^e.D{AJj7ZFg~2_z|5L?X 唻 l@6oI:{:U15PuK(EoU'gKzt 3Xsr> 2֐O|9^"\/W : 8r(Jr4f%_e@z C@͗C"՛J.Pr/Yx0.<`.$ZY]![QF ,wZ2ebsP3TP#oen%j1'k *o&4qi&m^l{%{ЛNvo gp{ߛܹN8@C P ?RA(B~AZŭP n[~nExs373!!"+}9޼ws3w6s..we$ 4WPz @zC 4?B#M(dQr?wRG?y2h_yGK;35bx#͟AGQǂ36 }H‰GP63?C(ʅ@P6TaA@x 07%/b;b&mTo&s WS]dSNCPATcx锁p g7XR .-e'Tg$` 񹿹O Ɓ8so(%In&>QJ\ I-%cc1Hזx&_RV7 A -hLu" Jd*XB|=}Q|@_ ]Qi ^hraᰛeF8T S-@L3Bj=M͂{ՃBC]`-_ UϋmP)dQd:,C7EW,-N,AU-qm٧Z2})+Eۂ6o PǸ_CTR (zs=̬͇)4Qx׫|ο^*\IE;t2/Ԅo&ĚINR82=K_')tdrGZ@Ldfh_7:S96\iM+huå~ p}:9 8?"Q=N.ASf#3.!K(0~xn_`C ܮ/C[0`Gˇ%6\dǍ./԰'Xju/`µc"_*\ȢPpA^dx=lG"vNѓ!w>:1MρLuyæW@Elׇ Ƣ&oڏ@ճ* Cg Kj5.#WÂ(m`/s2mbJe)nbt)Ѣ0M%e \x@hR+ˑ볽 cʮp /yW?\wy5(NAp'7~K!OKKbl#FiK/pxY.dXs 5.~ !fPQhv/\`#g^ز'vdW٭1> }Ojh]'K@xeMb<9W& \zcZB[Fuo ƸDYAW^b@G%6휐4iDG %ԜW҄Smej'īgTfėgSNk7,pmyoNs >lYyT;Cn ̀;ukIb=,j/V3cÍ:-kQ[fLl x$eCN |hA @m 4V.FԤ 5DteH?= YLvskB07LJ{Z}ۊw-hS/7F^8cA&gG%|gKb+xfG-S7U=!JxCr$ Pɋ-R>$K+[KYaNQkil-lR֋ IH=U> ~q+cz4-Kˬ{xNsb{49FtF M!9XqpBaK`~>@ s;ZNw4PIRV3RH3ac4`ѫ~;]A1Ҧ O&烳Vҩ="VŅ?]/VWk,Bcc3Dъ zڝ,& A=e=SN nA%$,q/ bNX^zmL&hwPF> 5FI&~%N9VTn9Ŷ~(yԣ-38x_K ގO"…=+ N4LyVq:]4_S'M}` pE-7ʵϕ5rӔ8z,~Ń|錃X {ktzXj;,lű'4)|g z\P*.o`5r<P&&F15էǑƊTyuPnݧqѧW))eqGv9}-<⎢w:b,Ex{.(U]Es,w] rU Ѝ+&SAʗq\d\-JwŽ^:Ey ut4wօ)$itzwR%kK j3&BM97&$fL'_ 8II}?TydhXw0vV.^ojj#K^ emW:D>t6m)$<֣Wn'_袦% ܍+>غ=?>P%Il'˜*tES߉5ݗ9 ECެWɥRvha/֋/y1).@h͇7| #q|vc^&ژP~_x+|2 TR1,ouA}4Mq^G|s[l)JS%͜05FՂ F TL랆:Ǻ:p5nUX23q)#+O=nlKܲDmzS R"rDVۧ{~.)֎/2`?38qȠgQU k,懚2+z?gdRE?d|_,8ʦN13%î?:zoMp 3 ȶs V=6=?چ.-=wa8U~֬XWUx_=f8NxM(XZEV(TL ,o u0W7ƴ&3؊$'+h*J~э*fi?I%J -,-4ݳ:uMv[e$?ېX$G9"y0>`4dH^~myc]uS"*Eb\RK ӭmQ-eȸF5 i->T}0 -kB?qbcmb%>B| B#zƐH{1 xn`)sbY.O5%U@qWq~#ܯ-egQI}\t Xȩ*YތDt}۴2(>F5,fjuAM QHbb5za9"Jm0@!y{1km~)3a*h0cDRio- V팉_~z(?G;u.@P@w d 3cd=o' &=k |>Ζy!B%5I+S+)Jkୁw1Xr'gygsu}:8ŕA}Q4XCI*=8Qg̮8_^Ⱥ=;\Wݘك^ݞmE]Sl<)8ћoM;nTIĶQ*S'rR_ ?WģAVAj;CG *ٜal؞} ]f8? fJ)3j45dʓv0Ѝi0Kf2櫱fz=@vۂ8/5'P Sʆ!cgosF(S@k >*1{[ߺ\_ʹ!Yʶ$=]!flN|>>`k,QA|g9UNbyb`TS ı6o! [=Y88eנfloy1K HÒƇJ#-+2ﲘ/^a^` 3\ŷ 4=!UG_OBU==PsSlca48Σ'ğBJ%4 4ڠ0nohg n?/ Fw&6`^qlUMBBhVg1m٘k: !s{Sxw?EQ9t89݉P} btZv=/_@o# j@/'Ҿ`‰XwtL xBE?bG``i;U͌s\ŗ7ޚT<ȏ*bz:K߈IGB s斥G#ˋn]=4J }Iל݃OK$,\PCno[JT_]fp\JvZtO\"_r8_"kWmls߃=.%q䬔-'z4ցnU,~/=1y|G|R9EPWS|ڡB"'էt, j\MLw*m% *YcU@82dk'5BvpBwk4 )ˇ*dY)a'lw@rǬ]xzo n/~+[!RngFY#-1N6 +7S)Yv\^4㬋43 gJEɎԇ±}b\X1Q#f-56|q,5Y I#4Z|&nARY+$̔~dchx {%%8ű6h'?Am$d͢O8E@jc{|EJ.WZWq-wҦwkXkbVV.ūt$ 0sG?&y>' Mpx"Lsim"͎6YtP~# \Wx6?^ɞ!Fo .Vt{: F߫҈Wojߘ29Q>S9i2ڿqw=giBKE=;Ի~_0shB@k~p'pfoN8K/߁)慊/bRD+O;A`rK _2H(k|+$b#vWd ^5lHfZ=NeVLrXXVQ? U`@^;,/p[:T.heMM_p>A޲"*PQ^lfUW>Rob.Qڱ' ;x}I,>׍8Ag^m&1E9 9jSzL |?5a/ FV.mª`0J^su9 g5la0i8K-j(2딬E ؼ07-\HSCIQfZI(ȡ!"}q ҸB, n3:r ʾ3-=u"hܷ]M/ Kr C٧KD$J myCԜࡇP= OgrM 2eadkU%}^ PdUA`R7¡O#ːֳ#t8_͙fo}W31:j'}5ܒHHu$IE#m6?{bqB2>c*VxQ[(%ƀ~Q^˛v[m>èFck3J.='o#iLwvh]ey B|Rl= ̲ů[TU\s (#`UMQ|w.PwT晡r)! ;C%Tu!XA(MK"w38Z /fbMlܱAiWnZ5Vz@?%6VFi@`Q;cǭM˪~Ɓw/ܑ W)y[{ 1¸K}2t [e':i !wy56LQ(4V>É|q{}{?ciME#xssm҄A1~Vu 14.nu33 ֛inM# 8óc0G0 fŠC`쵍.ʍYxp`+\}04#/ ߳\tσ6Bs $s ` **[&K˸&#w9W\mꫪϋgS=CIܢcp*8 o%VxnEHaj,X,E MФ[LD]%L$!kc7@dmM{9ಃ$VPzϝv{ex T% 5*ɩ.52j Xaΰx{yTd̡>̈븹PKGȬ jZcFǃD RaK?8&L%])wŃ]"7{cm߷)2qjܔ&=ktvd'  U2Mh8߷s_+@ngmKvOL&_$6)'ĭ@QG,zުC"ޘ5&#y4M(u|'81NU+V;yPK.הƗH ܱg)alEӸ}U/wu`XcP>bUsz) k['.G$H QrA S[#!42 bQR^HJ=[ UUeȯ,ObK`'"LDY.F컘 Z3i'"8ɡu4;q0=3Kޜ'WD#{Mr:Wz;Uź|˧o #퉇x:UͶ)Jy^|ʚ r˯YǯU<z0 *Dm8)z6$q q)q;T ##K[b>vXsiJ(#;d(0Gjxdm4octy~bJY#D8C-$qoKetcӑH !ʭpb =:V03R7F_ۄz]aAsa|͎ۖ jB IR1_=g+z;zRiGU,RەĨ2N;W749un%/wD"Jt.Rيx<jͿ) <\<68RrLqY@oy?%g_Pgiz$DܧvYA݅gYL`rۼ$:kW)Zh8ۂh %NY4Ei«oV@ӌT5湕CK4FBT~ƅSV,6Y1ksP|v7Hjq[  R""" r<qY̩SE V>); W̏qy;4~'/N9hX >L8 ܗ wjȧU MbfҌk,TLSv&Akn+G>Yހ[Pkށ`tf1'PXFpbnw?c]6SarZ+06Aj9b d4 \( P HoJ;1{[d4xPJͽNWFP:lBK]ZQ%98jH_TCZ"PגRs8 <@DG}ܰ;=G Jx \7ǘ$#l3&Xf5U!JА]HS7lb<_4 Hqv'JޥO Itcdso4PI:!P!ګٛÏ! L_#IWC/VD u­j9.jp1h':f嬨(rbx[ qn ^Ǹ_r %y:B o   gp]]j^ot@W\kmiCrb_c*] *7>wp8nB-] [翆 ix>cƄYGբ|Iim5z/3=lY: >JCN&h"SW-buGΎք Ԑ8]9>{l54ZLDҘBaxAJIZ+ʱ~i''^ %]ipzG:<d {r2lM! :SQIg>fFؙIU=X=_SRdV3H.ap>" lņk=ujN|-dLl Wz:/8x ο0ܲ;XDl}o3$8@j~+$a(8>-xI>0x~eIsAlercFxh j.CS,M9]Ϋѧݴڥ312|G+X:@ j;ɿ8[@o5{:M\ s^V8uD9 `SK ,(АI~'O )ɞ*hSϨ(K(1GigdYħtQWLhERqa&-JV2EB_vu}7I^r\_6Vt%xw  d2;}`wu&׷pԙɯ;-Mt7'o6UՔ 8jU 1~(e_!$ eW:.VЄS^jG T֬(*lq w{ӡ%j7 ?CS 'dVe} ᪪{L`oXK`)-:!6Tx4gR"1ez[vE<t:03 1b}#uk?tWO&Fx1-uBicm(|`Z" Mc{´ήGng[y*\" Iuh2,-L+ ƾm034+ͺDA ]%-6Nm>V_XkoΪŽ7sch+_#򧢺s B-7852E~O#ZZ\ZUͅ{ap Dafr{]De)u prل6B1jPRFt'lrH'jTY֠-[ h7M^&W)IlJ0B^i6Zts%gr+ku=Tʌ.&fVw%c)eAg?hΔ6@/:Jfz?i[%h;sQ!#ʝ9vNNJH@Äj?.[\aCشXwR,av%$&9)$7U'{ paN&gGy#{3n>@<5=vuZG ʚWgإ໒О*\n+Y X5ށ!ϰ2&@3C_茿^IddI,7?5a=~#ږ9BUT[-b =0rϋ~IH4 _)ґgG5>  <+́퇬$ _Mf@qLI٦}}~h>ր_j׀uEn/!B%GS^,4Jc^'z8FvҪF?зIArct"<l rg3B3{wbzCoMrK}*?F;qj׃rc&P.:ήAVUGhk.HB wNhw-D_j3 ~v$]?=nO J)T=KTj i$R*PSކ|t.Yru r'n n4qiL'K WH2ߕ>zCz2Kg=֮?Mxۣ*cug7&9-3S9PYxW'b%H9Ǽ#B' ʣ(gN䋬F; ﳏ:bj'%PtYV8P'7Nr4𓅦!VF`շf̐eY ENq'u7C )Mtc&xp0234^PoI$MM5j7)vZ%bB rۯmww`\uC?\IM-KnȖ. YB-7hPc342pfg5ZѓNU/NGI\\lM\u7\ІG$`G Cr)c/SVK-HzR0ګSʵ1X&6 Q^ၽ_R`Tod7ҭyf=KDѕ@B>t]('˓tG*MZLQԫUMetTj㎪T`*] @4y:L;@<`2#k]LM})mU2RU/B`i ғxHǿ| R&mՐ5]<"]|{2}PW AIm^PRYTkڦJk1/sznԄg\r 1qWň e"%)\mk_4SS8mT}rVʸV1Rc^2"\jo-wO1j6^rf6GrI|/+sZWND܋UB4tcA&$0S5BNV >eZtq}OMC+3lV799n︞OJ0WӵOP^)d]e)Y۱DX6E~Z 5k=mokk2 :r?~7uuDg7;hSu} G6zihZ"f~[ǐ4+-oݺB%,BsyCQcRܵQk;h?[Vykh(A)'Iw }fmTlGMY;aFzU}Ⲙ:?ЎG"6ּwY!;cXk"^͂?ȕe鬏@74L/tuJYX9ߣJG`=d# Ue*f\q ڪ +ˋQNdoCK P|sdcY|7?֑ }/487T#PZ\1-iѲjU=*#Y9Gˏ{Rٕbd5Y>2z[&9{kX}Ą8ū-aLz%] ܙPè|kh/ϱ3ϴ2*/4-ˬOńGomJjW[sY\0O8lk7_ 5"z}͐rt  ~~@PZr5y@YGKٷ|>]s^5L}F4Gi/~y쿲o9QȺǥHP'!(f^M?&FT{8̗z>]CtDK\-ӂoݸIߪ+uBK]jg:!"ǭ:gxrlp]tۅ'-ЮJJ/Kit>gy4߸g↟ 5?cߞ5{IvlRt}-QzbsW99Mv}2 ]FbLÏH*?,4n1)W"EmJR<^q?b()WߊUEP`rN^)>ƴ8Ff[;83lͽb5ڶCnޯLcqׯЩjuk<mkȾILX<[ 2ۿuFKӄ5)7 E5FDhGvc3M`5M1|n?Bw4}w)\?F-}Lmyدe7zTG ySBL):ΐ4 }8UBHˎPlPr?g7 ?O<^;w5>(;>!s%[dW8?~ffЌyɖtȀȍJWxzH#[VauL70.quF}z| 0gEr~հ(gPksA{p_O^).,1BW)vא L>]'-~J/1m1lL}AXȬh.%m{8`` /@n#&V`O֛EQe'G.\3hzY#[!"YtZX> 1) <=8+i>|{QavI/mɤ%u=)7&nI.FSJ-y{?Sx('Lo~2&:)(A c ; 'o!^(~E F.2!_u%nJ)E>HHr2vXHr{*:M?{wb[DڟOF:$g)O]]ɥIB)(A? EØq=#`: \~N,,=$ >j(^giu!cWQIHd(Vaǯ S+;? sĕZ2tqkyK<|X}>|EvE&DN7[7%/zKH(}ޓ`\(NdKp;#@ԓCB X>$/{Hh@l3@ Em t"H:KZqߟtɖ?vtpƘXnrR\LT>D5 ^x0kߡc;!dpZ6v݃q jrU./# DkPmBAqgA O7>=I:A]9s$b$5 :ߤ`xOGfj |du!^ؾjr']j s`h0 NnYo/ Ir O xN2 st'j-1:ozPm̕`d:pR&H7pb4]클 euU%*{,Y@=fXMVOyC2S$sͤr,yL|"hU5+:[T誈;>4Nڠ3~3M(-=(0jBVeJ߭օyj#M:=#Vb̈5P⥶P5 X@$JZBy+H%I~Tb3,HVqRͼ} n)[qvuD"/Es($9ut9FTAMfU|ʜQ 5M|ńֆEa]}b0" 2j)dˍ]з)=G:lEFjަ%BaG5jNӧ"`Q26?BrMS"7qؤZ65BйWʫ45^dPP 5Jd9 1|7FrԈenF`Hp&Rdw>RO@*֡/) 2?N/袆:@8՛;G\ASPK &$H@rM,))1=_!j0׏.;f=185r KO}85 y %dj?S1M3ء*4iꄷp,Q^5y!D7> 'NFpԛ=oӑ5'Z_iypFԹ!0y[0WG$4`2 0`A:1@(r9V4  q2$Rp6D!c' TE!(W4ˋO.5њnBFU{nԵ}B(Lyx89@=GpgOfǽ-v'EgHf@^ksyJ@8@4>eP ;~#&NHxX`sZ? t0r&i^ 2@:p&<@3?#OʊLeff"Պ܀%&kjy64 vjsFXd7mlڍ IYCIkNo41w]})P&pvP`,G T5 #,Z.'AǘM1Row:OChH#޷҉UsܟV~X\'QtIښ! 5 %\B ]*o{G*Ve2л&*`.3WzqcfjEIJKb+1\f\M%Ah*u/Xg_źؙ\,U 2iԪYqJ5Uy6Q0 kw|wZ^KFX*s\#hlaXx ,@ghI@-[̼ 37{Rh^ "PU~)7\gxB ŨBp̈MAF/-,:Ȥ<f!8Q,`#tpPMU;7V꽒v^\ NLN<]}SͲ:W_pBOقhj+], ɝoc{RW_}(wxlzO@񼀋bR] P5i96+;I4Kp0<@1>pû!p` %;HPqAX Ww>-,-}%E      X !%E nloTp @">A@VU0 ZC'O[+~,S:o?. @ @ '՟`5 $;@ @ @  m"2PUWO)t~F'{75S\Bo5C ki{I;'ccZ_mX\jpi{}^~y7';X?@  0z@@EPUU] [gjmom=V8bYΔQ+v3rkQ/@z\n tU-󀋸'w_@yl8wr@N-̧T(gvsJ;@?YP;"~ P(]PX q25UWO)t~F'**ٵ7fm69Ʒna hڡ9!LELSRO:*:MSR~O@@̃pF1"pMs*_ &3K#?۷ş[ɏWnw6ݝr6o4Yg//W_]j7t4 G.N} 42 02xn9 msy2,;|B_MTwoWxgu[Gk5lX6y"ܺܲ?@4/9eDx߿"C-^uO5+`m./u;~|nYȜF ܲxO9 xPrĈ 0E}R94D3@UڣqFPG9׃c7m *jC7DN&ƲB%HXm#}ƶ؄h2Cj7ND_|j;fVk%7DN7Z *Ww"_af q243pWoDq'PZQ@,4h8-|D|y ewn$3GDho2~o2u}e3.Pa-veF uHBM2Fb v:yT#[k~CD;[y]+5ӗ"[&KY{凌uW*=)dc'JyGۣۉ,qSzr^=iT\N+>XDB&VkfOKѤu}f5Fbź1E^\DbұDcm1i0%=ma8f~{1YCֺ̜`)'шHbIVDX62e&Ft/a~\c ,MhT’!x M1YIѨi%iCR+@_ ©d\dǰ;:xN+Ɂ?rq~pPbf>w _qWuQG:9QK;=ߪ؅e2!l}w44xU u8٭ o\Js Y.Bn;Uҧ٦KVY>i32?(zeRCžwM1VVA>=Sd[.dΊKHg屑ޑ}_HׄZY:z3S>,A =\b-2*཭?y2l#gQ}+24A*Y*\}BOb_5&Z:sX|So.:R@Ul.qv .[[c|L3 @Gn/E|+ݐa6xstP剋;_B"@ 8_0Qc*X̝O ¡o.O6ڸF1Ѩ%$*ZgCX&<O(q  XQaG򓹍4IVDXH7& ƲƻP L']gnffFim/BHTΈo.,T3esD=Q"Ҳ5`o~~ /iKmdF#TXCnzԂO n|Pk;IRa\߬%|ZOLH:,)7!,חoIUgX.Tsrix~y@~rm(ȑ':T ILJ+m2cL,s'wrFo0>Y>k;w=1kF9oS$n(WzP\EzbIL#`$r¾Ne+9}:&3ˣJɾH`7I> Nrg~,v]Dd;g9۳.3jyr{5.RNg4~mփbbC#PHMDy觼΍_گJq4> ^~Me"=o0zBg٠c\EDj{$ɷBdzE__0)H# o*]e7EHa2 !˾>J{3n=@Ԉ'bs V-*#YιL>0m VX5Dn`_<\+-DS7;HT`* q242`V!O<<@$4|)MT|hBHmwݫskH` X>պO#ݤ&\Q{d%޶J\NpuF|!cRk o$Lʅ->.YA` Ds{$( H{^"Hx@!@?ѯvI/q%E)2?^Ҿ9.Ū i -zU636㆏H<ςJh<_jw?^.*m(ZE7dz'P>eӘkŹeڋz+& !GHe-';FgYZ.<\Ԛ?tWs6='֥c(}?RrO]م`tY6PXY[%D'wRNfmW]ֺsubt,9p=Gy\ۋW|s.( ~>gfMcWKX0[rPk=IP$,6<'?OԘ=EO=3E8L䪿n{|)w-2]R6Up5T?s̡>e/?/H.kLKlC׳0]1=4WٳWgkN20z1(&ӚιC,rgK5f^{9O }8ږ+f ۑmF=PeZ;Wؖʓb.GԠm#g|">\uG˷,lp;>-d)x`Vˈ?w۱ >+}Yv>}Zj".:%etzV. >YtuDťjs,?ka!걠w¬feevO oKKEܦĝ"]ߪ0fUnT_{jRqѭWٷ.e1}t0 5wХC" -fe7PyIvE`yZv%A :hT-dmWH0?n4 z0YčI6;ew9y2/-]͂$O͵)1&d# tK6)3 ms0?VcDr+ Zn9PUHuz/R݅ [ WUج,ڵnW򮞷=J<:~:ίQ) ZRNޒjx9T⹣ѻpU>gVCWTb!f#kM`&<=^.oL+BƶLHڸ/$m,I c߉R ~0P@Hs<1S ?to71>*G&Yo梟ܯF-Lo+DZiakdQj*MVSIOq[f?c4ϗEj.n{JHP^R xI,:|e*24 Cc}ӡm)![%˥IcSu]IxM׍2;1P.ȽTA,ŠT1^U7*RDa_z/ Zpޱr=%,hRDЕ$z{U P谪ZN$[}ԟg xiw!6oPuJ/Ty˂ E r#l6G`hմ09mLVj}9G,zp/>8B!@ ! .]f.m0Wz= & lF"p\@. QˌkP>B9irÔH,<I2)uVx~˭OD/A |`!8[lL‚Ÿ+2~(S)4#Cp5op,ծ6m?mw 99Òp7-Kii$rsH(@|q.tP)5C mۧMqݯͯڮ޶۶P jo/9ٻ{&Ͳ|rum܍Ė2Ze{K  0 1Ѹַ .6p]#|{Aż Fjfﮰ{vwֱќX8C5 U,x> ddjiZ/ECI6(4,ES 3"4 wM>BKa_`@/9~̴M{N}-:s\ P^g=ڵHW%abj9jFx 8Ĵ1QYG"ap H?C#n)^Eq,3ŌX 2GKJyEQIYG՛YDǔ.j 9G@k8g)t#QI6#?JJ "$[rP+U*9:H bȨC_sK6ѫbSIH1byY~LHʡWS6%?1I܃ 6' %67#+E (Lrt X[0& d"R>w(ܚtIHаJTtIsԙf7rv3 EPl-.T$4I9AP&=Ns0~vGMnkYw ɻw;;f*.i:"P8쾂B֠BǗ$T4,`2LlQF8ugK$QgtÁEױΒH|䰔[$hH㑼;apK(Xh7*S'Y[άu X$6SRPAhCJa]R*,kFr. QAm kў'u617kITL!WbNRj2cÌ E-6O;)]wBN>s8Ma}| Ejb l̍v4ц1!h&ri@X@FQrgHmC2 3IJ؂ma&qmh=Vn O02^BI'G zLDQHz)IϱjdT&6*F)w+QL^Hs*Wd$|F2 Xpd,ZY(n:X"ָrC٢)%١GVfjJuam} I%^]˴֬Sb#,(M7~= 0IIiiɧ H'ehY\[=(qQiFҋ9c ƭq\rұ#:hG4^N?E J.A0(r{*Q@9{,8&gڎ$)nA(>^8BVCH}xg'~ tb~z#wpǯȿo'}_zʜ%7~­_6o}_|?U]~QG_‹X^lJߒ֥ϳtΪte ׯ5Rvde}܅W;?h;Z#nG ˀ{i| vΰf2% T :-R8LVw>K3SfP'Td~ssvd!|ytsj(tDZ|x-kfݻhd=K3\bQ}7qjU鏰9 zÒ)C[*CsT=&8FN)8!ό}>IJvujk-DQl>M ТIv{)TydއN)?ScrDOU}c/}?ѐ < \xд$Qˠ#qͺL2,t^\0k<o:`l$#?xa3xU]OXm兰~zs1#| |Ԭa9mY/â6eR(L.W*羺{_K`s2Kx^ _+RKyRnί_L?J0-7b$0cfV7{a:݆y;s/JfF ˒u,߰'xsqƤ'fL˻cʉݶηuQS|A& `2 T¡3;EJ훥Ҋ=Q+3nkӻ.njcV>CM%.WH]LJBh]n&ܹt,A#њƿ:h}vҔ?'~`ޛnHsMK@uHiv^4fx9Z(!x*##WX$Q\n}D0Bc)Y|n,,Yx-sxD,^Kٜ矐藧e{_6c }1=9oaD:P:kB]G5ƿnY'63q/S$/$[<43++^t} H=xK3h750VB> GE9 hV=eڔje/02[DfϓA&;R^f&ȕEUJLQkL7c i 3_(V6_'z) %~Ι[dۜJmXI6~8| {&Xc=#'3nuy?j[6}DȾf̏!Xx)]e܆%ssm>5n.]g5hiKi.,zF֮JV2d n&^wuyK a1̖WT+zf [lh *[E#z=ʩ"r^juɓp_09oeϞ,绚){Gaz`A! ?M;g`o蜟Yk-<l.ySH sW[}33/,bvr yaQH q}|59fHQarz!vM .LȐ٘h1y\M=lM`ܠt{#a z#=iUaE^~"N 7"9tG*31+x]~(:1)#bQ\^0yҖu4#ieFx0Lfj@n xF,sXuK9<Έy˺{ ugʵQPr՜qRV9aq,Č5?oA΁XJhxN7DHKࢹ"!JGo?xof+qguq ՓnGr?`|9従DdI>^8{DkW'5)\W f?WU483+I$W\^ʗ)E*sFBd^R8N>NOj3$qGrN5p"^7.Vh;!al$ 8rjQxF´}Jp[R7]rYE؇Q};On!H(EXCڟʹ Hb2-,=rEE {PݦꦻX`tiiam qi7S2 ^72 Ũ2u>zu~´zĮ"Y.s {3` ;nwCGщm5hD5U|bગU 㾽Oq *:?| oBMzLfFp.MERz4>aīHANna+IʈdQ8x;U,)x찗X7;l2E0?ԟXvhHWAdEU0&i%'HiHҫK)߼W5aNYv$it[D E5?Bq@1s+'$GHIӰ6-qE֫~fQP\nU!Zݱ4vēM)?Wf_]ӌC_]żqW'Nȗ8|v 6@9CUCS5ՠT +VW3<);eq^w0-Bt~͡LquL.E]#3([PEvC^HQ"P\YLޡ݌z5zD?yJwG2O3$OFBgQ՛ͽ3CiFhT=%2(ߟsz Ð RDbOH F =kȴoY+DA\t=/fla>7)$)IXqsB}@0XgAGHNr3gZW.{SW^;J2ho3QZ֐㞜 0H`1r)EK=<0P13U0&5`bn(tk' NBs."3`DV`IfI%ɰ00jA% BJ[[$Đg2@Y*J@W PWT]DATA`4]7_{{޻ݽOٝu{nwnY]V"Z[O) l$ jȨcN' HYE@@1%a#8۾],5Z@@1@xBnBxʥ%U >KzFcFiyvIZ<ŭqItZEM.斻2 )WP Jr΃CWK='= c ΐM%$3*h#(D8Ï}” =WlB6Η>k=N~r#6ķ2Ýez:-f>g3QÉD p+ |A3$ τ\R6 1R"zAIy'%A3բ+V"h!K(Rmg2R/y#﵎ϔ#a(AyAxM.6#$ّ*;!Gd'Eq{2fw+γmvpW~iC\PXÆohERf3f#\kV/9jTd H#ɋI7n'SIIФc[v6f$2?[:_G|˻8=$6nS,+RiB/FIO=s%J #T2〈2Ju&v>!er% CWcRL,Hf7Y/3%wgGrKٞG$Йcwd0MhT'%esm1xM`̅N`F:6$bAb%)q㳓kxj9z2gө;If`2Q >IB:jd55If2ۜ9n?: ]::}R5Go<@GbGv Ip.yUbZCad_ͤt\ܖ؀ٌlX0ߠN-@i,΃K|Sj%K{;Y&,FvKr3n-.&%U&dR2؎X:"K PZnFv>q2$$wJ$Ssu~[۹YZ4ifT\ HeD'FlWm" > ]oZ3|-GU*T3Agpt"!GZ#/6g+dbki>GH}&3ղ&D! -PΣL^z+y.b%R:. $JCb]Ўaɒ_' *j<=|O䘍 +޽(ˎ=[yU2"䴓*/za^q(`Ui!a= 9oiHB᜝2~C|O!eǠsAp% ޻rxV; ߱9};A~3qt9f?r6 ݧuVEwsqOh8KgD[Nnײ9_`n{$ 1t=ݞs" < UKp`Y\_Xza$(YU,8rmֳPo>#+n;d2Z+9$c4U}y#쬻.7AGo~q8^2WFc;|9}C~BȠ5{J&)ggQ}R9g鍨BPQF P0 KYwXOqDA1fߠv;t6,~"]k~j} Nogؤ|, ye ?{O"OQV0`$Y]u6 oސ?ci:r;wq67Tm*<o'IW74UU=,I1.ww._ݻ1a"a[vXUrGp iYU0>uG#6bܧ"xS. K*ϣ,U*`^][wy7,|*!xg.PžIjXͿX/CLzݬ&?!R 'jt$ Huʾj= f( wr'덣{F΄–L`+5T-s0SDL,JDScc'F-Hc ԯ0g§vŀ0. 8Q .X5Q}|cWa] *`_f_S \$V(;JbN@8cZhZhΡ r25"`F3pqx܀F)@[TUmiL}*!"FSIĶ>*I&Ҋ(EJUMaslxF9hƠI@U/=Sa^@KB Dc\N)8&R֘_b'5I '1q"CPCͦ<> t0wW,nȎ?F}t ,@6"`Y[,= 1o,@sz,-G+es^xP@ApgaC ew gyk#e;FfwoHp*/ DvO#zq`7&KW gГO43x-wQAPz@d?:5 JG<ɪ@O)`qov*]-.Unu#ձBФ:B/}OMwlhoܙ]l}?`T}Nk; W~~PnҷR[iKٳWJMUL[ַ]=#9o׷pZ4UgJw\a|A5MBOD#4+%Xp n2T#n\i^]Wۚm0We0) pիV+j.ogV{ffАU?c)訅u"U V  ȳ˄Vu79G@ 8~1˳զ寔j7pHєHzBI+ 0"_\IP?t 35Î_vݚg-{q_ڟ^',l[ZMtqs9a7~qU)۟ϟg2?{_Aj"I`5#ַmk|?aKSg~tY-5ǼE_ŝMn9 9 @I`HTܮ`4j~]ǽs\` ˝kKv=xHu'ڰ^C~awy0mQϢ0ml8bg gO|@{E}$J<-Lk7mZ/?|T5I$N d;=U׻c!kP n¯kR`I] |x}m^`_k~uFR&vpL9fvUyDuֳPVͷQ~b`ID1ע]Eo&$KdK09<"ȣ<C ifזטVӭ TɻoFP:o;"AeccYoɓƔq$VKYX;m- (qQbALTJ)RnJ&;p??'L \ $:GVQnwcn@6 JPϱW)Ԩl{Em[oDȍUnT܉y@Fxrj0 |hHQٯ{c<(z[ SaVCŁcc=hQMzUՃgfvJ=bө"ͨ!u^7w_sU p:{N䧪\imcȭxz`k/\Zc^0{1_U1c_8#}SJ{ DޮͳZ;HiԀ\l\s,d%69n;u?FWA3 f +`SLn$.Vi()].ArX46LݩhA Zҁ @2Z;D|!DkKe^UƉ/ ^ŧ.[hB0}z_JTXjўx2eSS_"$fb"c@ٶPšA%@;=#xl.lXlT)aR} HEЭ&@uh|tEc)ˈgcI 6sgV( $>uT:soL,+ >1u'*Jl_\(hs,rջj4?\@R+I2Xd %vhKb Xw1ګf-ig 3ǰc>8? jQ_۔Wu/k<ο3hI0po&cca:K.ގd>ئ/,8kZQ8y)L)ü,)_X<&pYf^`/GayٛtDeb6kxWMS76 ⛗qT\qXY5Z' ]s^#oy!_K}]¾_'#%+ n3E"}ollB0#! oK@Uut0rs G.RVll;Ar1!v "?`d~t}p7C ܆/YE):WqxF.&y$y'މ%' H w>o9v;F64a0"|^"j1xz{xU?N7w_Cf:oW|7yxk;)2ڮz>Mx zNIwB,BXeXz9^1E/٫Vq>S\~$ICg3[/퐳ɊͲ}nj f _IwXeX,Z1%{c\U}_k](k`IE)&n2ĤN ﹼz],9Lb X^h{\b.IWd4yn5,T|$faV/_=h"8K f1cs !yd<]e}J5\򣩌UTp3%X4zp;5Z)C̰&f2)?;>{Je^hȺp;Ns?QSt2T dg0U_hw2*Qw 4ûЭ5/O8*T_\ŖXsK| 1(&Kջg2˾j3e=R>~" ;-Rg)h.91ۣiVŇeHdG 60m$+ ת^fa.|uU M MpRmvy8 Ұ.M'&{z݅yV2Ĕ”(y~-WF{5q 21-Z\~]ݻʂ~~%_+ &l1\EkRG,  ={)m'anJĩ^xɾ'IK[r %b rYoYEW/ ZUڮwX0/K~n?T%?(-EBnw]7NLW9”̽`:1>i?]/YA,ڸM}r>kXUZK* ˮFYm3){ænlN)bxrLۢ[^sJ=hONoKD8ˊk_<=^%R;7A^}'DMtJҩ1)v/k^ܒhBSL_ #Uq?m* 4/I\)uʛƋĩ6͌ 2ynwlm;1Ԩ 6Li1/5.(3Y:kRwU؟&*HSzӓdLZ}hч$[!`V+k%v>^`,J@ Xv'1jSj&]!Z5Z](ڟ+@wS= G–O gh9ے+.R:-B~/TZ'ޱrt`E-;rwm;RN!Ep<ܼ ?/554!NSrD`TW3+[ oH䔮\?OQI8EN|]3~I>-f%4rh.苊F9ʴ4':8-RI\wOpk0"""t{_d\r$k޻+/Yg\"J+/n ^rLf/(̒\O$I(`8EEDu]`2IČ2KX_2K8E`oeq 9| Rwv39fw}ѧ ^N"t"Ƒ$&x# {MĒ|̘ӓ9-L2=K`Eik_2Mp{0ɤ/&]F݂.a8[H#B!|7'/8.E`Q{LEzel5>|=Jv*YlQ-aJqOE`}*KD0{E2vvheO0 n ^+v΋ns %dbXNs.);9d0NvdFtCcjZDEze27:eylf$2HJ),;|XdzgDь ?ǐivjJ}^D84{Q,f(.{*32;LEa2as:`Ϲ|3q\pUXR"+,I,;+u 32ۀTsv`aBgeñ5L*!W ]+vыYu/'tՙV4bHdD1 9:b0cЁU|)zVV|VT!AsuBfClMFL-TƖGdL@u͞!$6t2Y1l늫[n[il%)_͇3ɬEf׭Afа6;ntN[3fy; :MW3:L r(uEcR{ K&)%ֶF8ә(i wNmxOwo_;S&5SzQTs`ً9(Ӂx 5P[LUyrb\ vVn8:C|+CWjsnD;=IDc^asEu"RQL kԒw!U>!BRЮNۊH^IPfc1μ=oyᙢÿwke}YgLZKc9 ,a>=}ާ2rxىxoKc7(-q 늋+E.*>V)>G)FWqۡps*>'ljX>D19/jz|7]rIHtXp-c7HIRWKVUخZ ܺ'Je^oV~Z@Kk}(_ŷH^$2ᢂNk`G,9M lntnUu'V9"{Hn[ tՕ+l<rvvMƧv?pu^Dv593uL k]Id(p ]S+W=;d)æ:o~ X+լ1lcHX:ӛ5*h+ oۙVXi]#W|`/ u1 yLy3|Vbv*G+6{e>3qy!Y(t0<3{x3]S/b}{q">*qݫ]8 ۩$,-zC8D`J^ nBG2g^TMd\t-k5ZujuweWmp6ʦڻ<[jKR(JA~IzPT@\wE4F35}ƁI=tiA=OHRmFzRgQgM MieW $3VDtpBE,ĔJ+mqy*2l%1Sjybxi$' v|s2N !11)egP!`Y&%~y 97E( .ZQ.GgT (ؽLeU*i_}׆Ń*ro/ُȽe^7[_}$'kl?r_-$'ؘ~9쇆bba7/ iFY4%61яǿy7'6:uQb;KO%&_n3/DImRKᛅ^͗v҇'+!$WƨÞęxD(t3Oimv/o'( fcZ|Mm1R㛂7+ow*!&gSfM-R<^ 6COn9=~ԏkpI͜ޤDaءݚ2E9VyY\ m?aLbu꤯Ć^O{;նA^(C|L<;QٕӆD3<>4i|"{kx lAH&O`Ik`rP2ǀY&chrPsIjE5](>)IنƔ@3󄆻x85Ĥ4W{ŸIf\55eρy,S|DTLIʟΔֿ+p|In(J΋bDO$lN+:n7Fz9;Ӗ CR{7Lՙ4y)Q'aÛ4ƓIm4I?~ssE7F;G.4h:{ ق/E$epos\}ZdMH1g٘W͂0=yn0gĆDKaYP‹*϶~?~~%6G1"bR0 bzPhfOia]!,1[kľ^I.`<6v)tT#'ʾN{] 7۴o߶ >_SBqRa +-!ضDUEvBgv :UXz+Mo3326]+(ieb)!$!l4a9$:)*C!!ӴTЈ ~2.̈́o HzB5 (=G5LW6qB)V@e8J9e2!0lud#A:"VqcLE*D}A 252 aCa«uĥQ8Jˌ:PA Tb&~dKȔC!0lVtȤD#/b CR"\o2XC!l0b#6 ԧ1$>/?mF*VqCcYn! jԐ X*e+eQn4<f= 6B}{!tU^5D#4:TX9냥Z=z V8c t)kΕ(&C` ԀGn$_!aMQf(TBth.G-i8^sCgOwR9KB(c浔GE(bp~0Ɨϖ!%.Q#S'*"V`PɅ/RKamhLղntݝ֦8>F؅޴ %m2^+"-hQ UT7ޤxF?[8{XL XniD0(͹L0tCxc>^e~V;Hy/5~yw _}'ۿLk^D6?]ktsZEWniƪ (*FP%)i9\/I ahƫ4|҆{NӞB8LZ߭xB:V:<2'-b"tc &FXHnƊ`{?&éh`:!A#pkQx- q|/Ěhpy5odˢy"Ioed!9Vq_BkҘ ŗ(Ȕ)FD\ʼn;$h5uKǐfI+/v!wD!Z/+ ^ c)$gc!DߚZma0Zh*We>%=݃*2`+u_xIK9%s*I-ngRmAˉREK$0}k94iPbm2X; øvB}0'8l"@)fct0G(l_DjFUh@upY^Xc02fpF3pۦeMHt3~$8l֝0 CNR`ٸnZp0/i.C~xj6#2$#$#`F, -5`rp^G8`||ѿZ5jaˍ11tJhe"ch-d kZAZbB;B.!Y4d!۩T`=jJQEWYPC !i 8Ļ `#!it\sdi؋Nn}0xϫEvPV? ^W9Fc Bﭰ}%52,ckC|[-#Xĵ"k*M[J0jAt\b5CM3BSD{C`/Z!t֟)pG,:Nl%00@ΪGb`0ƃf{_]B9S7w4d.#5ZٸtˬOjn+}3cݻ/!̭1Fk!rF#.FVt׆m̙c1k@k)m3!>΍lFkb:CѺ}{B;tykgkҦ;!'}r<־mYCgYm{~I8U{}\x%Z/hBHyWkkXWm뱯eB nc%2`O+|QCU,YҒf,Yٲ$tY[$lIݖs`j 68 1 q.MP@:U'>|@WRfΌo6n&sro$Ix8 bcomϴe!`A`'}\5EA`9rX#VWx8ii̿ _3{쥒Euk&7Y͜p_AAﳪ[N.eg5G>㊖ӫP߯JSMo[ eE9U{.怄mhR#-C``x~ʾV_]'JȀl̐܆7Q|al uM^,gxCfު^L1@4{8Қ ,f\xC$ Ҙ ʌ,ѹiE`zY\^} 4Ł)E8w\3׍szW^Xهbڇba:G4[t0hIs\on,˨}d[=c;0qfz~O\ =0I޺ XW7X^ è0b>' Šb|Zl .}[y~! aq1c c`b`5`$"`t}MOdž]v޷Aʑ/x.qrQP` E} +lWLX9_qǂ`8p@m'<c~SS3z@a20.o? 7AW;Mo3 RB! ſ?ܩΩZ_̳E:<{NN60X6]皸1@06U+a' uQ12ΆϘs%;. *15iE51` 6gyS^Ad=uߨֶ5J_ui(A7}1B{;*~=,6 2i8~k϶OLlmmjź>J~%/ `O_IW'}]1̽|KS;c[;[{u)6$&fE*a?Uةjm(ޜ'y}~r#+K߇BfdsO3ǿiE+/9w^=,uMJOw(wzJ}5 {((Tȧܿ`E }ڣԕ s^cW0 |7VYe;9ŻBagש;.qnw6M]8<Ҟ^mn1lM9X4fs3XU9F/'F=;>ft 0[;s4۞F'ēХ</]wXޗ zK7ƀA|cXҗ|q6俟ϥ߼γ*X$uY;i/S'i:4nY1cfp‰)`DڝDh+&эS!5B;]rUC;ݦ١R~q G` W攲XfJE:McbTM^:-G[vKS1}cuRIjk<i0"Ww@O~t5Zbk;VC}VW;{>1.=`vy90f{.,s J핪H5S^Dc,"X5Xrcj  DVVX0 @@xd`?2ZPzܦڭVHqwd2qS;sXu+ˋY+81FFzȶapW5.X.ʕ/`b4#[-Pһn11NɵZ(jqыymz< Jc ,e(k0-ĊzȌ4w.hx }wJOƹu8\d\|\_Z|Vg=1!Q,ym;}2-J/:]y>c^0;[[uV⻕uŵw0.jY g R ml'ͦNZ,̢]1-8j/qu ?ƧlF"I`ђ9ǎQA\ G Åw_XjXȶ&R)b%V]'c? TKhy*=5%7-j)$Ӵ[;+t]j*>[ aVnO`B(VÎQdr o}KSv5EzjQ2RR&MoWLERV16!",XcP wc^(zzƥ׉ұ[5VEu"oE>{[g)STA^1]UIUIu + VA21vE!a+`F(1e")-HEvwEY+rVeK^p#EK&<4N/P֪p4߰,/*;{k>J .S&=π;PcC񉾪̔A (H]L+!؋vl,96Ip-sLWzw]jkO=X!0Gm2\חiW>9l gXh]! *F{]&O2o ] ʝ!$e!ha3YD¹t'nLե`_զ4o/W~嶓ɛU;v QAU#y;[UY lnOf0V`)rtN*鮃 '|Aye<:01:rWW'ءoXsuiټos͙XyqU t{=YTQЊ `s 5_1hqW@ ^dp`Ry9lPt]80l݊Kzyi! t4t \OZbkt_ :x/tWYbS$۝ԳvXͷ~N [~GӋ$[ I- ~/VPׅZA"V Ji0֪XJ3пrL0/pz |qSq# -ʸKkV< ߎf?}lPcw=mRUo2vESzaB*JT=wJpo F|-W9ie-k* ˍ2oN$vɰjHzJ&*_LR-H'm U0jYY^_.XA70qd(@+*ģ/؊7!f-zmMRNKi4/X.{Lj9Ev:QH]Iߏd3V%|)-4H£`gfA{;9j0t {̈́wJAA@A'T0߃Au;pi,8G`;A6W WyΕ iLR̃X-|nWvG9ScG O:YF`yE.u"iTQ̨(0Җd(iz`y` )tѿEz?x. ( 3h6nͽڢp`xyx{b޹ts-& >z -߻/16Zu.]YZ?no> u-ߩsM-W֭^BkI۵9-%Qi2Kmun[_3K jKdz`AmkYw9]NŽn)X ^B kSeMm#OzlLUev%j%,ڶyx0 6^ !]e)wFRP *`gEgY iЬ=h!GfqJ**{%H33P%Vj2RE$?0ί`¬[ե/+E8jO P`fzE\:g_ MiI+Gn)8oOO {[ _^f R`?4aHYA!~~\ kN[`'1u'8d@ ?ɇ=~ؙ8FwFkfWoԆ .֞¨hVLȐ h7(bRB4ieO_z yMmd@z~H`^^2ip;2 =@.s ?]LY03VNͰХ?$()9ApEB Q!]3[8c݁!|ꮿWNxCz 3AlW#.Gu/^z\J|I. , ։A _(!e<,bq:؁o!~򘛲X7;OS,ha1Mf?;%X]~<;[Ynz G-˛GDT|4wGxM(܃ fv'+G1>,&8M1Ȝy; N,s`3s* aKܜp:#==j8, +W쬳&v47 AVI*eQD+P]/]v0jL'a '3/!Nl>Q:.+-¿+0n%Vc vv;X3kB.og\y>ٜFȥ#1A @5Kj 9ExaZ)2\9*2EaOnِ⽂GI?eL`#; Ȑ?'ܳsffIl#ČfiNrfEh`;C|b_'YG7 [M9l;NA4X0 D9zs ~#ςhL?t>$̴4.2_]F7@MhZc( p76`Eg' F p쫸&ѽE5`1I@)ğoOilxKgD71[]FDžs\9y/'g~_&Q#~\ZAz["Wg iwg&Q @[+y֋O ^yy!E!.DԶrA@-ֿaFhKp -Fa@{~[ z#Ӿu9xG̛nمhoH83R̤pC>ko78iJ t^Pn֏=:d'l}|' oz1_0`^{s?8_I\ZB%Ղ9}=)8_(Çߴܢѓ`i5mf-5T)phiFW롐F|/{Q9ǵyvžhQt q7Eۋ[U5S)ެ]uKs6b ZMȲI>=mR!~KLPJlL9b:y5/ߚ{t[oTLfums?1.f*:p:lJ. ^(gki`hX&D4dIR To)ޮooe7; d똼ڊh)ǰ4țQ1L:Jy>]ɭKZ yeT+M F0Ul\sVj&训H*YB8gIJseN[Q ϛ߫hvq:0~sbm3`MrIYQ&GS)Ecci *Ã9}xR㕿!CN~$+"BDNL 0p̊">EC}Le4M((XdI?S[mvwݾI{}{g/] wckI{cKCʄh`IH@([2iEѐ@$ K{#[$`ao% sK) ?@syyn̕X̳v-e۬5ʢZgi#a% `yxdD"/ v|,jQF5_woDF%0n^{q_^ c嗪׍QF5ըrNV5VFT"nhu!m9{uTjQ7Te,vbuHNO G"D0`Đu.S(1Ì=tJPF(%5etdY'g)OrIR@l<$WRXC9 ܥJ9^:>czS*'PI2^h =WE!9rm?nؔm_TVD.ٓ~0s_Ov'bOENi_p?~_‰sd8 dTۑpv6v'}Vd!G( o[C9ӡ~x$ǼC݄KI/X|!i8C/r:>^I׃82J'(\nĊˇ+XLo`p1(qqU[۶ρŽGc7a|n$\\.A[=֊ZFcrö2Oۡ >P'j[e5t EPK4is&-[tܹܔHr_mҮSop|LhLnLmuf@lkw 2;j4gFV@v!7΅W0 e:'Sl_mc3أfgxny=7dIL/H>4>H֩dqe C Y"3mK٬&m~5m1U:1~ZG{}5I/4zmSIlx-\G<4JmvLV;' ۋʍ|VZRsts|D:;cYhrڈ$^_0@8/jlmhʓ_.ǜ؂"r1+([G:%,'SG[~B~zy2inMԄ ƹ]K~KLq6T28y)HeKMbn2m6`ȿN`qa%Qʥՙ9)_s`¸@t,lP0O#_}r8{*hoHv^a (P/o S=<`KPk\CHJ-jۇ#C$LÔYNU*+V!#ߕ%@wX]] Fs,T;q  6dd \OQN.aLΙ$S)ٛQ,1 ұpLx:/N+̘O.]kX'r2k\d Y"_\vg*ӯj"Sq_G%E/YBcjݡeHs6<":'xRD^M}n2 %_挺]fq:sh`\_H`5j*d8s|9縎d"ıQFH9.ufFjq_cU\WH0 [nr-y8a'(d ټ*+r]ξE.y%`^' $"G_*ֺ0Q|(( /ߜX{-bI,U;$#gsdyk9Yq sue1s,&9\ 1R_ky6 ƃXq"~dL=m`%``dɭa ~Hq_h"rXZȢ/CIUy/OK&H%p@%5=Av/;!hQ# y'nO_~4cp$j?b)N0eG~ّ[[6^r48yZ)'7In{ .u忌P:=! ,cGˋqa|$tX /,[SѱP{3k1~-`.^bvs>s\D"ggY< J ?~H.]=}y"# $!O(89r_4Ɛ]fa ;w.U^})q{KP1jDpT&HDWb[D|$_<_A@F6*T¤fE/ѣf> 7۽/da"6zQ8M E.V n{ƿuW?=dF=Ff)I1_#SxOMUTfՌQYv5 p82vP%B|mLU`*Qs >9^[`A=?\ro]2`zmJcMsoMKGq6 e:e(# &:PK~/*OX7[ҡKc2-iПARGOKzÆf闩AZlf4L0;L!L-uL/QL=#>l؈QFK}'qac$< jĭ٠_/Hf 3W4+T"jö{Chj {<͉J)cOmO1p<z*,*bc3d`!IpE##RA0ªz_b1SK^1rEō#hIGΟ fV2M5Ϸp2,:Ufsxj]Ym!藢 pD>|0uǦ+]_Xs rZ9!sڂɍSvdX-Mǒb<'FFZ2 ~e  st`YO8itq!!3vFH<'rS?L/1n H8lszyAwZW1]գ@W@QiDr<|'66boڝַ!I,rx_7ӭFoYŖ冁sfCvmqN=d;ŧp):mn\tmoTnݎmUk^9\me_TJ.PѮo<"ĥb+ݨ!DfђoPUHl^Hs|ҝ9˸Y:>! $ U&m^l8x~ZˢNZȻYB4{܌%>#_aΣ>F(m\0: zE"n؝ l2wQ,qc%̕ewfp86mmnj 7ٮ;춳Mv3ڠ3Ag|fg}h_inNUL8]j_XVai^A\ݦ-rP*?кAb0Oa=qrP:92ε'ѷ|P`%FX}rQs)#aKV8&D!tޕ\?ՖԐ w?xHfDދ'u/ֿO9 +fˏA_BEP&/p3-{p V&`mvalriY z-d߭qسH.XVR 9K?eŦ]jaO<]Vk}Tš*? ,ui춙 NKQ6ڙ[#ƵF[J))\}>~=$KE{g~5-ry'RP{^/ۗxoKO;MSG grFtiXt˒e Ir8F'@أ/m^:UJ  sN 2X8K0Q d^Z$+X5y0wXc_INw/ۤ(hL9uZXЯcPp w@B{aف ~Me鑳P(Q˰ic5}C Ǖ ̳k]{3XJKv{rE`'Ҧ`Jەun)gK{E,4/fwٷaھuk."ݭkҰĂ& I6b̘u\otPJj؀}V=z6Pw|5·\,l.iX|W; ʰN>.Շ+ u5I7dz ,i~oECB̰D:KG#&7sAwj1ъu zƌBD+Ca3[^>+!ǖ0U:w[ >`urAgz{cX1́ƅJCeA!q.$yx!J5ꑘf (Ȝɡ?+E˺~9b$$a@]/$wG& B\O ().(ĞdIC2-^mZZS5^IMi0vuakXI.69`e'ȶ&ۛ_[kuW]v k, jkD՛n=ۼq}Gz}ͺ_P2ՕgW|AYct&O/`U2,̭҆ٹ ~d_ZDYR{d }n%@ yzXYAs׵C-8V8$2;| *%MرRw^֛1_2T`KG Q2I@=Ad԰=A0B.3jKO#@!kA]! ێBs( K J b.ŝXYQȟ+s!v%,5"rbȫIX; hm. GkL1\vѹ -wmg#D'sp0'nnzPիX:/;vYOjzFۭsPۨMՑ;]x]^ETh?ڗ1^f ̵)4c`]WkMT{V|CČ )bS}&;٥oYͰSiC988Px!;Xc[hSdZeMįmQ0X!𾿦 ʯ)EE6b B%'2Qf*_xJƊ9RgZ4`9A"hwy& ̜(@S9qlАI!=d3!\[?$_d޼̂r@0VD&~CE(BxM [!yEJBӘhd*mgdV%61iW啹ivGIwMYOvj7Oabż8Z?Zݡ={Ԉ/k=dԣaӋO]XZjRvYKh l@l^z[,4fJT/m_k#MSV޷ {:9e{Pm~Gm1g,[br.Q՟KV5kymPvה``V~Ui;h՚h&^o9[,ڷ=ڵg՞T;~\6TF׽vկ>zyXX-]"/Lk3j MiUjݺw4oD7Fչ^V<-"%W)9"6$;F9)HxE-AΝ_-^b1"-UV3 ru 8+%Ŝ^1")RܬW%V8 :96k`D[bqsY*"j_R5O[Qrxp/&P) ·`Q e6^Z1_QI$[(k* /d-sρUw')$s>mGG0 zGCspGڼvR^Sţn|:_{[܀k-jE1s:?~ fׅKJc_8/Mt 7n]@\^(h U#lC>D=UT&qUxWŏWӛ@/K`UنDr߄ *nlgaaKS:45ͅ!~5dP`>)tP!eb,  V$fpFgMH]Ş lgrag/_ +,4<>1]ລěҨAl{95oЄd^.$ 1Ɓ"C1L^ exW0"4}qd C$=uW{KAD JG4J~wk+ǨEPZ cT`j~8: =p)ۯ̀u)Q 3@ OT݁y7 ji c˅F_+#Fe)=,2gb š z"WP=Y@v */ Y's )A 9|w=9P߶: 1 iSI0dM2e%D88GfF(8**_APjA䅐jIY g. )H8 P>e)FgS`1H]jhv%x9N.edޢ/5JNF^(ďY(̨T_s׷fVJs) FR̤B"ńO!Zbg&-0,GUH?H,QPlbs ,P˘EF_q ])_5MQīB'w>ؕz]3HeddFH@2aDAB Pon߀h 6 Jxf]‘[@{7?x,)_ 6n .VgHFD|7L¬(5 g^@ hQA=E  r}5H~Wc8y"KiI8I,NxfxrO 29|Dv$ - $|vb1U^M5)4@"0*Q@ab Js6.4$ (au,A?POxr-Ђ͛QM,,ݻw׶[9n߮x۳~e5fmy^8Ł]zOCU5vM~WS.G맧~F{5:,jQF5ߨWRݶݫpN/5O~s4'D=sO6"( `\o yVVG׭daonfA{|X\]NmH3v_T}7d3.ۢmHUsqcWM^o/M\ۢ;ܙy~43Km >f ?4O v b*. a\wTՃ/~y^ve{9c%ozXoToޕpnwۯѼOR~ K;4@No9ט f/ ?|z㞓Tᵹ抎ܻzʰB`D8=Иo ͛j3[?uoiQ(;yEkXSr^j"oQ\\TOi5-Tک ߦ n_W@ϗ7y|t(+n=UoVGl޳nѻ,fa;K!XgF:OՊnE7|el~vGmxַ{K^ /_0h93 eK.+pTAP/UU[+58ȋHWEv%DZ !^^n)r0@>34%i^z'm\7MRըjTލ=5pTSOo>KifozKrw˜&Ү/^b"ݼb˰d _0L$=`{O!hb eCy{lF>_*ujm`"+{7pNjNx!/5ߴCA|̻U`= ƕV_0zܳaA/3Px6ƕjf?a'Ȧ`\F.A~?,HQha%a%?7 <1lxf  \R,Ĩ}e_ eߡߢ>\7naC<ղMnЋ_]㗱Qp=Ӷ?EUPlz# C*L/Q 576}Eqn c?W/aA$A mTVҼ$pXǂk,KBECs_.$V\lԀ:I-C eT۔2p$}VL M̈́7`P"NMM+,MݵwײQ@ [-{ε3" [A ZɄ$:3^ b$fWd0{޷{kSTvnEƈ4^AGxއ7x~sZ yX$xr<=t*;a!p]psxpX֖7WXsq"]6 U>NQ%b -KioJlYJIث~SjQF߮&@LaE_iS=ݑVn!z쉳}-l<^zQQeU{Vv?wx-a3QXشqr_pt.kߙ᳣o7.+0o#| U)>sQ4Xw,o`z%8rQgZXIVjy ?[/BoݍW@_bwĦ?|y{)+eo1ṡO,ả28`rԞڱ1Α6ԍ .,rDza$B@Cˏ~| 9)r ' [/*mDY~R_xOS茑Yִ^Dxzy {+v >`NM-%xalYEPx` -9 '|%Lu-A10r1} W d qf sqlD?I,oښ H,)R(512nRHM2 ʨ*|1Z]͕QxtE[Mnu^ՌZiE۹l5Umt[>tM06~M]%c @ ;Zv"25D$ v$RPE\N;:4DtH8!j H R\FY4؀1"#8*{T-g$ZN,|bN,_5]}%*D $Nꀰ8#߇߷oQh4rExD"H\Jns/qEdպ;]ml]%?.SQ/ȅ w6Y3_~Q/:֯E`G5~M^{| 0x-h"@o(ξ+7VQWc>Vuэ@V?`ܹH~FY ł&D@8Q.maqQYeWY]~[]hc o1{ Q]gfnx?iB~:ٞУZ]Kpm~v]}SZsuNSd;+wYސ[U-`5Gjq"yzw?;f[#J3kOym»W*_$0.&F6ִp4`GmP}Y ]c }3z뙮I\Uf|kNvq`&eKҤu}Vݿ,vEkgQߕxզ $ Y""@t^ۮI^h~ qll"e҄գ9?7%m*(píw\;D\WyTw,޴nζ %ng8xDneTΞZnigr$v"c숢V:^rwlyGƛwmN^|ùR#uMV !MP"9?jRIx}vov1v g`x+_3G{|Ko^ݾ7WDZ)'K2gacfcķfzNfSL?~6)\I{,r\sܖ0h:"|OӠ#Ű56`Qm AᒷpSQ\q.L,XlEzRR?g pƥ"Xhz'ؼ|8aU ' Kܾtr@aKXƲQ^LRGǴ*JN8g":`<-#PK X-fL7FY."S+4.kA+8JƸR y\X6bEr#{46TJ;\ N A5;B#l^ly&JڋCJ`D%qC\܋ !y|!.06bBayql!lep0tAF хQIK/_ɦb`-PoLa)6z{bk W)R_x9=bj`-Rb7#I 6-,4,Y]2nd\Xѯ;hq O7ik\Y0"Kr.Yf]ri,xKP*R}}/ԙ5L5WЋ5COE.dg1 ٹ>^T:b/Si`M:^s՝+zW*mP'NAeО Ayc|bO,ˈurؑR=SVIf{ΠQb6y )5J-丹]%A0AX\;$ԗKHDWR*zBI2Aj kY&Qiw uRBjT&aI,Upo*w)Z,߽YJ\Bz ˘/el-\5םJǀA"pXg] *ϴa/UY*}&N}_*|;v$k1  n2E"`o" JvlYeA(x"v!&WAKUB˵PU]޳gmch?;@nF)#D8bcnF3 o% UԖsH2nW5I/"En}MO{<t{ F |s8{ܽZYƕe].1"b?+Ȥ""#_]?a{xu 4yWC>)iB(6T˵].kGRmq&֍ .[m=q6[&TvӻW۔r;f?^fuu]{V'YF=1krSgto/N:ӻq'ÿe۴oqd8a}̺|^+v5c\#e._!r]`߽'g,F+v_+yvJ79:)խj TRʿ}Fin 9] ڦE_UHٿQ.9P@l3j۩$ ՖOlh'dulsLZ1qOs}UU}XW+qk]_sf{0n I7 }_іݡU+9^ n@2W6봑`d'$NT~h%/qoy٥iTNcW.eAdT8q[3xmU{JXѱh۪ڏJJ'Ijgؚ/d&OS`޿} THBilPR~#VWNMQ+3f?iY{d}F/=oaΕc2ןeʕoʬ, BשnG8H\ظx'2_.Ltr(vXd2lϊ2-`>ViVYtVF V6`5u}VL,Ug<P%Wo@q<u8fTS YRӀ> ujgX-Ϥ Y_BA _eq| 0b[OT8X}ur$W]QYNRIMi"pnb%U~^ ֆwg[pF[@݈EeB3bKP̚y|g,s:*R}%> p+/ ΠUV\QḬ>c&<*׻=Uޚ/#OU95빼ͪ}nL+U*.Y5ϭi ~̕Dž oap"PH/F/"KWj<93/GlqEu3OU:leHh5R4uq]) vEw( fMgܥ`>}NYݐ \|/*k^ eB#Bw@> sD9D=8 0*_2# _1͟64?Ճu’s6OnXtzU+9tΕذY+Ž+5:ˠB&@t mC6"w]3Z.WOesU\.~;r=UQ|eC(>''tϙ$%Z)M, L  _i3K3W|^B^$( Ml IJ&''1 <@%Brׯ>fO=6m \"b" .p6.5.ȕP}yObGd d3IcQLaHX*id.":HŇSLc"?GU;~/?ףZ_#G5B=_G! kuPST&c -h<1 ݼ3.DX_a4B`j斧!";:?D9sBh^pCzm^ ;lJ 0g!dL5$ ɦt6fd`zW>`04!IBhFWv:!tr"p3SwerY6lclXMU952 !0B4LY+V ݗ3`˒G[֪VڴǔuC6B!.s2SG#ڌ`n3o9M=MLEk]"/$ּ;~[xI>n+:mBxR]$tmU0w.5[T>!d..*D;}8&XlTG !wJ 1Otu7F90$ 0ml8ـ5dSg{Iz.]=*8 :vihdQ_Wb'ܧZcXprTu6΁eTMbQQKk8%q:!ҍ]U:@:3Or ϭ`Cx_/ zX{B9W'7v'N?6W^_lĻ^?J?=|{=O?z`U+{/6`7pnt6|eU ƽQ2rc`_yl$`BAUBDr h*˚Jbnj$P w*Vm|I gЀBw“|'Y[zgoeں"=!ɰe}g$BUm:jLUWnL<|SKc`VWSHl>4v̠VV e\l=U?W[%lQEW̎h3&R X-VUDtQʭkLqY9]Kݥen.9Ų:6p׫ƅ|%zs X$|)&n6Hj-X2, :QXLzT^V8-浊pqS-!8蹌ϻ[jvI5ibO:M[JpI[-3Lu"|bͬI9EZ뭦seo;BoJɒ7;=)a*3M/ޢi%Ŷي-!qSVO9-Wg-~Ϋ4S Tf[S:-`Tʅ{•N!2':v7pTСsͫmjP6›݈ [qqNoNɍ=[oyLr{lD#@;@JVPJu !L1/6|+{XbOj h%zw9x;ީ]]lT)exLCQ(W7lq_>~ 'PA5`'%wEbQ_CUFEk9m7[mz O/S}fN!tt ؊ikIr$>@@ӱʕʱ])ҫbDZ}YKp1xB?C)/o |̗_/N3 [vEbo)CR>!MI>qe_ݤStru;7@'>@`Y\l_= (f\_^1+!r)π )0ٳ_=S]^f Q>H(@Kz@3SETvP ˴M>ptkw nTUHf \kj])hU*`r S(qVe*R6g^J L9ƺvfZl?WuZ(edj˲PJ0|1'Z3굓M-(vL-]!҆0 .Re ZEv 1zbWdɽ2\d5XU\]eLTh6J!K0x&>jYZJuQU`SMn9RS3Fh„ |]OF3fRT!acE0Wx:=yG [ccRc@y9j0OKqrО[$fXP:h!BxR})`"#8ׇ}'=Ӭ qũɐ&7q0Rb &j)R)r ʟ)f.Wp'.Wo}k-ɟ _jU:W]Wߦ> ] !]~(Td S 0fBB/rd#4' N`4)&r/4[T]ULf8C0U/[B:V'= ȌAr xEz"*懐|ZBaZb/ \<:=No].U Ca [0ꭝ'7f)M6XqgY|Q|v7[GU/IaZ|n0߮p !0 #1Ot%nҰ/Oi`*/'\iY8D^ /n)8 Y-֖[ɜi=svrk6nd{.?C#}Њ@DDwb-̣pt,ǭ,8\RSlG6h}?+*%v5H;UoPBͩ-=nĘRk1X /m8v~ZuS48K* wƷfm;$h6@'4O9b qF DċoTAH{n]wW ic"ΜJ/xm k-.r?-cwMa[J773*iCqga1F=.J=3A(Q6)z*"#ލp3MaKt q(-/Hq` j8\<!ԅ>ee#[>k#<%H9ӀD_[Dx& 3.T16!تx3R|Y |iCb. ly+>mCY!OȗtlE/kO0I0 $_!n}oxCQL)/51/!R1ad}Q $?"8&VcIwFI{L9eLG)<\FR+k ٜNPC,_Fq!2xQh茇B][k²"%#{ {w!6 phƃ_A:d[Z_(D={*MJf*:|zi2ɈA   ={KhB?gY _hC:JQfY.a9vhlŝGb|9(DtE_]:c)_8>A:q9e`Ϩ):X`(!,_{VBlCnv}bCt3: 4YDd2ƨ Q(!`mn[ !}>8ct3<Ё up}jI4C[ MCvʡ!t6!$,_%ZL+T!҇*~j ˏc`):azTb! zߡ*{j>S*G0!:*-HBB?=mʶ(@UyCULbBVp< 8_R߭h/JZ!} !ū/k|vгԄ7F Ve3_yK!`Ő?X9%D!\Ư5uQCߺ 2XP?} pY>~s[M}(,c)` n3C%2 _6& ,d'^Fz:ْu$KKos]6 LS;װ%06<1>AE**_|]?= ݽJn "`x2*РB{-3a!BnIAJCi )l* 0E#FCpWU7y9'ꐰ.bI$S )!tp1@0^E4,p0U'Ν彻o|܋Z8-!Kz'J&xc}EQr/?z'|sߕS뾝P7ۡǺꇋU?=}ѹ#ZA ˘MHHXr%H?iܵkօ;)]n]^ۇ%=MҀAAZ^0F2 1T.dיzۋ߭_9';Jɟ 0daB*JGH10 C:`]NW/\FǏ]ڴOrv}In;nm㻼@'`;9)Ӟ8x,"1c3Cut|.կJ/ n׻o[ wemS 6FIJ*LV u8N1ӛpsl\g6:5ViB:n;v9viUiFt!APT{}{ZoriQ?;;`5G_-O[̨Z[P2*>RW yEtvn,5*4%UѵkGKSem?kA|A0z_.Ojb# ^(9v7ֳeWEc(ȏKΕ-MiZV?pZ!_}ċ\0:`82Q[|a/svVpܵe>zNM><<= it,&7q`@="Y3AZ[Y'r7;:Զv6?g1{Q{%Z;  ] nJ.&Jx9{TfG.Z[FQrЮuEE̾_>`QڬGԁIFз`ފH$ b0u7ma CSC?7cHh0-fxv&Z~*,'K3,5rfwΫmk5[bZMXH `WȃefHd0 Cۀ860yGfavC̗}kqvi:,&_x.)!f(`@=#z`4e ) ăf*aƷ+){[-VZP/7XM5.ͪkkٶqF^BҬDA|A(#T^QRG} yhxL0TAPؗBegd qUb`^$ ^&cFN%CNѪiR'iyyId\5'YOHN1T&˖*SvlrARlnŪybkE&՞rM E|Ef35ZlѾP=Pi⩩Cy|WG j~5,5oh5YfFl>3qz`IY3YFl2TU0H8O b8>H<\  gQp+Qe9fokc5n=Z_!旈 xٕa*{F"*{P,p ?rl&" {ӭhS@ Tu*Aq;<@ ds7u9Ms*Ӊ>|?h:6p957B1-L^8yz-x?4o滳yAA0ܹpjGtn!4|8 >?E2EE=hRc#]F׊Jf3E}=k8_y HXBX;y-moKB|,6xd_z3|ko Qt"0Fx׈>z#͗?TDÔ:1Nu0Fxg{hnc0a9X*1;d 0 Tľ iKX0N1[W1 69QRԂ%!30Fal-a=(AcH`VIo$*5xc$$deK‚xa5159 /Gnrt~IP#5tO(iw'"UwTO^g}wn}i*Uh'0Vno"D dJ|Y] Rw $U_Ku$_so:յGt Yi쒾53 Cg<[e49(d^=};Jhḭ <&R-bV'>},i- &p(RˑtW;q0x1^$O)8p?0 , 4^GDِ !V@QmnQ㨅za^vȍ@ov|)ϐASv ˲u7-++@OQ`X@"ɌOzC&u =/c ԓ˔#O@"!Fh^^KmWF4:\ն' `o Sg r+]V,i,=oA6i`xSÿH7j}#.25dD$;)M(` K0ACM gpLrT9wsN`"A,ԉkv|jZb8 DEīr] xq0b ⥶r_+l%4Y|ذJ.a j(ɇ  (ߺ̷˫ˣχBݟr´:\nTot4t|Ap #HU”XsC ILpkF4l_X Rk9$[s RQibO$pu4RjfaeT,-Ք&-ˌܩD~FV%E ǂ# c䝰%Srh^Ϙ>Tmzl|H<"VG{U D``VHdF$ᡥ|]=2 4]\:0lq_Sb,B>X="0e1@j^( /_LyP^{Cz7*jF Us$8&cOSH BMTh\+%}{.XU ,AT=]}dlywPk 3KisSgM2\i#+&.uװzꎲp'2@{fS+7euW"lZԽFHic'=@=^Š1]! 8ף,ʬS~'߿YռM?딦 {yePpx->PSQBv^zcuP |3W[Tw"&X26(K$SL]Pۘ (d;mͣ( 3FJt P h2 Ї! N,>>KKvuQI 0&Jw4/z̈́S]?6mҔ%=t͹l?%S)LPZ y?++lvfeSEIsǔ 2YPŸ3RgX1zCt]pBJbц @ T $]QU;KB\Gq0ڐ/daxr~ &8y 9\Bː`p]8 jB"eJ`Tnz t60>+Gɬ FMR*NE] y$&A=xF^C`l` nA5Cp`~q2t: $5)tre*9i(ۮ~0@+}3 &EJu(H5 mȯ2<2o3S?ZM{hC\˱!o|7LgeDix*Oyґ1pq|A"8|ʻ)En3?BjGF~`ѾT+R#&vQϧRI!y!O/E:tȃVރb̽qB'I{r щ.Vّ0&`+{"Υ% LRs3?Dxư_Qo]* {wu˷=! PGr!F7,S'< 8qF1z!B! XGZސS˅8Ҏ؝K |֖Ì/Gw!f&ɶ';_|48z^C qF+3;dB<.$S0XEB{ebw$2iօ): Q_cE@ԃ( pDY!úǎXk-lgA 2ra/$tpl!K0E2]XiBzoOQ8ŮiIR51Rk`LUAfK)eU\O<@ŭ]`=$Pkҋ;/wL !Gtk~?gB5Le&yS~ fw;ba8rQ=i< 9u2_ISJU\V-"򞌑R.k)4F@q_rM Xy` rb DD̛{w+X1k{@$fr5‘Ty`5} bf##t|Έ)k#80^ۛn5t\hhn^_. Y✌SȉN ]Ǭ'✴d1Ќ1e=gW3HI-0 jZ%ǖOI뼀랥] -*GUӅ0;6T† .}. +R 0qJ kE~*k j{>ͬ~)pԝ ^L;'fAM^M#_fT |@U3 0S_tRzbx$j87`cwCsoOd9a,ĩ5cEa#p4_v7 VʶBVWZkEXEk[jymn{ª3W4p`tok~Ӆsp& ZnZO6 JTk^r$XJ{A' Og D3UDhWo~˝u۝kl5jj,iMr5k B'3DOg ?y"#|hVz,MѥO}gQgе:3_MSG(Ce=Ԗi4kӜiHRll5#݃HlJח&pBkjP*ԬTC/Vy~@;bȮ;:OUm:C0U:NcW*ӄ805áL[?73ԃq`FU:.uʉZTQNPy;/y& d,o903``TU]aʄwȜ#ƏLKwp}09R ;m5ӚL~P|JMqhQܚn3{ 2oG] )f']tQwOaU/o$_Ol3].$ oTJ4!@ oÃd)}1f5>i)R#3Ewq,03R>V<-%#qt!F/>p]rw n O5Ώw,ZV#w}j)-L8xvs-S_TIja6ΚlsKqxŞg2Q{ *K^_Q=*7Prꥱ'LǪ7EGe4%3\KӸT6KToaXaFM 3E6KKRw f3TwzvAoQn( ❶gaz_Q=*7u!')48R!v (E(L @%\ * Q~FrE$F0k=26/YҷGF,OF'E%^hz]n'k31_?8?$_%+ x+lge+X.4&> > {c|d_jTHbo7?gGm"rF>lzc|nO:aW n1H! ?[4Gs4J}9KBC ,e rSԘ<Uyua]#jjKƼN{eգgal=vC̿{=x)UNp0PkAB @v*1fRusb47g]3#91<;gUX{._I`o:SL?jSϣi".ͤUo0wQjjz RQ@Ũʂ\Dl0,FY?x ~I;R ZʨVijaZ#ҿU:$`^Wd&_ղKv_N'u/rgez̆F.;\Bkk=%1#ܤPZp,e/4ިԓT}͒8IuufjKўzESlꚈGAGtj4>v=E:јqJ@e]%y 6Pcpf g(;5A6Y;{?}*8>ZʎLGtݑz'蠟nF^1Ŝ'Hjum F"p16?S)~]Pv]-ltm-䌕S&r3RL. s ΤxW7Hga0b&.(hMNufDk"-u"\eQ5^ޔ"A4Hhf-[914؅'9s#H!rY}EDS %?gI[fH͛b?f1r|YX-%ʟBN/]u[}z>tqW9i]?n ͑ōu4KX]Avc^ẊfZ('"uG!ݢE졥BD1w~zѿȝT_ϓF J8VGK/_:c7a h'coz &;gȖNGj.*_ aFEEZfX*b~:$Ɣ1ay]#٢*1=U lRJӯҼkp[cmt$YѳWhzU!,*ϝb4 b?tϵňBDV9qq0"v9_Xg6n wj_?~t;qraXrrxx7N/*Ykb{'K#r #<8$B=J:uRQ3GCF>i'_56syi|u]W$*ԙ3t6LygV̄޿21L rbJN#xRsZUC_fC_L0HFOa.ZAn})ۊ[">QDBc%یKRGXiCC;NҤy^y2!pLyv6xO79C{[Dx(NËPF(b@)PR4O_H*HJuS@!"dEe7P (B| ^LǷiKe}vIj?k@iҎ#3:;_A AXjv==- cϊ<0VuP'S̯$Pl_eݒ" We5dίiYA1t1'xOobH'BM/?Q-nZ! j6)ksKr_Uu*ltpTԨ _Do|f V)==e^,A;Xs$?o`959˺= M;Ed-\sȍ_,3N:&I0ktW\Ef+F)YـGL1 ⏂aV~3+HД*@YJ]ȍ7&l?S҄ǐmVK4}yF&$Qh$K?G aN> Fׄ0K?D|GV.QaT!#'O؋DsZ_ϫi%e  vT.0\ت#\lqcbJ"F sR>y^nTKkCD,$ 0lqy(2 md8I|pc^xd+9#+v+p]>/nqܟrEgijoanL㐔¡ȧԨUp":; tP9T 4 B}9ABW}SL pC\!/y!wVmJ0)T( WaaKI } UK(Q1o uX4g\o6Y;2O`V$HyVfx:㞶1ab0/`Y,P~ygXY Nc RLWcJ?g++WW(& K O&_1 \Qτme,<~Ws- /ugoެS~ hWujVm*o SNOF|Zvi6SZn5 ;*Sf:NݳB%~a@'6/,GGكCQo0̣SM⏨& _pq &V C\[sVQeVٻ Zh"~3ː(nۦ/P t/쐏=ɤŐɄLlTdA~u+NU8 `:"c iKz,E `N7 3Yɼ| ix$Xgro?tn9`-GEu۫BL*^S63wWmI!(Uu\&8\NjpC,Rs840VW`ٮ >]5"O˳E^%Yk؈0o+O-9, ~kv3^@T;; 7t [bLlŏo4p[a .6D>)J.ZŐmFpd +AuҖ$)J+q,QX"2_)4#bset\efICtIE:k-rɱϐ#+E$UT0\~}[N=$W }bGw^,.a΂q҅Z]T}Xyko\컼61˘oR9cy' wYL㼑`c75}e}w wퟦk״ `\+}un^6nWM畲sĩAM {mrOM ~a09,^zKoO7_-?6*$"x{yR|tf ԆlZ`!Ǒ[[1e 'VEMSΪ$.LpI{,+Q"fvdT@iL&QG/ ba(IƂDL 3}fhGVz7gxO-=&EK_f`wM3-E&'(gѣ^hM ΁vmeHy!i,Itkt߼A&G\-*\[Pv1`wwrm$:˽ ˜yXy,㣞M\_ۖ6iyV6^^7y?SGO|4x\i7d֢iy6& +J+2KpU|>j󭪼䔗/3 Chʿ`W,_z}VTm@h {6zj;!Y4m$.=vV~9` T$pݏmμ  +i4So9PZÈm@vBr*6@dس < 5E/"˿dClT.(O*YWKfs>3dLb yͺ8Jqt"~ᄿt0)/M$@mrwg<]m^.Y|/]vuԺ+6CmUcp]*-^_L>O͵ԘWUYq5}U ͷdk}ܛ\tz<&0Э}^絚w[k=@+xB^e봒:&}# mv*vI 0D<"a0e7}/c (ڡⓅ9G LTTLψ##+W3^] d.bɱ+3$E$8[`Sv=8M'Qa~3W }HU Knw~ba xD/s)PIiY3 ҉<1ӿV>/#E#y,VwX,_&m"Lh2 ?x܈cC4P8Ka ,GF>۔ZxoU^/˧v uxZ>7*Nt*'|*zm弼1Y{qv[7z_!S;]܏ޙxK-F .zFTJN4^;mr~e#ΩNbzdzV[F^M5Z7h:z|~TmN|0ʨ2@#sm a76TGqND ?\ŽUOEJ ٌ?\W%30&IRչ~NiɼDbt1+ji,W𵰩ZPkDD&rƴ@GYF7o5r} Yhg&7g#cI,zFe-gnti(_/:FQ/@z_8z|C]s& ^9!h xy'8'W#˻i[vF3=jq1uަڑk%-օ?').Crr1(~pv+6ϯz۱ W5~LTLM[^K/VkL4Y6TRr?[;zSnmJ`ҏr8t! 5t)Z0R) {_b>ɓ.%}<,sҭa0T( )wΚ[i~5 ^,zP.&&t9SS~65a,\ب7naǁwNl/;썻UpHD{֮Hԉ8$:_E;n|Ӌɱvo}7[OV4Sxe3Uk^[*ѯxM{80b~΢5#l|R,GU)  e!| 8څA\ls+zPb_1AҋD'FwɄ~Hv~}y?cbGJ> {qid:2+dR]ŭET_4,,&/ZRބy|/^EPC7qNa6b`p,m>yr-zPT|cCQzBɂȠg͔\1i8Q*%# ; ;;`sI@n> I# Ϯ,.5@`:gVx} и1(=-p_ ړ[L Ebnܵr@Uolp0iza.;xC79ߏ")A~ө!zLJFʹSdžtn e|} 0!?_Wb,q0S}~9Ϯ5q,L\p&d)ӓ4K,kJae a/XE{I-]y Z"fXKJeR2cdk{]Xl(HO7#.`1-btH&kLAyѻ'^σr&Q~x['o3|V>D2[6>:/׉ULk>ծj:po .}`X޷*!ϭr,cYٰҶ`tDvn9;{$8bW#Knʲg.X-b&1;dX,JϜM2%نq+C?188pm\F?09?ѹb -9^#2+?Ew-J}W\BQL|6ڙ| '=1_ }s!wd^fJdM2FC?sg ;~,)v}$zߩqQ`!%{ЃIaoO3P6̢ӗG/ʯ_r>Ō~ w&7/Ybg OktX$e dTrT)N$=Pn߱0BDC{Kaf|q/&3,$zնR\6񰗀>*'>1J,#~(VvW7N$|l$1q H1'toqޟʛZO_ق>ѯS4}@”0"ŋ ~Q}t4ʿ+'ř7䟡,/x;y7/saoaFنY~!X0 1Yzc4QѾ8EǔRi.?U,Q,TP|tͲ50Ê_2fܖz^O?lYC&i9_HC]&&t]r+̤)C5x Rt}O0(25_8#\-p3K&R(Xx:stsiMO>Ci= (D&G`ֲ{j6m0(%pUpM AGrt6K~OqUt fKmӾ)SR-e薖^)h!DIjIf 7 amm_DjZ,{c"(&C*S %.tA-HHlW+%YEؙ˘airtTjCM2H&[y2: r:˩!䳯+zP3^E^Hi $2ah_ ^)a"c  /m3U&~Cm*$P&-T"&#am@J UKoj5AP0gX!Ѷ|G/ix ;RX 62 Y?pJ+T$IB+O0b_Q,[ ŎLH;b27*X1 (^_c (}!ڂ9O?2W<*k,D˳+6H {4s.#W lP9CI y3cKɕ1\:һ0F-#`ʪ(.L!18M1tJ:N^['.U[h.9bDKׂQsO `p./X&,C%6C5 T o$G%7VJw3 Wٯ* [gϹ@2PNcc8 ad?dݰ|Y#r[AC(R `%|xcaE,X1 ,TmH%b6`f<5C0c=LdT|d'%]7G,A͕J#!X:s>服ls=[nzn~37kmgZ`g߁|g4ntUyA}"X*T C6zѸԮ\9B>Qٿ9)-ؙCEGT dq77Y}>lЋ$ C8ŨO}btu5[q5m0y,~|?*NlS819{NǞ4; X{KُB(K0V d9< q8Y]ýn3Y Nik:mKt:]Dȼ&I&>3vɡ?uLKol22}) ~+>!K K ~g[f4nR۬ ڴ R~q|UAS9Yw̍>'U"~H*/qe_i6΍siիiC߷|W D@Tmd/XT׾ XiQg\B#\Kz96J死mEN1 _]vֆn62qۍ9)NlτL43!]!AltApB6D 62-7H!vshf֗>_c۷z)p.\g:m"|=xέ\X*T۞B'qYwESȡBP|^ (*TqJP*T0p BT*% BAByP*T ⷨP*T)QiP>6D^B66kVQm*FcP[eER 20} (ɑ X;!V%*KD\B}qd( q8q"+ ۞VL^=[xD#YYJRV#01+\r?ܵnvE4"Wahkq\m;/BdaP=dM[R|TSrF RMm6M"9^gވqUwrvJ /}"44C颻!"Ͻ=O+ld\e{tM/]uXYN6d_̓LfIdw-E8$>.,m6.VIE^/':yr꩜wqyUgӬdRk|l-\-2\RE^pO*Pa|Y]u2k" -ZӨ&Y'8?W=c13@8Q{թ_=-dO2-W3&S3?Wb E:Vq6@mt/!5l[dC<۫•iuTnV01in$b+Vr %ܺ[@9zI/ӈ•<"_ $[O@ʱͮ9W[9в۠/dF-׻Pnl^֯FFҋh6t6ic[tp~ѶT[ld\e7%2[ iګp/C {'C\tZHv?тޘ*O(v3LOzMГ65f mSxV[<߻/&HȤEf,xc`$z|:`kaG;7 m6y=\:ۓ§Vf "Ko>p5-j}+u7jV[U:`\QA_v7mnYSD+8wYgSMpP$?X`L r_ Pze&V*@|(7ڑF0&@9=. {flf>)FD:۰w 6 u#`Eo p<#6L.fQ4Q΢XU,(zO>) Vta)%q&wh 콁HRD!(02y(U{3+I_B*%^ 5b4i8эV*xGw:}(XN /{Uދ'bHPFI  @jii ^$(,8CFx ȓD΂Ze Kp)or([W@KYCQr8Ut8b<]7*RuÅ}<>_T8uZHb;1'Q';?MBk{u&Oo:_R;8VGoeZ9r5 5wgQB ֶ1 J{U1H|ҿb1AaJZ8XtWKzVkQx|'[b-&]@0i&EvumL5ѝ+hBM˲tLڢVLRpmcRmbYT&ӎP־EDڧɕpXC~C ; J>e'0pl /Sf =RtV-,2= nO^9fo\XEmpe3(}C5,8¥ЛQFgU-tڤCmRE$8,uCFx1ڤ0H3ymp># -. 9fmj@/P} Lj$#.xK 8l YsQp OkY pyp= @B@D/ 8  x*VpM@LyD;P|`$cPځUKEiq`q-O<~;ٹ$o@{pp@o@ @ ?@~@4N @N6p}@ M3ž'pJ0*\g `"#@DN&4G"訑-[`t@ʋ~_2>PNȶbi4]u*#h 9o-jwUi T~Ea.3v*{@ZG[yz=JE[`F`Z6`?p ?6 ]P+"VpƓ3(8o}}ɗ⑉JxY^,LM(A8'7w xhqja!E'o1Y~]ۍuR r S mu4_.-1aIs͖^[|Y-9kiF!/P غRb-N: q(b2ێ-#Lm[fW=܇<8OLˆ<6<8N1C4W?f*;ks;g|tYo?/.3VG ECpmS!AJԸwfeFG6~8!{Keeq_# uUlx[{;e*m֪'xV?[r5k;'o3nTu@_Vuڴkv:)}mΪ,@YZ5όsᆏ6p+@Z52jZ+M `%U^ c-c`q ME-v3U+]R bpqR[LCIc.05æ9@@ f{Y䗗VSGP}?`ec&8jqZ/{^/^gz<B{f Oˬc0c.n.Y;ůs6fEu6' 3k%$?'s|~K*nS{zQzp;kj#<) &rsp*s8X+yiߟ-M*i8iK@8[ 4-7=\Oj8Mc-sȧSM ҹ5F. }Ͳ\Ji/ol}'LpQv/e` &|:v҆x`ga.#C_)u,8M wP`^?D:G!y\nVzU4(ÅUҗ:VܾAk],Na1UYnwo[cߠNњ̒B&&3F9_u_C7^ ]9$xza1fٳp IrO G`EƦeKV ͋Oc [<33ቖ6 اlzPѠ]qZԋN$ڮN-Y}2r^\)39<HF€˰M v @sK";<W3wxBӬ<}G:rkRg"|vywwY-p`ہC=$F7 Eϸ_ El3fJLhTj__4~**jV.3wٲn)ٰ;ggR};O)}٪>ҏA)S ;Lrn] ܥwfߤ ΙQ=*>e͓b7_ۭ۵Օ,WF-?mQe6KezZp6|a^3WSBN֑(]AL[ P|̛It4,dY>iI#y{R/sިLJ P'-,L4-^T5 TlJ\IϹWSfY?fR_&3I_t۵DŽ*9~*Eazc;w{{>@eJ؉îr7feoQ0IdF\/Pt+I*=YJBI8#vݜM%8ɳvj _P.]["_~lN~$9֗-by"pM8L sC,/󌔘9lP=;N`#7iʱ㋿c ˖:[̧SpS84 @Dp2{}6q`0}!Făᦳ8BGM7n"oo`9KFm9 ֐-6mەkL)M/Ztţu'5֬^| mY鴙ڹF꺠XKə٬pӥ7l?PRTy(4|j%:15BDf*o>' Y e!j꣉3ZT[MK_ q'`c%aH&X3J!T꭪OiZ,&ɪ!4X-+?@ʇߛoR 7Yt'6Dƒ~Vn3bYmb4;2f r1C3em ȨB;ka!tKl!D Nz۬ɺv4"W`vkVmuhjd64m6ɋ(WIP3vC'BX 7#I3F|GD`X>sϳaQGVj%Yye1F2 )00Y_A]WfcM2V/ jH`č_Қ\ =t>KuAIUT՝tߪ5K͝uEMX:ju15s+5E"dW&M^%=0c=g/6rѩ絁މV.9~(jeZh=7Ye/΄鍛J(f5{'ҿa[>Azwro}PiOLJ #>D >Q+m rcSH)l.M6U*̚:GpF9 螫jVr[7xmK (,㎢18h89p=Hk$CrlqTIg>lw3|fP\22E/lPIQ?Ior?=N'l5\E$lVV%dFhossk nmXYHx4WL:,DaƄOX2tC%BiyZp%V5RxJj':ݑdUVum7ãyk\ n$/Rc1h3ފ8Kvx[4(_\ʲB0ԲX_,)+t xreiy}\m@g׏~=&b7 'w fUu}5 F]d !HrQ.M]avp(e/T0tR7d8-b׬5b7Agwx\#ptN\jQ jl};bsA7v*.oۉb˯jT3ohۍjYfj*LMÃ<~sH+qg x#k-K-o^a. hup2˷iiEge;ϠOaL jIJhK3fx R~GyO/ ;Fz2,Qga@̡ gLgI%f2 _ ldgZHø8Sd%s@/ \T '=1'ԪT({S}Тyr4"FyEkZ+B txڬ5 gkW1D:U"HLP(n@NdIqx~y"CEV9fif&3IdْIeo XJ?FZ% m Zj*fAAy{f"({ﯷ{ﴞ&Â?x25ɰ q#I9[1y\ƽ7 [K̯I8uQqsfy4$vXЁȁ TBH)Mь@=vw;vܤn,+c ch@B P@"(A!Q| =o@[~Ą%0z{=k6=d2 Ӎ(ƾG% "tgRWHDKUer?ʃwHꋿ (AE!CM$y+QE}\s8j}|@9H%RJ'2 xVJ\BL30)q!C?dO3ffV`c_͖p}/ul)BqD2Cb˔M6)m> 2YD3a%*Bnٓ2wN375 `D[&^=e*#'c8tm͹KopO>W".w28P.qKdnqR;P}6Ȏ[ 1m9QJA$q}_s~: |dEW3no2k"G蕫{(QUy\ HDm2\0(%6!f MFqlQPZjyKQ3֯k<K%9'cCX:4VrҾ46veemF~W*(d[-ŘT3-!8K/#,)27uo8DPj9O)icp+6@Z%.HqHXPL8 ȉ"fgrcl21_)Rch٘yZt =S)̠H;H +MbO 9K= XU37)*X[z 7cÇ8ilmc:G"[M*fZ:_d- P˜كBp )ɬbN+͇ hd[pp O2-XŴ|ZtS$`FhE80k8MC _*Xr~JwBi8 $xbc[y!D,0>z%KiUWX*8FN1m)U0o+(m$7Y=ig?T潒[hd-9(ON-=ע,AX!eZaqKqтnXdhg-*2f:dqXƹ(JX@U …όp$Ka B/[ߕqsvn2]·_b4mxo+,,!t3\T9nY%;zm/l&mzUzBmԛȋho9Xd?/fleO$#iv&% "˸FZq(f&P#Hf2Ϋ2 P-¼I%^tEFy찓F@omJ̠O#"a(@~e.XR.pVrނ4 ybՖSkRhXR;x;Av)*tE=ETlPp3넒˾ܛ9ޝ&ZI@Q6-DOTe$6kýEn8778 86pe:dR*zLf b q:]!!wCtR! ӈcl:qd^թ5*XNgmր/Ǩpײh8}bl$@oKHRXbһ([l!BO< o? H'-is 2u;?S3Tg>Hύ(Gܖ۰Ε̺#=,6_ܛ1ej.:+؁%7.f˔.GgT~q@|ύJY[HEYO+_oѵKMM e)yBz# zGI+롚J&)dx1Q^77ܙ,D @ͺyZ>礃h7e耧~ѭyhzB@xD ;@ag-gq?WѧNsb6= z.nAefP #[SQ^ژ@6 X1+[ffG}uݲwU<[[0&uxvNY*l; &n&8¦LR*dgNf( JV- +lENQϜTv. ]`/gqN 8gVmd`H6jۓwr<};)_.r'*A'ZJ |%W$]2r0ڂѭӹ(^55cQHKi,fԩ6‘2%O,&uR53SvB|-Vx URt ʴ( nꏃ9G[Ww. W7]}zk~~`]5}=;{ZQn\@DX6* mem Cdc}P|Ohd]"j[uTR\UbgqQȴY|=C4; Šã"ct7ĶǺWԖ,\ubOtȋ}%+ $% !B p๸I0raj0FX;Iڒy_&M&G熸8/oP$nzы,+ s47sЊ)g{Mp]\qeFZr>fJO%--aNW:)ɼx=Tn7҅n|o3qodw{iu< }g>gMYӝ/{pA{+@ 1d:-L#" t-mXt.9u-fT ֨\(:*.%xN 1I.ں!'ZUmp/&Pն^ c1{-ܱe(aP7e`"F( .๞-GJ OҝUy\'lY 78ʨ:Z6 Svq P֨ {ƒBX9J'CQ;0PbT͊I\RP4PJJp~jpQ0v5*bRT䡥ѿM䭆;=)BmERv:QDC7J7I/~D-Q\fO&9vG766qՂD75vB[PEKL-_9[R>`v6\ ^h}_jk~"H5&] '>OjD5 iy)el!)j&rn UGs-W/z;5T 0vdYhrⰚ+1 ,J Z[ 永ayd <*:?}Y?mʶ; C2̀Z WKT9#D-oiQo:s: n5u.SU*ڃN)Vr(:bZ/b0+Y[M=Mmon=U% .I]Y -넕w&O&qS ~d מ'^Ђε}n:t `oA VUׁhMwּ*bUEYic;ӕ.K"n[?N[ݣ<'PdouCrmmXuُC1 Hв6Yc"Q* w>!j5V2]AA&㝘 A}Vywkl hUZ-/b^T!CM?ȀB Mt`ߗUJtAW3LlqB.lģ o Pkmn["fIi "N[ϴ'WW R -Vz.Tf) ~)'O}86O9қnmvvf&oM*ȁ`uzoz mycԕ'mit m ܦN}rZ6e N%6+jrG6 m%SDS|䰣S\>=}вγZM6۷=08vy M1RL{r`k;t-tsmfyFus) `uq)J/tӟSÌӎCeU*Լab*&pMJC:@r{wA}` 7"V:7 tMGԓ|yfH.֚#[' HVj҅fUBjjh,._QG9z)C.NQRhsfWFa.[ yiSgt{X=9Oa\+Xx<^7aZU/`ũbU4t&sYy 5H+$\b M HEEJr3yo)C^)k0BhV\\Zy|pW9Zx?=ߋz5[cćcj>vο8ۮ9Ɓ@L+Fgj OSfuX>]bۮ|Ab\&zE_J'|'n&nb3zЎ7s0k_u=Iӂ8}}%<7a4g\ nC-KQc,i3Lwa[4 |>Oj:MRTçѶr= S`_nwR [#Zi5ɖQōNI/U9ŀrt|+K[pحS=[Ǐ°o{sSou<x#L@`=pCWKcBc"Y+gքN:uU=y@?CIaBTTv2NTpQɚ[lŔJ8/HQg0\&e&Od`eN7rCDNmfEID-2y5RIʴ$t1Tb=Z@cZd lQi0h|G=gN>Stc$onFr⽤≓`7ق>k܎={XAzoȲᄴ- x r1dٮck389;0@_ǘCј88畅0+f䴪0lju˔D}G3YZ&˫IR7. `H M,iNC7>T?=gaV-p[iс"%s({E 8uҮJqQwnSaqRdSo{T6#hOٓ iAfs:&[ܩ/۪c:_}~Y A8E ddyOp1þNFll|5I'ŕ@gscC{{`"ɋvM/A;9!7n:݋Y_RI'S&{Jr8Q/wRps`VD[w ]]:jSA|moaWe̗ -l8d,r2]KQfRn$~VDih+[z5=c`@< N `en<.}a )¤jFpU}k,qd@ƌoz='{䐉Sw1!{KR,`܂;!"Mf?q0bG-e5|k6ه=S·?YZ8% C ڎBIXY4p,!%><Ӏ؜y <-G%_b1M[?t]0|O-*r΀Mu=l.CL-п+ViH9nKe_rMtBEp\]ϥ M m(Ym-fu$Ҷ-[VånL+L|cnBEt]~]呖M ` E k--O!x1 Y6֙yBDr@paDK%mU쒗y >y:f5cu#ب5rM*.EsQmmjvvT2ξlaVSٯ5{6@voYL,48Q{Ccs@=9G@1-׈H͋42loj0.iAb[22nofREQ= q`DA6#P*JgY8.(nnyl@@IaZ AS!-px"VNet98"0hq'4 ?~w߲8#ihaT!#2HشTE~TXڒ_GQ̴l'(Zɪ2-LFULY$t2E++&oZpPtn P)<4P궪i*mSBTlM&)i0^Z'O4Kی) j7rJfM&ʡ* 3n2 %S#m]\jw_ %`扢#c bgUH皈n.9c9Ȋ[T/e  ӘfG}P:*@O&2nW|}6fՙ8 @~*\.Xetd5k|?cKi~[۟}[l?^RD Y6enH_Tz6Džvp\G$ aS GGhqUQz-M[.ꊺCWvdg޵!&88}@3 m$2V^7v.m,0l<'9r'vba6Q-Y˴fvYjճ+ݸR@ _=Á@fݲ nX"raBX_6NbN IWW88x@۳egck'ܪOۖUƥ LqF.q5J)BXʅ#Mܧ4a`lt[1LlGt5eگ|ܭ*uMVxSѫ tw9ap`d<'X8Y˳T|cxlF+cطuy}R׳dXuђy_)b%yc-~Egn~%%@k2N״[{*0(\2&c"%"*dTі=/rZ0\e2YB`4SsdSO?x4 G Gti\8m E|Ί8b)1=0w'3B =q_B`k5K74էAC޿u8U hz' }Pa#Ti,#yYfZ嫟rՏ_&b:jOʟtn>Bѧɔ O_ߠVYhvY2'dGȪο\xL5֢{yi2afa?6t!Hqnj>[^FMfc{ LhZ)XʣO l+)U:F.236^(K =MofNͬi30S~i O ~:irxgѫLb*ة\H8pXT檝;/̵q)1/8bpC[v][Fq/X,*aZ]NƽK4f}`;8$ K[~>s(b {E5[JⱁzfxaJeK OiBsdG]y;KY4f`,+J8Ɛ33?y Ndæ[o4r<x&Ls1R2}O.lIHHHHHH[s!z(HRH@>C^v &/@<Ő鐜wL=t;&$9$TwL>HHHT@zF& u#RpFD!p'< ņL"܈bGDc\E!QU`PM;}? q`tC#dSLJڢH tL%0I=L`5p7^ k.'("gK37p"@_#x=?NWfzuK*q@pmH!l 9 kUBjbDmjޑ0,"RX;*F;Xő@ ¥ٽh"Re8ۻ30z+k-FV*fzkP+V-F,:p{ǹPWBau]JrtlP3w9kgrb8tVOJM]qm{e%soaNfF\eQ)󟸐'D|"dV+x4(U^/O6dܚ"E  S[Rqם\rE/͵Q/릨س"jalg%i8 k75dzQsx q3V+b4+I׳HnzOdMZYp~w99kʪZp`@NJDH 8U  ?iA [83B,M9[s[?dhscD*U63*jPbANjbDm 7p{ o3Xڀ ׻/ ـr=sy4)*ZUBVϤ0rLأQ 9 '7=D\ũ e@ @0D?p7M F0*݇#QK-dEĠ4@SNYBRJRoN !i%(a5?Խ_wZ'=rn}g(u9o}@@ @ @Px @yg5%(/@@@ L0g5 p&z~w `"$@4N%ߢ=@4.I(s\܂D 4BV0d4䇯fs_Z7Ph ʊ f"f5 "Yr|?GKoON_߇_gw+V.Z=@@@@@@;_=  <~J. 4|}|4mpj1 j&p"0u3?@ۭL;s\Ì|t(n2 Va *YKhy}-~mr2WlpOIt2@u M#$"U<5"G (*Q@2hj6r5MOLTN)Ko."&JD<W^#aE%E˕0*NW׼VYvdZMRZv9$ 4KQpF>?Ե$WԍtzuO{&ik]ږnkwj[zn_NJ4d} +ڍ}'zTBk-s>_q֬pkDOtvv<t<\VmtƖ?؄}s6ƪinp ȸ-<_sZXK9,M"FOfM%ؗ| ߍfpV7SnOÀ\ikn䩵jq%˺ m#C`V H ZQJO@ 'A_|-- 63ܮWro}SW @;?zeveo 2W0„ 3f,M8FQ(O aoYYb@A} "1*+yswvTAxaxAFn\K˃~b"̿Y>-a" +䡄myQNy+by`YG.rGD$w܈JBܗvI=V*58\Y9opX۰eE)n?RZp|y> ;5-#RN+?}$|}u=A0p m{)k.p:͹ٰT@dny' (#:^D:( 0?(349dEp뗬N^_o._xp|c &7-L:sup_7p$r~aՐfuedXN+QQI=mY/cG.PˡʓK,fP/grNTߚͅ'hD]WPR1w!!x=y$ޖ71۲:T+T2۞_.1M27B4zC7MQIq,5jcf;9!!ު$[ECL\òQɂX@^'9O \lPἪ<)n|t 4/^P-}JtK2ӂB.QO꽼rwq?8qu,n'j姲m.N'^>;?p?^Wu%T&t\u5Sxd6lIsr&Rwok~'LjP kMg̷9-L<ׅG2tm#*z{jPubGdR9:>? )ބS˚dp7U{=a߬IM Tv+??)e .Jnz?lfQgņe4_"ᤒw3dݧjONn%*Zg\* DQ쎟lGۦ;{6-$JVZOÕ&B 򑺢<ݺWgڠ_x׏rze.]_Io *_pr0Z@|` 8; ՋS6 xn:H=+coM 'H$mt ,Zr _v̄_g퉓pf8+a#h2 !.bo I 0p5G ;庞G&r{T tNN\iPĈRq< ^ۨ2"!h8ׁMMۙSv *,w;8la kToXR6+;Ma(ܖ! DB)Id[B'E?Pa-o'{6P:w[\[ʶ^e9 Vc/'.7҇#}l5T]MbpoF8pnON>]@~lKKoY$Yâބ3qh~-d?v#7 Gq#ѯ$K(a4/n3/'zajw8 <m\v;ɼTa6ϥfiGM%?ؤEm/~Eof{`Vs15tݶ9:ްUV|U8lk8,)v}eByMNdQhB/隫RzéM*ep \qm$u4n`űI68f:'N5ܙds*착6YOS U?e{ɃHp|Sw N孋%4Uݐ4޼utZB^L>aݽꭦ-/?xɏ}Zo/ e8eθ)A!~uLOk2E޾ a&˾wT{qw;֯^m\WWmJ;"D+dqNWFq^s?{itUDZ8w-hAPNA r2$BpWo``hP`<``` ä'\ 3PjچwKQHʌTMܕ@fjf[],Y}+'l5LheJB\&KQsGY^pCfirmcnB"0 {`#8(#s~su%A|H/p8L'-N,DcgWx Fr!d?}-ܵN+uO|٣JͿځ)&yT68-Z{,8>b70eD* A[zMɓPϹG^MOM>>hnwsϛ9}#,B?PҧFd~t0D"BvpGo"t*r@嬓 ̘4Œ^w rM؞gS˫jS'cGQi0el~0pj|ZvSgÊNd:ʳرnݒ豬.6b4pP^gH+Ip?%[pni3=ڌyz|mN%W'#c(:>l)'#9=͑1j}3a4O`3U_W볻7 .;Jy,-eN}RB.׌IuPb D=_R4u8K-͵ϫ?;DpP&یv'gf;>!DUw]& T9m!>UDӀ]@أ)wj֭K0rX B;RG>t;aÁuq&,+$s{[5lxjTܬ'ێ>"T8rTm 6koa}\.\z_{;s|oaQ'Ymb q"Bk+ >R[k[} Pqp]?ۓPmJ r4?\:>4"3QDPps5䎳WsV}Y /q %̥yn^)Ҧ]ok;NG,!" ܜܳ>u]};.zg;;^tۓ+mwji ~ ^Ӝ&qgΤ}vζ)h'Ӵ!3]@L 8EOQ~K_xm\v~zM{ʌw<_|(q%aSCrAJhuv=LDZpnG⁓K&Qʭw\j稠՟1JC?)#iQ`qPk?db}NQeK*101'Oի1,7KVj {E]t4ցAs(k=9B[ ʇ'NFЖesaOeZMmPSVS#2oxQU~T/Pn؟}+AOg? 꿎^== ;@Y{%@ٳ -ޛ(oց"㚲+`Q_2`?-θǐhP8%Ee(Z)B-٦+őE|C@\}srZba9Rqit '2w]N&")8,W|!紨Gv]x2z މ1ߕW0+!v'1mP7D D{:n"uho>MF'q!@%?Ц~BXDO'WdXb |0ITJɷں:_2 7%׷!LFHRf#[n߇;hPߴ5#ճTI6SȹJe[K6FS&$zf@(+VPĤJgB@ὔ@бqkHEkf3&RkT,ℛ̥}U"{$;ހY_=jAqAzAyn7?@\czEK:r{-C%'P7o jsɾNjXnhC pq}(!ٕuq& .Jjp/FJNhÄ%t4EX\i!^Ж L&&A瓢pȯ"8e[>bjrnW(zG+?3o;足3Nqhb([蠖(-vПvS!C@49mV^hY0½6=.{3U\7?];5[KoV.}x, x줷_U7әUѧ׎ȶ2c_һڷ8um}{zo0 qJZn/Í U}5|g}?Nk-W+D\ G偘FҖﵺZCmo~|\H?bL xPapP kKO, n'WѼos~"m,,k_*s[#+ aSI_q_ޛT enh=z!;y,}3NY5˄:oGGTuD$F7>I4Vc_k8X StGpk(B%.1K)fx3Q`77̙,T'SΠvw{sCRgAVs\HA!(O"Kw03Kшt:%C\~^΁qu~ ).s(~߇Z[rvZ2jqrYrqcn=ʚ F\UlݯјYPfwjHll7-xM-qnTXP Q] 3VNOssf5']3KBN2-: !|n׹g>ŸmqRÒ/qPv]oI>ЂC T,y踉okfZ(JV5=QckfK,7ԭ˜B%Oͬu&RSU3ЦVNᾁ&KTmnDmCJ,sn~aPwqt-ukZ{X=?`R; =k jZzv:\=]*ŵpUoeDQd8GW2@|sG yLVcZ/:k?>͊Z4^/|&X;'敾ZT{r`FiX9ص=d{(N€d$[HB9^oWĩdC\cuK&yH?ޚ7}q+u1Pu_8!8ɡc -c-Y4i3攡RN-&\˲|'&a+:[*-X.[wX1S&S&dmK<((;boVgVg8:ۀ<.{{~8 ҆e/<~ߤ'?Excvȉ[|KGFN-WZ-:d6'fh ܊u -/^Sډi%&イR= ~@-w}ؖ)r00ƣbȵZs0F%.-FG> V[7V>S@r90rAL[MT/:Cҏoq?pJ*8nmwq-L`^wyP^e CD( ˭Fln%S}Dy|7&Otg|$0m Ft+Ib@[wg E-hN`T$5Ψf偑ֽ>l\:RᇅlR̈JJZAʕFBVT$Jsv0>Dols9`N_DY8BY*0>9*l*W7 [J7*S (~>Zd(QzweJe=[ZdI_;|Z'[hۣ^m7vxoij-;Au7ڭ#m1SOk2U-XrUNa(#v%"3tQԶ(Ůgqa Rgr|E;Uz)FT"ôŸvف>GmEz- rϞ@zx6cVMaV8p3m] 7u^prKL=!=)Kz Vxfy #v˂7X#M(7Zb ʂ__U.~j;Z}s.g{y<ăf31ClҋE [ 2Uq6EC9W%75#jR}q1%j'|9v%wU.sxI|w~2ZnJڪXo _l;ճ9<:pm٦wrl0:旝0s25&;p3owܖpxvZÍ[mNwY25}@̩ӹuAJ5퐢_ @y(i5.yf@0.@GkgDc i+gP:uU}y@?CIBTTv.NTpQcl&ŜJqOHQg00<&&ɉk =+IT3*%o4M"*weV͊9>]NW8`栋҅¦ѕu;"mwMbUL3-F<~o:+MzTg" #o:W<ֹ\|`(5[$?v"`ԷRd R| 5h* e`hAfǍ)|ڍgJR6U% zx͛e_P70 LMjbNoQ6>fF ab( iCF)˚te@5kS{usx>yh7:cu5#r*گMsEQX "劵1YR:͋,ES= a61a@xY}Hw,[݀Q48{I/p'onFQbtTwh mV0yZ=6ys|[o5$qAO-3&n*Ґ-srEgsa%{#^S"8N.vxdD!=8mrx9S#:q0&h#'JZ >Gcab B4 !Zfkl%"sJ7(7?$Xr󖸬ӒG1d oxqTmXRIE׋V]Q b+i+6a;f o9f|@Χu4MaLZͥCZX4m($_ےX?Đ65Z&!fn2(N-Iss9Ak?*чM1_9]|'#o_y"n Ah7:a *nRI*6g_-]n]]]?|]h]˧mJ}dS[wrɖI+/}kX NzB@z`>fݗ{n7Mluv[ҽn-?0ZocntU<4p5qo\e5w򏛌 s`Kǖ-mV_ke/gwt&[91,'x ay!|܁ K&=Ns&n՛ܾ`rL7e2=qZ烳1쮵QH(,Cr*eŤ)(? 1>F4[~{K˶q̒P- pG⚜2ֆ7"!i<t-Hѣi2m9Uvzz`?ľ!x>D$hϞS@%ǵȜA./5/$nr~a7~ڿ} j&|y(H9= \Koq {)'>޹IBz@/;G> EZ\ l!N~B@nh0ĉo@z $Ć  @$V pP (Xko@P?GKᢊ)@{ e35d@{ YAp@?PȁL( ,$oBU:DbwFhN@A|5ƌqX;n8r/NkCLD7%=t@UlhW1+y*ZdN@Aܫ` h;_cB /NkLC9q&Rѝ ֪4 8 Xz Q4"`gDid`bX AѩNIa,c围5k36vkkim"@{8S4ð=zp[2]%5vؐ@oCI8p@(t'r'("+ o6coIglBah΅CJRzZ|DJ*\PhWik#޼7.Ka:I?{-[aٵ҇WiueoDQe!_a]^60I8iNu&8e"܅σ)؉﩯G)9!)=϶Kr\8q)*3=Zz[i1Ɵ`I` OR[,0I#$`D^DM>`(> v+'/>s,Z:K=`yZv3ZK'v*y A ʳr1TRɬ] l8.v٫c}puhG-"?>kTU"/fZMuF80m~JBb9M4,=P=S&gڔ{2zuhhaiP::X"y{"쫳p܌087Ay&5Vqf%)S$Jqm%˝̒.\5Z :{94S=,?f RB.Ucbiuha*F8G18v^3iyN Ik,eWqWR+D┖aơ5iw'ǐ1MV$4L?D 2"^RS{?|Iy&&$Cofm9p Y5oDQqfa #S^I&'֭kv6CV%a[YӸ{o Ov9&Iftw+6Nq0{$iv cf<+)It&fS+ [=ME>{$iv ? }qyFOu҃$:{i'Z u@LLLLLLu@,5Fro7]&; fۀq` YڬGT`cס`\Oƚ&&7`lz@ u#RpFD! 8b&n!^aEi r ĕ*jRA2@)cJt}R=p­SK";p.Lwh!{gR.1?.# `'Yk3&Z/)8UBf~։RI-^o}qp?cчɿ~{R^XMEFHy#0ڸEހ0UUJCyS3|"_zQZe )5KU8 F:9j+, TvKNlU!^eiN|~):{aº:/T@8Z~o I?#iTӞZP_iu\kU mVdnCCMeZe|΁amq̟mU?(YP edV+,zmqz7(V=QIП f:Q98QZM9^uM4T+}z#>Q%uQqԬ"\Mܲyۜåd.n:UB~)Դ&/(9e4qrV+,vu:X 1p 3ݪ~C)= H\[G;0SY(Jjg!9%# H ͩ$#-lUK}ohFvbf Wo6j9+ ,p6Ej+bw -gRZ8$?Qmܿ$??d7nRq\H:pr9n|Ʊ\Q)}sP $.|#S 8 ]t :ŀ.3]tԆ\@3`DoE8) S{7TS+ [p&5YF,n{@~G=h@]^JmqF݌rMY?]|A(ADI'W#w麟JxF`xyX|HFc3laK.pq5p1.'u}k_2oc;b7ȕ| ;Ï/`^e[[?{mp7(o(;;t(˝pÐ T?L󴠊tfVe;VbCZ~9]yӻ'kW<=ɤOtks=Ku luRQ>N0ix)ġ[;U\;eLP5m]OŮ?g$S!1WqD8>VIG_~q  m'4 V?k [ц :2Z]я^ukݜ?**S-jve\ñxF&f2 BVv=_X;XS}v~b.oD.<P{S#לTwCQ^ſjz8sPY@`r,3{M@fՑt(`,2Yڗfuf=?WׁY ή/ֹ/fQ4>g!.=)lz^d1f+_n5#/˺IÜѰ=b?埕 X[AUBpo˫%廬^8͚@y0.f~l:z:l#5}s4s$) OvybB[q1`+~a&n!"^Cc{u߱J/"#b+r#e} Y?K#ݸWz 3<ɳuCC&=Z9{j1iWpŁ}[嵛QXWosfāʶ䳡o!l%/I @ж6,X `,O}YKdycl6[@ea4n_81㠾X( H""`4^||p 1O8pU--P!`W$pD'!$rl .Va;U%VEH+(;F,`Fղn"eu~VfnO_^5jޕ_vr[E_|u;ٺ2ToN x7im *t`?k&e=c0vQJ517<,My.?\+v?W{W^6F*W@+K#+VVũ6+H '8y@bv9 %2Fo`p{DqvVgl++(:e{|N$5I&kzq{DR!aXAStQI4SePd ehDPFaG<6eL.i=Ot?oٻw_\~^so}/8w_z7%mtuul]t~qh\%7~dg_tx1PU oi?VD2ͻ{g"[~ӶDթ2v@U8[}e/ 7@^{2[fg8fp4nvtc@pNjp({V.Ͷ#) MO4W{3eS~>*~g}Nw>o? 6I)HqnķY0b iyL|ؿy]Kp[ [Tu_mC8n*Y7Zd͋.6L~~*_oPW[iUo1QT;-4Bkn)j Z}[ qIV)fy.y74\sT۪/\JruZ04UD|Zݪ$$%4`D3t Qy 1)UӽiTz 3BFb9H3sR?!fIar*%No,4 c3P}R1I4,Q5A!Ѹ'#FWs*4&"Z̒YV.#bV*"m;ceb{@KP F7u\o/po cM *is apٯ8 Fnߟ78Pn[j7W 73`Z2 RR?̀u^@sTv9/ j%/nUoUmt8aGNomopl.NClbww;GiJgN* % l_>ӿjFTzkx'Kf /uZQ#pMm6;:Igk]_o.s_ =_Ol$Y ٷc-;v^W9TɁr%oS~Pp4iZ'%/tn;ߩ<n:4vD1o.ʯS&7O.AI{m\"Yl*24 ab4p#mS`r}#jzu1mo+Lp{J5̠%w;׳.s&jR(>ЉZ2m')ptueBs}cns0/XDTBM[T(iŃ)9m*h?(~2\+֖jׄO]Vſ;WogMS~GƮb~ͯsͮ*pj5+'%rr i88j =/VoouLpgsNUpCgx;sk'Z>ܔ_n4pL]iN=~+bmU}˦|I 9o\*g-}WD0_t?Qh^hsC@~) {^NJ` n2#3puk;b  :N#DmvU緵+[ b43x>fu XeBHiRBhQ8?,"DF!l(@([HDB"wޓ A@03޽{9mr%jc8eGJN#XĂkӚẽT~@y</HwoM/ڵX _;ۍ!|᪍=MI$ڛ ތ/6AvDch=#|#Xˠq@n"-d?NZ.&]5UN{T+d*C \-dsHc~ Fю9ӭ)ui[bkhsߓJCQZbT,Ot.M)it1V򽖖[&mr Z-iUͤstJΞ.SϵBu5t =L6u b+b8/KwxrS3IuZJQ_0ƵESыRClҮWT̳>Æz9_Sp kZ &/9Nf2߄" I]58ܹ}fK'\,a^Ei?Kl 5E*> n'Y hb գ>J_~k6,fF&fS¬DΦy*_ I^c2j"7 M4)M.Yulr9!=b1wD#oZ1JFE1u@a81 wSۿ*g.مi߶ ͘z &Ԅ2 kCiP"zu2^ nEF;|\^=4d& )M (Pa>k/gԬR#~̸5S]&L)j,kۋ֭ ¶)FrgjKyȎihT (*f;>C4c$.* (8 3J @S5evM$e_Uyl̑^w4ndQ7R Ǵ.b~>>YRV,78l?o3N@[kb%h_ i=IPgܞ'aJT*7'v }@ {DHg$@rE). tH?:>F>i7:̥6ZG( މ48H] SO9@@3*m3f}MpBL7|~yOy_%ArvW:輿|yP"_/#'KZz'/~1ȋWY R4Pɷ'a;^nlhKڬvʍ1#s!naȞ#xmݍ=89V2,܆Tc*ڸH-H[$Rcu't+MQn qSTx܂4N^&-ꩽ2!"ov Nn"]X{ L.4p[+MS➁b=bi$$X2{rҊUVG#35J^K/ͤ44Mh'$!"#,-% GnB An;-(H @rڮڼwm L>~6~;jN? /+ۅje[HX58}ѯg4Kһw5jsB%Vxrj[4ID hfh\wے-pYyr+"YD4>>&49p\~!@…/>NC@4Ì0I<;'q<:Kf}"rd&n^8=zܗ^anY ux¹.^&fDa\nĸE[v! 9#ysDW>_s'gK)<̓\r՚abլ ciϽyzuW7VQ뷷}MSG8>K]AIv}.Xpgr鹿?zչ'dw!9Q 2~)1>.z\-՛>>g4S ȥ~ɉ2HČ4ܰL -2YD3% _cZ`gxej:d _h&-KERB'@2#ۇXy$@;dXv,i_;\=%'Н(GtK E>Hq&>[cAL|~(Kf =/遟=v̀ o â[L2-[Ad^,X^Pb$. KnH;~J~M\܈ظ&6jbEPj57")|5Q˷뚔LXO!qpTS&&w:S*:Y? & ҙx$ .$`p6ׂ.-7 uvn9-)ˉ:M.XG*֥7ʽ?ھ46v%em~[(/F:h'_bfNwCYvc/C.b: +5(gX"9 of3mj VZn\6ٱm }~DPf7-X "@]m#v t[S;e1K$i%y0DsyѬ.;`Z2oE݊m^wfD^|eDrWf $R^O8{;SK s4]*xe'cW(m=޿lŕGҘx/c4QܴȜo}ҶqV$캙r~_N+UT߾~Whb(⣖YH qm7QTjdrQq ٳ(ذQBSI[@i'\:,u~ }叻UsqN0H/]|Go]"m˕{rN['Ì,xYCfw&ChjmgW:7*E`1[j/9#A. ~˞HG ZJEvdY7ZR"$1~pBd>㉼*.E~B+Q" Z#s,e ̪KF#$ a0SH2JXTp=rʜB ےՖSkThXеvnSHT4ݍ=Q;b[*.nXw5o&]D$P3U+X, BxB`/AJX"rLdRR|UchǐO$qnȔ6{?VzHxfK&gXA{X)PW꩟cLK\] ~ջ{Q.3RZ9wZ6{bCsc7nP(VNd|Xܦ4lWDL2-IȰVBy,[r~ .:M"K7ĈBC̸@Fvu\ft̲3H Va58Nf?%mNwbҊYR 'Xt"VVA\,Jîbvhè35Çh2q8,f.[I⛇)=}f)W}+?hR`@wQm畵 .̩T}TюY7Ӂ-VПvSDnrrVN_r9! @phKqw}_7F U#-ܩ8KWlڭߐU?mQp*wl}K|[IR\Βm*]D'RHgl$7ϜW JmiY^ f1 +5z> [v'Mg9 )㽻, sj#Źc#+)f {tX'& \/mWq1n  |b9ͅĥ~5i,l[jiA[:,f_wkRXJT̴~So͒4j"b oK,sb#-ұ`.|+|p^Ws8mOp[a~0 P Ƚ_'@vo'O]+98 5wɊy+IYE*|ehoC5s\}kw&让Mr: *1E]gb# nE,4Ȗ=$_x+6$!X޻vGj_=\Vp2UKϰ+?vր 7n9.K3\kbX(&ڹ"L\LHtO>O8/rq_8N:mBZ.Ɗh6tέh-B_N6+b\aqevjVݓjjUͰR-a,-I~7Rʅ|3oq^o➻[{zå~Cͯ^pz<>}~; @x5/='㬃(AEK.wžѨ##s)XTtmN=URT8*5F0s~+&@S=|3ٛ᪟MLׁd &:-+X{7Obyםm[vZ Wբx8-#D"#urf9ϖ<㝫hU9`kw㐸]礙+5tPO@/z_q &~p\Q4e޶P=ܢѨ4Y'DowZn)ieBKz!4L~d[ej<@]Zę/Zc5_󮝕Yn9n챓> ~IKXk]?:"Pԁox1c$Hqcڡzjd[je7Z٭ 8iX7,yjQ%ӊU{ u3\EM .ű4jDVCD"Y[`@*AOu~piF1Uga~nD*0Y'OLn2n2NO3ѹ,K)Ǫc}|\f,}W_CyolI"Jb>w󸷠U펻э]`CTn=5VTrqG7n`r*@P:+ gF.(hEOU %b{eojzQY-._7@Ee77T 1zFd 2A \~bbvFqR;!fDppu!Upߗ(;=qD3z:+ ۥN,V$Qt.^ġ=z˷z.5۶ǿs۪]Ջ]^`mϿf֔)_/7;PO9AzIr\lg4ٗ*:;mЅ:Sc ScӠj!L}5ZxeTMFKjVx%f7̂iBNoH$:(J'!L !|}w C-|H&xE8s+-bm$Tޅ}`d֚MrʺS?}ыk_~1^;@}!k4"e+O9jM{洎A &0yxr<mْ11꽩>+ꙎPɳWEӍDV=T`"R(RvCk+VfaPPW_)(621r cRfbDRb =$!2RD7$_ޠjTr\:.WYq جjmlrg&o1W7lyIYgNSS>tn$oF䢉⋣[k5ȿ,X!f@f7YC(p2;E4˝IfTX!Q؅N A>dYH鼑^XX9Z2cFΫbKi֒WS-slgųj'-RݥoEl*`j3 j1y">lPm:R~QIS%=\p"%ܶs{,E 션ҸҥKqQxnOuܸ24eÍD*&'nM} -M7uM7]Q q2`:Af%J[F=ĂlkB6W yyYJm #N+Rly=8S\zjw17E30NTqoT^D֘(j[/e3LDVQw?#Jt)B6{*Yпe`ifǭILr#2Y˖?Z,A5Bvc:o^iҬ߿E8xԒJG!!a@ -43fS>hꞇMʹnkr =[@xbrm]bEFpn2 5Kz]\-8Un,v7Hӡ6jϟ%r.IYӺh=&+Ʒ&,D.r-ԏ\.*?x$(n.@o#vf-/i:$0 Gx"l\dG?, x[{x?ˠOQ-G FV]<+$õf^#L,vMo-F9=;*Q`Ag`6y)6ת >D`߼lYF-.48S{X}Q#lLsG(G 'Tx7 mz 0&y=R6%d bĜ(eMpWR6Cpb.D/QֈTЙG õ0"Z.{&񋴀,8H&A,1Wo ?&.&6d )e.G|I; uq2'%d&"+ֹK\>(9Ỹ~ӽ_|1V"T $٣. XJ1NdױI,NljvI*ҕ6IvI\w[&iT}>Rz%5,o'Dnzp<ʊen66}ڮ"HCٷnnS7[rZ!d6f(|h#s8YQx)saDr öώr 1FSqăy=-|s0HP8kЏg4 W{A.Fީ^ bڒ˙(PND'%|IeqB\[*΀E[hܚc+4(@wX7jĊ~ y1t.;t_i,vZw-F5q s )v B?Yްװk\/:l)G=Aog|NuXZz lT= @4:ؾ*بUS}nt \{WjxЎy-&ML=P`?fdv'+~q# AG|bEDZQHVwS'mFF=mU/[nF=~?&sD@ ^a tm` X`ᆮ~rA_w9ڦ/{wwSoP`@Q?|E|NDW&c׳/&OY_, Vݧ(0;{_pB;X !~u{_[ =}΋@$cr?d&W6'9(sp~cUfB9Ou'Qˇa'&oY=̥FCmX7{ݩoQ緰Fr8ڄӌQ+z+V¢JEwyȝet*˿ĿQ(qҾ(qJ-d:a8Ge~ aFM 5oG& ㋂OB?gQד",(u G.ѱ/'\__Ȓʑ@D.@kB"b-" QDyyr=_ _II*$y PD0uSjF> `KPI4*Bȓc?DR?xT1v@LER@BoC +@%/rz>$d]TV?r_3١;`Ld19m *Z,5X]XlF?X($ _HMt )z d@~EAߕ!a6-($ f@ t6DNG2@>P4w"~(P H @Tqh @bJF֤aT@P?X[B Zh@"P( 2( @{,PVA b.Eʬ( 0  15Fk/ H .7~ʵmV{o{l T<%eCH#A@M Z"CHn l^1.D#ƌc?>bm;_2G}f`Voܝo{3[kWo\E#0`f۾5LRLXs2tLk,۪NtpTfv)ԺA\Ymv@K  @UJ>zK @T_lڅj+_Fgxx>&၀Y.N`c3/uQumW ]+b] S1["pD]F'A0ԄxфG~)ŀsi[ji̪=72 r53`-O.fc&_diHL DHJ~ i!7 @A4CpfFُf?6ٴ<K3!)Ϳ!VK jD 8 U.oOC +Fs|q"X6H_WX4Ql:(Yا>jl*րX{T<69=`hcIƭ֭fVj,Rc@zEO^;<|y߶q`|_oO<}@PӮԝ`ܩr؅vwG |4"ɷ@?Q.aoulE~,%pr=1W; v% Uug?Bh / 9:y|o5JY/aMЛvv< ~"JF[?1uw\P•K Ra^_3i)#_GwFT$]/}|z8븵=qYafVrr*˼rnB mXx)u4᝽9T,FbYtQ/TvƊ]S7'ģos<9MQLsbX0 !.{7:;!Mvš\5Hw ׆n."$B ͎BILe?1#/ՖaV' HMLg@*tciLot=%jLz!W?ӮUnrl ?)6,K}j\"*RIy6h_3 kN**y5 4DVU&(0/3%C YOgVS.CGl%w?IMBUxXmRO(ĵk@S-M_YGO0C$WWdz?#Gu9-,¶̴_25:PhVh}M_t>: LNjIs ,LQl/kege=OhB7U*aHc@u EkfxQJ^EcCrB}.fzaش+ff:~U ":ґk\sڶ[5^saP6o#PĄn7 K:)ȧ__?b@VbuJ_^~ΛMW aT e8,U.?(BJ< _ȕilFJ."Tŝx0/iLK3oBXksj~U=cHQQN?MYy*wzzݜB݀M9|):Lwdzʦ_+ĵ8(x}sIuɑ*ЩH2@_1§+B=yzRw"xSv:x D b咰 J|k!ƈ1 ݨnuAZii)ICG#GG+d{>DOp n4Vvovw]nw;YvfjyJޯ)I!番Lի[Q JjWV39fRczW"lhrgeի g" JqsǪ8%Cڍ M LB)g3cgVPpY=ӷKr=6s-I*ZC @yᢳ)RJ{)AJI:nӄK! XzoEѪesg]i[/#Ѥa_9+v$Ҝ֗Km4 =XQ_#tFC+8e`84S59WbNuڹK7׋֠Y L|S@ySb"*8clq_h lX;ddz'=;f_23FBbv"DX- 5NQY2vLO z Z#pXX+H goBVa1h4{gLaZ[(>`-dR̬J{{~WHCB6wB*B+؁X_LՐ}棈Qk_Դ~d<!3!\EEV  Fg.W~pЯ*Xʂ'0+!}fz-oõkaj40QZWm鉉%PC`$!!qRpb­UXz l/ "Bm۪Z_ ~50!q 0łn,'r׏vG"', !j@ 8*А¢@阧e) rBx  s@~hSfJ?ݷcCɃWIb!=&[fouxb,úbki9];?kơbPY2RBdf̩2pŕʠ^➀WjgEQ`V~&< L(,99in;[JlcY?ۮT#NV+}\[d}S/퉾U^싺^kwE]^67# p1h _J(beþf/ݹ{9'X Ų\ʜlMCg'5'u_WpDyV|̖)eV o`-c^dbPF|pd<ʩ6 uBQq';66_ֺ~Rɻlu<-~bab0 !VN Z΋>+5EMRt+mb@ϵp[18@C[ cؗHa$7 H#:a\;]>=t9=XԪ4̛ hXb(t:ժ]FJz?BR`޼ pdu@1ʱ#V;D_ n45"t_www3&E-5V='pAl}MKj`v٥=K?Mԇ^T[ Ub6PX@{#dLK+6Jdȅ6&6KB ^-#QBV!fapbh7޽8WW=q`+Q4U&beuo| 8u$p>aO:|<-z=yެ{JQi_+7~Z15[=Zs\1sRl1CjGC5 ( ȐXz*a `#_Wضd4Hgs3Uȡ&]QT3;:eFB2MZҪ F,"rm::vxAT8/8e'f~&5 HqE‹0Yم={(,KfjG~]TQnDR0%,JҺAt9;*'V\b$ҟFtQ'fݳ]4To]&GuuUHݜ"?x%g;s9`u^uTU`̷֟- ztF\m~r:ERT(fZZENʷtS-[ߺo͒;m~u&2M۽]T ~:0;o˼͑*w݃=e;^S,H=VR>Q?}̲EB'oɆ"?܇#=8j1 3ҁVHBy/M{u]cZ70WyiYݻ?Ҥ+Wװ~îč޺ӎSZiKs=ȅi)a9:ױ%N~ݙC#熯$6*qVu&_z3 _+ls̪SJs DQF ty8?yivbA2*zbn)a)/Vƣg.󘾘y7ӥ!ݻS5_g+2?ֹ0.a\.~YcթPlt:8|WbEZ-T;hxq~H+.9Ds~|O3%;=3S/<;wCHb:Z1&υt̊L7 0e57tt-EmaJr򚍚_(Ž`">~WVc {˗00.^G᫪Aٿ5Xzn*29́O/c<0#_$-x;~;G-b ق@~_cea,R6T[S;Q2!:xc_cŵBS]|*0o; ́XYY+2:Xx w|Gz2E&hK*ONUd\/P{HC]B8>S ·"A~1p5ݡJZoQ!H6DGX\FL~C6HQ|5} ~XL%/ N)7. $!`6/`t4\AhFuF;Z1(ǔ=&RN1&S-^! M ҥ=[opS>-G#VXQ|uӒ`䛹Cӻ@m}! "Q≋q|]a=n)}Q9K#(xUv;/o0(bQSjSvfs㇀= &,`UAl܂_=|葈G\:{"hmS9`oO0'ۀm 3E"^mcXDؖTOy) qFiuufE{]뭥jQ\9D]qfݳE@<g| HL2@5Y.^L(uBr |"%k~8)˨po0)>x F! ^gկ.=[rGκ:4jwોLq$cH=o*O0Ş ҳ}ʭwH4Ōa_}5qeFtZa?syqܲ1Bڗ0$|mn*|ſ_C=yw[nAd2""N rI˪NүuI.bd$J,+se3eus9 Vf849_6DY5 5hM8Omt&YG8'`TL0s W2YڕZp8;g70kzw|4O6<1& %D, UW43'U efIД F, Wfg[U+[V^P+v\!_QQqќ֧eN . 6t5Uk'\lA2(PPol.$hqSh=4»[;x]}N]y+Z"+[)՜Z5/BIEJ@[5'ٻt(x2 W X"r+U#3MU "-ƈ_l^P`K/?i`p]7+6ù<~M؀aC.`.!*\@\ȕK`j.$ͨF:YX<ờ5SLR^%ź}M/Q -uh׽lXZ{F7)$Qv_x5ZӃg|y^7Jt`yyo%hʁfEP'vX" @.ڂ QIiyS7PJj8kT*wP.(Wew嵷SydLqfU`-M)7CQ ũ"F@]Os+J^ “$ ^]X!tT|ڬ{ y~*Pob4Mu',S6 ' *7/ˍGvwDǽTmwNOHۨ G^Gt+_ ū4V%TSD.(Ĵdh`޲?ulyRتub&Ğ#{F\@q Й:S0Jݜ@\Ec$لGBW\B,?2Jeۏ4e3p_EhA"I-2]mJS}WkYk(zć$/e|aDԃj]`-Pfz\8fxҶkjUE>UΪߋ }ޟܮ+oh,vrXK"z aՆWJc9{IBe[k ثDٴd9u~0:?NG/=|w}EK#ka|tv.й[ιZ0Zc;̗~+ 56lo\L#_ _WPɝZGZ);@ z4[Rk`fxAh:pbnK4@$tgs0׎EN=sVc]q3(wؔJyWO]Xb6 54"[#kvm}жFG|g˒2\o;Ћ3+CF\?k{N_66vu_ 'fk ٻkݠ/uQ^%R[vձ>F_[8qI]bzsEbʹtvE uڝ_=hM̃M, v:O=3 |Kc|lC;L)tDS?[W%2aH?wæ鉯. Wb]݌N(BƼ?1V6/co(jS>콴OF7lFi(Cn>Yq [uriTܢ&=4ao̊DD0׌bwW5F<ٞm ̔6yb"Y|RbE9,.Bdw/=Ѣaza^gRׯXp>g ȟt5@_YѰx3130\I yATo:V\|y@grrH'<*0=YXO1ޮOG]aC? 0aIku_-R-aU I-E8 ؅`&E#Kܿ2U? RH+${H%v}|zzM?ɿٹ K"aGȒH+RHs ۃA|gqXɢa!1^+HH$>c- "ً/i7~H(x}DH0pf D/ҍ3`,n80DyV^֛ǑVH|Am@ 3s4"p` ]Y$I%,kK-_2[Oi.)$e-^ARUomr+Wٷ+m]dzK#~e)|3b :$XA+>ąqk|;d'JdFܖ|d3C4a ''xdh3?z7ţx\pڔ ͓s2~S$EqTHJxno5뺓y̝%! Iಚ,&by.d<+*w##6@`K8*GW`S#9qQN#OEyqTHS)&VulE-گ6u{K޵"[VpVf0`5T bAYy,'ϿDǞm[ :WIK ]kwݔG,vXC-LCESOalԜ1!5BX˖1,J&?TLvԛ-l~c5bTruE U3#+ǚ, =WVpDDо?d5o$$DT~,>Uߙ1>0̭&}ls&&{ʈZ/|sS e4.g==OV[VTzJFQfO/+STn@m\BӘ7>TfuZ v/g((os{l$kL Q {Up&C8L7`t5K\i:WcQ\cu2gj'igW(o>X#4M[ΫluaM~3쳺sVmzVIĜ'9vJOY~`͍,&)%kkrVӸ6ǷyshlB`+!;C=q8#m_C#W%KuٛwS&j~Wn|]:;N#MO1묘L\awd|5K&C0%wE{'-K%\_"GKnaZ_2յw :OwVU ׃A ,s }U=f `}̭"[njonYaz[+y˧8`B67g]M~us))aJ^ṽ`_G/+ʥnLC+b>7v+e`vY0Na'ۮSq"h, jqֳQ]Eץ2`׸,dDd 1['{VfK)$P-wȊ3f_IDξż=Go[B$7:pcykѾWG N,Hk˰o.mQO 5W"(h.0KsBF*ڄBV q\[-Z/ _lbқQŒ (id\'Ū1FĒG̅_"™6njIIj*15;_#ca#pbKXo#VuZ;acndlDsEc$vyr~KƩ NHgx5{QKrܮp;Ѩހ1, l68zk/#-+&>yr߆gE'3:eS5>hյVO1;W|i?2׶^ѧ3gh#\/4 06yiyrq,qTb FF0`1Hƹܗ'0.i s:djTKVmB57*<0 ,HS9C#_*1u3r;`\(`o:hôh4mRGW$A@0rA_F: h¬G?]/[UE5G 6E1-i)i۬hI0`9B]K]UsIG/˻` !-m32JJUbvIPVj]CjK8j"aEɝϷrzE|Bb F k=5yηA k"puX&2){U*8CK+ d&:a~Qʣ,*aCW q `Ϋ5ՎXcUpx~A 5̼CW܋#z-W sEm54w^fIPPp(}W(V~1 `Nd-/JYd]U jIC (-sQ*"0=Ŭf7fv;i|Mu*juw( :zHfC0ףʹ 4 T^W[NJZYU;5p 0K4te{B0d![6л{rcɗTt^~ܫGOj$\\GsB Ke<[ &AO=zO8E3ll4-m' ދe xCԼ1} X55cX!rFݾMRʥP>76d\Q8^ 8Yؕ8\^:ڣ'd"AyE0- cwXW:._{N<씅STmD\|d,}Jf*e9ɷi$/r"kIbY-r`i- Bѕ(& ɡY; 1MX#||/1XnvlUjvdA[A+i œ]8=\ ^Ekٖ Y&fC0H.e2g8Xq/=anmVzE}ʫIf='lgqlu&9 e\Cտ'{vIIk8ri|}cEsg a^j9`2 ~HAً8a?XlsEpovi0zNe4S,͑Ko[>_ԍm^Wc]sx`]_61c9sc' a h+=^Bّ恓  iV/?֥5fK9{7<0MbAa_"[W? k0s_mj9<|Ϲ脓,nMlr/]%3Hx0L2CEfH`[fVrEǰ[Fy"̆L W )0ZhLH=8u]A`zdkNMUzb@&56KOh0kQzqG }sހmt9P4"!iwb&5trqk9~߶Á 6A5~Z{rWImd`'Ia0 !0EuW+JRtކjw\DW=P{5$'o5-cAЕ̵Pt֛6o ŋԃe#A`􂍨H2DT˒ƭtP02eF}0 ^NH 0"ux{`Z wl(أ+f {&aiR6*gr䖬@>og3U_1Lk 1Mjo{V$"k+dXU{- 0}% fC' Q|פoɘ/0ǽKی+ 1L_ mmsQփYS#-*)ؽ-8y y[#KN=e@lz𖀉i`b'-xؖ:`Z`I%^`1+Lj644:weW;9/HunL'\\h]`DJ޺r>$Dv5үv[g00)a{x94c" ~=ꕺH~\-b ;|6k|x~K— {ugU\'6 Re=Vμ\]ՔR}'F{9Wл a*="sǎ}u+.ls.ڭ1d%~{} 0"Rs:`IӬ$.`T Ot4Ʃ`@+<` K 0# $H87H g*!@P&Kw4/Ĉ),"Y(pQ A?@mݻw}ڵϭe՟Պؖ2 LeD¡W"^; b^WHsaUB) '4=[/b+xgw odz 纾vQ( CE 9)A-AlM+nFR .T%̆P 񄬼E\bMHbek>fҫx {!*:Uw SqZ5;Nܐ<ǔ%-m`wm]Xc<)[ IGo~MR>; 0+h>C,2hoLo k{:ܷ1s=9;ޝqRb% 0YA({>ZaZy(yP?ZݑmnhջߨR{~l#>Zof¾…-zOvPdIZsiC<M*1=QQM# *-o-Dwm] ,UCjԒ 6 ^XjqQ ? |MY+ZUNlj;6J:ʽ9+90@;,^P|%bU=VsH``(bH*"]Ѯw9%._& _,j/MVQ‍`atB/~ӽmFY͓;[0D=ft!SX]w痢^r˟z{_]+~읻>OuqQ˽n:td Pfq#v.;otД{o[eUɴ`QtS)/k5޲1g.WX._[1kSs\+1:;ڨڲNrXY:pjusun}ns}^[֒B#.dy"u7Q" D_GaU="K${LCxۛwT2A@j`k^ڭiSN~Gr(xjE.WQpSjW=|L"_/\WFNNSgggv@:X+k@:loklrO&I>ZnʹТvvOmRo]5KEhݟ;74 H]U  *o gݦOZ^]cSQ>v1]p4=A#{NCOӓUO|Q>| pRq%7\*.劚sЋ/= E ǝD8roK_wL]F]omnpKʌ$ $&*I6v;zIky"Z{;dTh{ 8 q GD+ l'#?`!Ij8;OuP1cs sB!XLJZ}+E!?WUmppr\)|iX=˹|q8Og3aN&-~.βt};;t@D{>2ӗo%DJ\.&[rKt? 2ɷ:U9g/FKx8qt^ q O[x  S  ёӇ~N>4P0O_yD4]$Ĭ.b+J>Z|TsqktB<\\v}} g}U5K9+ezI\+ (&Y`%tLl%ߖs]Gc{L{s4D`li1- LbE+.pvȼ|0U?ZdKR|OWPœ R˼VEl.Vx}3U+r8!ǝGp?kTs~{uE[_'SnPESaC)&7}RIHCzBi?l>N&܎@cHxB:5QԌLk|a?lC-eJ?fD)!a<fc_PBj5X=ia.j/gnv>>؋W)Wyt,"zۨ9H ߚȭYk=&&I|#7HH($~6w Zv4jB1Bb=r瓉M1y巌[N`kXU+PC՜KE+k΋twg@.}V #PJgYUpK2S,Ǔ&Sh+Ӓ?aHZ87/v`1x֌J8N,oֹs"%e+:*fRτ=7s/JvgS}/竾|}}]ZB ,mO~&I2KC.@A”j;OM@#?9vcq ?ڧmj/;: g/;t} }\L3xT4ruC}M-/,ٜmsU[;b~7ۓVm!\{ u&T??8Ard+K ԍcE XV ujim2-ۙ|qGNOzO]_Oʣ/N}r 1X "S 2CJ˟Wup\nVbu.YC|cmtrqB|_&ՠ"o[헅օ& /NTnb9r;:/ RO|u\/ }}Q[Ō*TlJm&`/K Ht(Fuf*W^h Px ˫ՌT(%8>0nbv~':{9 N\u*\4B@I5D⬽j}FcZsM.-H` ܞx08ЁD-4Z7i$T3W|P0H~RrLe~4 :8kd"0H֚tV,e5a$ ~1U) Nңh5h^5"iq1^`up(Z|-\>w;GohoM4xi8 EJL1$Hʅ35$IIF‡0HM +ƃ-,|WCףԼFo آ:]1jn*'}Cfu8ۓJ5X>*o{& LM b$Yr9zJYKd:r?Vͳmi4@\X)_#4쾐S#[c/4(u8hg*]þܛU~=0nMF 1N,f=#{_Z| q4CpVENh[ݥ`YxfYI5W B>$}c#n/Kj[;wm+vwV#d{<+W~0qƑpWs]Im.4VGdݧؿ+zە&U+٪:ʖ"=fSOr a{a%v@6O![5B{Gc/q[zr>w<p4T8_/ޠզSCZNcw:FoMOР$O8/ Tt`=X*)W9ާA5`j xO:4ܞajTvjz$ohj?d8a>X7q&)^ J 0j~嬻Ip~DM4ﮪ5$%4HKqx.Mn-b:!5]JV}k;a@\$ }Ƌ!i!6}4 j6RJ&CuȴyMk/,&(՞y_şi$l)? &t܂hw35R o_Yl4ь賗iޗh9,IfQ2 tdq:l;Xfm#?VF2p͑gGB"e'5|vh8 |_oKR6;Sl)Оuu䉾  6AcSD?/4U\ɵgɇnI T6-~l`:p6;2i( ?hE9LUneێI-(?H)kFF ` 7,R6.s|1͙7^Gh\8w ogӪ>Z{J+4XߔXfϪcCVd 7a'W3GA1i3$z"RR+>$ɖ%7/R/#<#-) A}l 1z&sL: XR`:Wkp*hIߏ4ьr8yin%K8Z 췫 n뿲pw<˧K˹ޙ} SIZj3ʟr1ne]|xE$VtBJ4qp ;osd`ڿ^㋌LD:e j>w?dͻ^uSѣ|Jٗ5']e ,35`6ƶ?%)}2 WE7cޣyCG|Ǽ~}nɆ}l {"(Yw=H{ۑN"bڦc0yfJHA N(t%wji][NK@ԿHƀ#r"¤C~H$T"(؄gހ9|N*7 Mku.wɩ"36_ CYzlwO DBQ DTFD A@B˖PH o zmW}wm*BjF;+~Ő{K~J(iP%haj ̯͘vp57$scm,u%b u_4R1ĘU@D,(?973vxkMqfn[[m60ZY'͠ l"/x%HAcU7UV%!y9Æ]qY6qDvF)2;,m`|QEd9O1Qo،sc UAo\3 :qnUؓ.]#k'nVY1`[x;CFA,'cM*߿F]=\xwǐ}C&ŀVz8V~a Zgoκ7.zDf+"<͖KZ'o`xizJsV%Oq\klW>x|T"Ds@^<^/&>!'8h%2bzM F^hKKb\",ff 4mUSY QՁ-e~|ql\'V\ +!b!6Φha:UZ \@}?3*SB˟\~raJ OesQgPޘh祏~eoqc0V${VtE֮N4Ύt$߫ζg霡<-şϻ cEdDg3I?f(wUsUi~엏3IUU;@9,'{??+y)7~Unw&¤%Ljry\ F2Do: mӎ{S.,xͰCp6C5. zcvi,>q^@Oع;p.o' 4^6^[)K~hB$Eo{ ? g3bAPw\`sa}ZI0m75.|lssާZZ9eML =΅TI^8f;-<l'FRcA.l'n넡n`Ī~b$=5sO*n{>EU;-\EW=J)wOZqjOEfci y|VU=}_W؆_~E#:8Az?g- £`; a!v5?Jd;㎞L?噜`lw\qw^No :/:ˡޣpOuӟ+^UmO>=/,&0 |owS\+s_G":Ɏ2g \P+A]`Ix),i1S)-.2gC\u3FO jtU)C`; !`qC-z^xG2#^|oYB9hͥ".KG@!W]d3-$C<=.8(",֕|@O,ƱWa͑xyU7 3H1~Bv=hʢXcάDPVhwnȠApFW(im_2_@Q @OI(E1D&' K1 XDbZ :Q*3B{?P8Q~AaUA)/K P.d=r1YXF@٦R2F.* B"YĆ \=\l 8y{+7&M|p10kxI!UJt6=/G;g~1A't1S,d)d "I" LЛ%f^Q E$؄L [1D 7G1e<Н̯&2s0) F~OM6q|_)N`P)m= /%mL4dCETd_D=A¨F.JE1it&˴mjD#Ih&2%}Oƈp|dI,StqN"^$,T=pmDiV1"JB9VC&Q3]:/#ëJU0ҫʘ # dkxY_e33Z,iaN+6 . N`y XHFr4!ƤaTg#fz~EqfV \ſ@CIV-bI .vZFF͕dIH]t/(KLGX֣ $Z=&AsM1y*& P0P@ढXO$xd%(,W% `cBċ E24.(E,~(2 lY쀈ܼm0,BD! a'A~E053|izGlL W+q =e7τ\=avr x7*%-%CPHK7 .Tܝ#3f-3\X#{VeAi2%Ym)b; (+M8ȼ-ד!bH=߆_Z8e؃ AlgL_Ο 3{0/{eBi ^D#A *XؓOq%!SApmhC!2= ?6 ;L%gosqs[ L&U|ӡg.PT^XXVb4](+D+jLQDmUtboFzBg8@Pά A4O ̂Ô1$;VI Ab,En,etM2H$8 ",b:#C! <~gxWI_!EȖb&*@tdx8޽c `0P^TZ;cʆ@0HyM+P@f&|%wc6=??q`oѯg\ b q\$c 7!#L*#fSȗ8u{vavy &Xoy bQݞ$HGr& roAb㖑d+%SdC0(xJԝC臌Pb pHc/~:B>`y"# aP0z,\UoWދ. yHxcf(K*N&c}4#R`LnO6 xZ E(|&)R a3y=l{8{C{*=!''*- 5 e?|J!,dʹAa|׆䮀W#XB~6Smȸ!//2R};rvU=a3!Zu\c 7m!U?|2+dPQ㩟,`jkyHق+a1tbB$wdQ #A⭂,F_覧XȲNj@]La"HL~O΋;{`EmxK#_^[ZGpV2G:!810$0\&C?9V*ͳWg 0Sg &^Gc2 ڳQ*6Zfq=wutgx -κl"wYX>Vg8G~9rY踡(Orl oC څ%GQ^KR*Žf톧p4!"bu5΍8[h[d$wrQ0iq$>fhL9"W25M3/4 "w\F *،DT [f1*trQZ-+L9+b̔x(Bj:*y)HƫS'V.OEojcg~0zP> LȾ =j!^S}j8lvAXTUrp! Kծn>,jȾ W _- {m`kF#a0x+Gdm$<׹^pwj݁7A_Yhf>ˋ~g=;; <\wKgu^n~]]ɬNjgzj$ EZr ~jzh{zE+ZsZVb=ޫH0y<;tzK-u"8aX^Fgt7 Cja>ȇ䜤R{0TeVOh'X;ApRӝ)FM6G, c9` x:B[SRG0Ȳ+a}jG?2$hب[S*~ gOf̥hH #$Ẋ? A+F` :rfxAI `53hGF>nkvR 0o07;%Z:HS{^jZ9Q^Me;xZ++ wt/rD_FLuNn͍4܈v7]»wǜyr[o qZp3f6 tdR;}9չQ!R(~6Έy_rC ^a{ve۬Ÿr4ܧc8$Wn?Q,޽8T(,~O6F!b!DIOPW$ ?0FĿA,L+SpKAO1_(A~:Zܺlh/W4 tΰ:,\9#ﰁ, ACV9\kі6ZlfdS7IQGZ|ϳ^ggCj/f[nlvh/lו.pC-x{iw޿ J3]'^;QyX]m v׶az5jmF6Zfǽ3`7XǖZ sqyFvF٭@I&h}jmгe~Wd0_e'f٣V~{?* H^nzu²cu`߷$A ,;|"@Sl/;S#Y5>go͢ۈZ6.[ףH%ďXr(jitToK FjA~C?UjAoX+8A)`Vv\f,gpHW$CuM1ȠP"}Z #I⟦|S;Z'p(Da/jH\˼Be0ؤ&5dج| PaڟY1 nd$8 @)YSa~0˳Tskxn~~a".ceiY Lʫ/E U$ chd/Y70kc<%2ߧ r`mӾr >tJKWs?BU.5ҮꊵVn[ս[hvUZԮU5 p3Ͳol݃.Wm]޼1k}7jѮ$QuV;՗8]l+rԱѣb aOv.ε&=֝lzy~*ĕA5c#Q@:]IkpGFkpی4 F*3 Omp_!$}ʢG,,a@ ex`[>vLS@Cbe d{գ<+TrI!qV n O"3~ }dPE)c VX4l=7ujL]P%ELjB8lZd5kܼr*ox+-Liz~v .t.y+:|N=ޯ{=J"5޻VɶTղ6S-ii`376W24U7iarStШ:WeW[g_Ā~aTPt.gݛ oNO_74أ(QD `"v+ ^WA5ܿ/ϖ* k҅A?j[|VI?D}D1d 1=a%JQx\@z:w"d0d6{M⡹_>G$;)$fa@"ՒSD_3|5?~'e] jdS+:䒀nŏǧ<*A~`4'8o &Gw<,ݽ$%nT,;8ah] 7%׶c>4OnTMl̇>\ʲ.N~8ڪ(6f]vz$0B5؏1lƜJ9gܱ!|q{ y^%07R:+8#2En`,,㷭2JEZ?(hYK ,K- RXL1" C\*cۮhs?=ݻ{n4{ζo5vMMSe Y]9|rΗ4RKB HIJ\qC Ht@IwEuM8>%X{w{.d3fUܼy~#FƸ6r!qJ--pr/jz/o:B9e*!e}ܸ2QDovHyg4ӰƠ7-mLT T` ZFhW}YViB5s3K(%Mi3:ZssP+јT4,f +LFJ Kp6{\Fi>cTW>&e2A7˶%X.\$4OoΆ"(Eb E;H94X2A|C1eaFg 'pd->9~~G &5FMtTCXZ'!{&.jL)UXrM ˑ—S)=^dC:_Sf!aC4L`YRLy_LW7ρyDz>^CVGTm\Mzr#[r #!iDT|%US8NE_"jPRZ.\]hJ΅Z$1 ܥ$Sz}^/QaNC9`rZeCJÍ.?ix޲6^Mc8?_),ֺ?d>OD?_ӓ$\Hb\K%.)ȈXbR$jf 3JHCA'x,A-AtzW8G'|LM d ¼0*/GRXab3Z3dc,.XGk1! u)HUcRL_M~ YtJlIDnJ;w/ sn.T>+7˛U%Z޺N$$F[7̶=yw26dnŠl5lbwFU}Sr vd.Z=TD#'jX / _2K)a ^ rdR&ER@2ȂzZ `b!/(YlvI2Lg9FZG0uE{_kM\~"01.d+0g?WT5tIQȼyA%s9Ga~5(3kLuǸ/<_Q/yD($C s )/N|-%}?9lLS=-[oxk|'a*( (}N dKQ#0 ŠV#~;}=NL}1ÌKb@aDh&eym$$ ;>0"6m~?x9E԰cHj*s #TXG+5ᾕWl1A`9L5($'lSp=9&U&D^9Rs*L59mj\W/w)A>*T}r x&X/8a8q/l_y6+ 075U8 ecWuU) gKXθlֆKK1 6kCNcaS_D]aW.2o !$xۧKb[M轙^11Wq gD}J$PJ ӭ[Ƙ۬5>n+bT{-_z{ѦV—믙 ծt(*iL\YQUbچj Cr %戲d[|o?=âbࡼ% r D@d Ihdyyfd] aJR}*jHҟf~jݮAڼ$+@SpT<~Q; aIbyK//G^\u׮UG/Wh.߂o}1%y. Ao`eyo{s|`_y-g k)6bW 1ꂛr)˛3w&fbB&П־?i505ռV_jrpU4ݝluE/V c9yfܮ)&,9˾l8aVl0q'hP}4>*lh8!љ)gTݯTf-gK7-)VӤ VfxY,Bb~M]'gm 'aXl\7= 3YAKrNSO/;ggXp￧tcw_xY\A_|[lCwh;Ϝx6vv7M5pUxjVnN۵߆7OڙټH  ]o}^/ykx;C~MsۆK.K# gVݷ۽7CMn Ambv݉Uz˛nN-N5TISQM`YueFV{I_4O?ǠRU׎rmѱ;pwG#~puP.Cm6mzq~k07y68Z e1>5o:Z6kAA봤A)QA#6 l`cϸS"S >7i}o~E~ _o#(2C35Dyvo0 p6Pϖh-nΫ5Kqt𷝽uL؁$Zyϑk-o/̪ɶu~_-՟%bّ:hsHUwy V۔EK]Ġ+YvY!Xn҂ccp߃;Bezd[u(l<6|/jCx+1E_"f!kFI0сpCS= N Q$5I_{!XdhVX'.,Wu"ݸ\h?{@2RI DG@n >xC7wE1-0#p." W̼%yE+x G+ǮXWmW?_+^9~Ubo?R@@@_@V[-w{`[0Q-@p(ׅ'ζl߸h 1:lFFoL Yujc3/זE/N?izpHh NbOLDD> m"42P6/o -<@p0c 0qm [A$KwoVmתD ?lOJmz-x̘]r2Ɍm⌁U87EIa#WI ߷1ګzz~)\D\ E\n6"1Ɲ7t['|~dK.1nWJҦ[t}l=&ֹ峵Ȫ^c?9ߪ-.l={-zEEw'sceSY]@ k\RYV8^1&f)73=pѯ:Oܴ6͉^}VnR}ܶoO%"*SvfL_F4c㺉l,w[=~D57 nU߿pyN1?h1 )&] #2hYluճexX]C'F)nWs{Eά}Qbgl?~ )Pz=A'jp\c,1*t5H˕B֢]ߖV>wM;-/[P SFMuǝ?7?@^Y5W"LW">?ulvcq\ؓ;͜ìzp\&|VB(7mB| `E(9U$V]P7E}6/`qKcfIHLrUNGBFIHPjJ?%$yEBHH-jG\yd,UFe%`*/as +`WL?Ra | O_ٻK5Ƴ5RI4{&Ft sek{kk5ژ3|jɆoz6441U%on~οwcsΝs8ID7)Q0UZjPD[o*+^{hL%C_n;}մDT]p@/4l$KkDm% u [' 1@_KsfT AR @? H ovnvu:N̖jaxgJ Ti6Ϙ HVyܨb&XQl@x~qi4j3Fcw<^N7V=)+%9%\8K0!Uq"N *#EEaLiXdU p/dK\ \V]p^6Z/ϿD"+svbѢ&? ,YC_|!Vi1DV}k2gtMp}1lC YZPjHb"Ux_ iYg#AbAV2G=ZRvQjl/Vk/)m94b7|]eNp֟iDv_ee'D+/\ ҥ}=AS%qt rSEpKlvO>q7Zcǧ*\ePzGdLϜb3EmİV2XA'[JOhh1ژeAFppq{]cZwč~T_C-[i7]7KQ/Y8(*O q? Vq0j,};S꿍7}Yw_=s<헣⸂*zțyN#+LW fl8S8**XI 16b*Q߁ *Uhdg3;8x}}Gf`/>_<;Ҹ;4"6c:`o?2",&!4'ȉIL/>3=S.L[_zꮱʚց H-8"^V³EN!x 08.1r3:V9zXZLJ\sGL} G<*TM}XTra;}?|3luǣ[$ۑcj{Ӵ-!ta<D|$ѿ8Pg'8hٙEA08fp&w:F*6}3'kqw|`XF|۔eHgmS v,=Nqd#FN:a(VkW?(9ѮX^+0W1]("];W% P8˶zX!}X]ax,,rXgBύ36Di-GM޶8s3&k)lFjC4XaX:0 oK­}$$4ƗD Y&_4+7VOw HyID;|ln2zMuX!C{6C(mP EIٽ礢%3g}Ka:+*\-WKrYd+RD3" /&A&k.7u`3~C^h ~rf+Efg{I)3:eA{ۃ:kfk_l!(n)ʩ}J]g~SΙ*4=5MTRfA vq"XI2t+xӻ鯵 qڍ`lf~]׺Y?.{xz4"']~ڥ3l_k|w-9v,F"x-ƞaWMŢL׻U_:7wulO$-ylj䈄Սk^Z_XX^dc|-xCQҎI?5 Z̹Fco?rv~1eH(kOFkyɻWpQ@I!UBǒ?))/3Ė}-k'vsDodhYl➛*o6?P q34"mDQ", eɒaIH $Hz\"%DcPPS˕wlgml;n9X\*UT\ߢE)43V[Oʺoz7-EUz=#[b"_jBPK޶g!5m2We { >OfήmYN^ۭ֓iM0U"x12φH#4HAHY,'$kN:G{4<)gŏ'첟sI_Ξɠ:LKYWĚ[ U-}y̐dgRlZM7D0kQ]׹܎hx^)ʩQPOKq8>+:TD ;E0Q9?6ƃ qz]rgT-tG``X$xKxW(WHgivKCUJ!ԪZ8tI+-Řaa>sZ_'ywI YiQo6$ѵ0)yNKy -WBͩ*=`(CL7q$ RGdW~GѬ] JpC| UlZRɵZp-l& t)S5LlN_d92^)h3]k˅.G%0䝧5Sbu@L@741)T\.}}V/OɺGA/hM2[wZ7Z?t [̔fm*?ONЋ0vRfsbv dzE4=S:*]xB2 JFJ-SԡH=V*Pf^9ݦxJ !mxOKKC+ʊ!nzW<>M+PcCШĘa^Rq>̈́c@TS/=8kR)%{#Ӕ$@gJ9Dì8@PSj,Xo"JaV@C d(t&V݃3w+%@zq +ߗYjl6dzN8: ; B!%D@` .7GT/ (`ĥdžبl,o^%Jv+NX~c@!!2v$R*NC rzdU!Bgs/Oߗ.Յokq_v?[;R&3F(1 ΩD} 3҈LW/Ҕ pG|Yɘw^bb3 k)3MmW(3ܵ6\Z gO9tAtgkQLKlYɕ[n[ C /; {,??㛣 y^7XG+5rM qJ@T ֿXb)+lmehiYZ5\,tJEY<1I* ?1fu|~" S ~r3jq %nL*-j;fK3GL 9CF+y Y#hDyb`uԇ"&1}"֭E9q&F,Z$SJdfMT5~Zb1w^/N$1(@@mi*^xc~󳞎&I> Ii.񍵳릻5]g>zcH2'_))]6tJfeo`n^N:3OJoè&q=MJ ,;j48->Xn۔4_ʦuc1)tȱA Rtn5yʮÂ^ǟ/#7Cl;;1g=M|g}T/Θ <ع3CDF}F>轗K48`Bw78U֪ s|Q1G;vzv؂ qgxpaD rb{_"c҈gLzq]"+JWn(\K uϴ+^ѡ͌iB{yߦb"BO49M>1 mC%"=[ۇa8Gx6w7 !{D+s$?P,SMMォW5^-4)Àp"+0_-=&LH넞 *I6 MݺMC!!)`BL%l6'hnrdIX$Րp٠[?wn6o}s'|W1XbsX}YoRImA/^747Aq۟<Hnz^n-ݎ;w4~,}i4j$ƊC )bO9# qD{mmnfOnjkl(jS퉻v1cx1.ƀ1gxFm< 0 k@ 9 @r1N*in̗1֫A x0S:v|8 ,治KFm@!ANQ8W<& c]~ZZiae#;L !BZG9i1z`uebblhlksEܓ#noq=I~& !@0"011VCw>*¡Z.k5y `(,j2cMMB ?*^flD ;7'jy]5i,҈#3zJQ2Q#Y )T3_,i~;2#>rTՕ;iI̦ga`BC? 1RWDO>U,ѻRp %6ɽ__< > 0CDDq„fԊ̍oe[j{.`cm G,q>B]kq/&Mc@cD c\6;&+ʺ,®5Av514OtOn}7}ƹjလ".  :ȔJz ŝ4ݮgR5V{v5q2/NO>zeO,FDkڎ hkzǘioPrI*TIR+Je41j9lqΝU;|zI\ lT  =d9Xd 9joӤN zygᾓbb:48j/_Do؟I|'O9l GL$?`o`-kےXd|pgHZDak@0!K>j # NN4njfpOj^Sևp z>J-&.׀80Cu|Eob{x l{߽Wa0cNܣO6ty鲊/-)tH1i$"@0!ےs,wӏh\ /tƹ=]mơnwPK6 OQ'+9d+O@irRg1d@0!4M(Z4*JNexۗɕSN3*S@=@GIP.'~tQiq„+J^hݺc?@ FE Bֺ[I ӻiΥG%PH "qϕܹ7@]~En {!J?}X4=fcnnR oJA<BE¹wci>$ӵrtce#aq„+JƲړ^=Ƽ\pc\1QR5re*lRIڟ}nIUbi(X&K0*>eWX73bv,`ܚ> G_¼<@4a|&RqDŒWS4oĴ.A! MB,Bn$-hhD~s-hՌGJzy+~MHGqPFIn 6tOLv1Xxyɷ*I)Xo1QӤ?YM.9/Ƽ a!&=Է#MB*[?@Zfu ~m''~3ĽXi )y9O8BB"a27Kfrm-Q3PP/8Wts:TG-Ҕ'#^I?\Kv\.\kLQC>K".83 W]Ōa-r#[DaQ^KXC3Ľn7CAG9osV7jz_y܇-%TAlnkjmbm ʝjpVQRH(<"P6֭+X_vcB]"OF">!zH9Ot"c`4]ID,I%YkdBepVeK.](iIm\ 9Xhls=+Q&\me88}bZ~YZP*G҈n RsK"aawBxtּamAaSpo5`WP;?re;ټdeN6Y(op":J~'7yzi2g+^ _sHBZ4=sw13NZgPMFBMDô8l$N+:M!)K!+ԺF$JG$r_V7w##'+ތ g6jh푙hx]knI:/ݠ_D۝i>uk2l|Cxh|vY(/|цYgiW^zn[wsFe_fG;a՝{&UQ!ϧ+>N[fYw17 '-5V;YP^gɟ9rާ,~}r7GGy,A,G%ʗgw47g\gWwWO߯r.Nnχei&~x<^Oy9mR)[WRֹK[ԥĬݰz&z&JGGd|J!ET'8ru)!*.paOl]i;A?7E8L4DA`Y22y57&y<`t7-HܶO&9]v e5- VF(kJ+8py zA^mdȭIp,pƼwT)80dd1I&5~yjku-*5Ww|Jy+k |ܹ^6YZýG*X]Y+vݟL(w萛`{A^_ӊ!5&V</8qdg'V4:*X|8FzyVvѥ]Vj 1(fo{Vgj 1\a^F4a U̘5o/vЙHH8it_ڀR@Ldt}M;wNx9J>J4{|k6{gW h a,qNַoٳ}Ϳ}0$hV.gmdY phN0Mۗl/';ژW{bw]K+#ɔڳ ė9;|mR&#<:Vz1ZZ粄kU_n#@!v$ػʃOlC IhwWӠ-.-F sq':QQxm[6*KݫYbV5}bչAB4Zn@ʼV}Ιs[`S`7xy~Aǐc:֗ўprahݲ#?ϒh;%{>k].`L˃jLFCQ7zk!+XzڷN*ԸI-8 W i!CSؽ_{C5hJF깲%\|I4>E*W4azYF̺#֓r!cHy7WNz|#'̀j`Q?y+\u>|xH"c9yHw=˳ :X.>-嘳zA|ȵ)?O\sbũi(e\b: :C$5ñ.dՌ ֏Jquz W !4V榦QWN:lrjKkK91/[5M]ֆOHԕP:T3Ҕ2Pf+mKA~􃶪ƪ?"\cH1f1m]X06ޡ |Ey\vc+*~DYTlwq̯$?T폿/s%=1Dp{aG ]O h/܍+vO;Q=YZՕ_Nz7ĘHοG3acKY  s]X3‘?\5 mDs%"pg7lp;woc 92=춷ؙ6 AvZP5W3W^P"+0rsmŞ|:L3'aMM!$scF0!0.I^V<GķWCb |f]Yl~>jWLi"dXє%X!z +J$-?JSw ^k`[R$/m#x|W(:W9-ҖFKeұEg*"[ `ǎVz3:p&`׮5m!c=dy %o P線Qy:cSD݋vlS_VõUmm[L-iUqw@9̖'x=TKoi&#-Fжl2wBq1@iQ&\2UQ泱r<~Xյo&8_}L.9m)9~f5_0w6Kr=:˫}gڐ|YEޫȸW9yeDy˥De'̊xM_!1 VT; cƮNLpw8ي,6Q{ѱ4Ţ=3ji°O;4cKvؕ7u;MI(Myf$y>$x^RR WFVYOf3I+*6I(LOE^i6ܤ~F( cdmB}LL2Xx;m`p){o'Zxↂ3EHSyFn!'WSd[*jK1w *W+i('6W%8@l}\omb|&H8yY~OƠy3XڏIKqߺ>9)IsB{'AWn )Ety`l!cb/-Z&7^B* g-VMBtOx:'"#`K:/d-{\ L+qtVoplF" /m:f*P'v4VjS:u`c˿ =O]m΁9UW\H𮲮=<:K~W{mRڰ}6 &*^qgbJy7߫@c9B9隟-[-s3n.jgB>v2';5?*T1ev3냅{Q*[:/,o[y]C\ |Ng'ޔFsA(ޭ}CHՓ VSgyvkI0)yʴwkRE@8@#cnr|m3<2_y|3V̙Wět}}Nq|24}9sSߦTn6~@sw?潄EB}Sy*wXWqTŧ5y`1H>7i ]^0Pq /sG@oi?c4ɧ\; zJu/a"Dx+gPwY*z> B-(w`D$]ԇZ2j@pY.uI)ת8 CC#¸y]iɢ%|f F .Kֺxպk]m/T  [+U}*Q=Нgg:"zy[TBm_/MUtfB\FJs~X6&wY2"œNȩ/oJ@3SjYPSY*TSէJ$ۥbA4?1# 6kV'U82 Q uyl[M15MVko^P/-D&ƥGNubnkz5f̆L%n%BXK6GԌ=,=`[;NAn]wSwMg.r J&i!6bIOɳ[ebUMf>mzx"яYJ]݀9#nPWKW*CXܰ6L-Kea]A\f,@6)wM%Q5N`lJA.=RC5Q%MİKej[X_ bdlX#`spԕ 9ۘ\- ~-1ks?J8@/>.bz09ܜc gf(bA?eS nI5smɬ`XM¨Ĭ]'Eظ(CgU8Zw5h|&] +DiPIJK7 C}ic8quSF>|`H sq0UjC/'Ja-4Vƨ\Ib"3 uC_W.d4^߼T>|dKo ǾWx%7ĝ?Z֟Is  ,b$JXbϨ^,XX7F4Қk@4pWw3ND7ңxWjn R48^1Q37BM^١>pl-S'K{Ǎs[,m8- >;@5u~g u`C-'x4\24|/]a{J/h |DH.mQGLYcE Ex\WGk# `!O,2XEg8F59ߵ/l8K10C;`l,ڢT,_b{j[&b".emC a@ppIgGJv%rl?9XEl lyƜȇXljù粘N:!h6* ̙{ ;?d[;sRMMb:C>ypʯ킭3t0LНa:"WqΎ}e\Wk.ɽ{W>׾ 3Xٝ8৐dӹ4u~"?r<'fR9aw!WIJY%mE(gxw9FYoA|y5eFB)xŧ*@R-b @+2v{fcN&DxfDZσ)Kl9qG|6Sqk\ icS[YL\Ds9 <2#ۘN*7v~y!=z8͊}DK8Uac"QT Q)nM952/uk̩5kt_mC=Dxr~umo?4޹dj/]f0#8u1`eec"?Z/8 7n(XNDnR : f\&nN 38q|5rZ c9Za{np$g&QRMK1gg(h'[o_۹\9/R6.왛Cd |$lq;F8AС}Q@ՙ7) brً-4D.@̸v|;O>C=5 e닝7_gg~7n8~lDS^\/D<|}L[\]t[d b`.Z7R7Gc玠HJ9)k{bg:!TRXi|l! LM<ji6q<ɈË5:Ś,7=G\0G?n"_nrV+Wߢx dP]2[Q.5q @3A )N9+ϋKg:ҳ'p HI.FNŌS*$$)iH94vͮߜ.vMA xq-Wm&LI}.{Qw jit>7 #H c[RPdQC%-vZ`m"VaVY-B%ŶSψ2zkutOSs4.]IDZ1M07KaV+R'CJ>3AH3xGúfŢ0bJJrsV~ؚ61SJQUT+G:G@Ecp\ܟ_ﵠ]gvn8xqԅ6$LVKƲ#;˦#t=4ƣC&Gz~KS>^E E""N*թRE2I|Ya4Xv\)g{;yȜsrرybH"YeLw]ܾۜӄ[絗?|:yѫW%aXɛ08 \Q,b"0PMD>C&*^fShuuVVJ(a*Cd)@ g[(u*#̹aԍp3N\li؇7 mD*D)PbXӎǰ80e5m͎I!4D.bo7$W*Tu`75RMA'}FX՛9RR5";J@\6Ƅe[Z9ZT"iLҞ`UUlY/FRl5f@~a7q%yB5!\On SgN>lz[hqNa?{ \?&*Y0{ݘ;c=tiNT g>KV'ʎ,Jfs EƳgXC{}l5-%1rX} _/g+>47cZ&q۽{/%AԿ!l84 6m]p.%ԜMza]v NQnOw1J-L:SݵO<|UUg}~GZ}5[6VѭtSrNÞbHP]ݳv֒7)Ugqƨ?9$s)̗ۢBh"P4^(*6/aQA)Sp`mz.ZPaddY,An3bg4p`L{_Y`iv -VmP]Lh@:҉N"!2R q"B[Lh0 b!A? F  ;yyym捭w\(ÙW,FC04^A%^ccf? |Y7!?_@=mKk)v*]ȄU]ԍܗF+;}~JOKYm)jj6wOST.ԪuWk[4W~r)};ݜnf{AXcLo eBP*ϡwn2( C1~r,ffPr{(~ė LrnQ+z9Sb0(ʹty̓,-Aj"#L& I X*F*Nb-Yτ o=K$;efg~MQƢuqcY ӥJ(!݊~JW z_PҩQp,:| xZj`cifOE"sZf'kIߦEYZhVn\żD WD`|w>g1} C Ji'v\͘gFL&լs*噣5 YVO6N3y y ҇f,(4jd1ă$VW:WљC 6Y{Omqlom*4Z%d.FM޶NO\Hw;T eMQ)b{QUT{uuN]Ϋ|[]M/7][}3⏡1cr=F+PFo,#=zOZ7˞Q7,tlKs% J&C*݁"U&դS>핎V,F㤯>$~n\?)|pl9_9+U2_6tbӤ1o <_z.iTW$:(vȋե}v!L5x1F*[xc1>ks|S'z)~]5 œoob?Ff~9`ФJ+'OrUy^_:]WknίX ˆ{A,)4zNqTbp6mq"NW<9S^QL۫Hɲӧd#]D'|Rg7[jY&[aV~#P#e^!>{MZJΠԆ/0r<X4@JHLRT{o^կF :`3eja>c5|ǾspR߷KKLZ]Z>k],pk ǜ`}ޚ!<{Q`o,d,dsoMO's}_S@9f4Xa2ͻ͎xiC3bNCPäOR"8 j ǡDC:vc [-J1EȔ]eoǟU-<ۈ+"k.˘z }˶h<`ѺV4_ڍex( #F6 b1$*MǪd@hg_\! },7gOuⷶI7]_pNܪ_EUtee~1O[?N?# TN]J2Rv3`3Axzuآo%U[ R|]+uy_Y p̄L Y 2r֛›5tom;.7B#tI% #^P͚5tLy8N(LaW0bFB[Дn'7{O@^p~-j(hBE& .*2s=M^?;{@sI2ظ@W$q'y۷}9CPD0?_; Sb@Q2J/5mKmp8l3!_)X5m4KmHP^`xqc6BZo#Ez7!oB"Y 8>:e@+Q(H!|ѡ:VetJp'|pH+:& ֻc 6^.牢 f[(^up{|\rf4B",]~vh\VuHX4WeVc ,O\T񥐈1ȱXȾvXg#kXw`Cc6L\Zz4 _M~XAq%+0O1J٩tQ]'>AuMF1$ǫqR#F#ЀNFɢ"cj:lF&>ָGWL? U ep p6ƌK5+z'1OjUkYP#piAO]dL׏\Ow 8sq0zkEC{JPYAZ$ VC06r^ @%2=P:Y9/܋^;V_g7a<2.-7`F2'܌L'}Ou1iNɳ&8M)GM!C39sְ-?T56[J Wc+8qiGR7E׋?|ϥrD;y3"2X$lXQG)D*e\p =մd'"Bhr0}rcc/ E..(sL|pN])T5y3蚹){-Vʍ6[.[HfkK1?#DōF5̀|1.n_e[$H"IFGK;!FPR009hn (ٌ&7$D%o]24Vv;w+Ch yu5,s23p±2@&gVl9wb`3W4`Ykw7jl_hz۩F(>+~D($<_ߜ߆!#"J 3@DV`{e/51BD"5%[E+@|5B'}Eqssss{,V]VC!uKVcS28>iO΁Uzy-.=G=8G\j@AXRL)٪<~*[VO8Ԭba%Q/h? ڞXھ9}Q}]7y4nKd6̿<2S)'SHL(ɄDҐƣer/b+/1Bzp5"5C&:ri [\)̹C^>?cڟYs< ^zE;<Ɯ~i1bKi<2B, p6Ҟ'ڸ]/l̴jKejzѸYճlA\FfxLj,8/W1Yܷk٭2CFHmo,Nq@\θ-XHFg=ҍtO]GW`s־|O+>"t.U Jbdؿ >1,QgZ Y{}l~ߑBwH뻲UᲮ^G*!_9tޥ#n#jivWw_-9,FNrYQ+HD3&t +Au2PWa}*O+gVt&A]y;*5+6eJ×Caz=7Tb.4X pϭ[ˠmnަ6Qe'gOVR!IO:+ggcD~bTҽ6 Н%@96SwXl{~4_--\&W1c2͎7& 9bgl~kzNKXK?==Mn6df5-sCt'Ox[Z{lY%!7f4COWD_c}D7"S]/ڥv[*HC> Rp Bb}qmmNK7,*HW9R._4ZV%tHx*o@ n5w{ x:|ZHX>Fͣ?)Vu&I,}١`xҢ}7ٮub`><ܴیE6G;ғ`OgJ-*X\l\L0ßpSȽV5Rk8-:큇1qSnz<oQc@WμPdco,v \^ev`9^梦yxq{mj`Gn-_0=7M~c o>'b|`T`k( 5L ܺq;Voaxv,k-sd3M7.-OmmP&ۿRO^_eQw(.UB skȱ\Lm[3m7uwo*UoqdLmz7QgE?o͸+PBw[]9i マtkdVħ=?I,-Onx $q-/>2mjgmֹKwwUMqڙN+uBYSB(cZ ,ٖ;F${M3έNnj7Fs̫%^yT? TFgyhYKoPI;D7F+I3>BTKvyz:Rvs^u3A%7V0;$@IN.)U,oŪPYJԁ6;jN"BFO@^x8˨̞SJ̫RseT0-V S+=S7nwnݻQ#CF5`ewz{zND'] 1!7u H`MB< +7 24rh֖ ~ rd׬T mb-I4VEpp>no3wyf̙l˙[Y7&arK*aA'?_5q sPXaXpI2Dul6Ll+5vO d'́h{JJU[i}g9]WGdyF!~d4;SJ"_xznT_l0^)e`[ҝ O6nFuHa5Xqh3}-ΰ-ܕhHe̗J4D;qGhSkg* ۩?؞>mRdHhܞwnUװO3ґ*/b!vKAsJoV+v"kHS){ƙ|`s#2f O(ġzIXV}5D#z'xG$/ `ȿohoa Y ;D[ɯd52+YL5:NǀoEn|$s%p_ah9TzF!|!0VwIr8|7q (6,IM;pqQ55jX;/7GX,T2b2 V_Hc !QŋC>8DjS _|51chz:wb:r%~@)"`aBWhbZAɑ< C)آIDƈ\L !BƝxUΆ;Pos PGEQfa Ô2#qV6?yac`b͙<̜Ĩ,70,"=Qs&i!{@ h0 n^GGm X FFrM^a+1Դriy*5bC [b94NvRY,At-pz]eB;<5fq;(n`]>%9EI^P|~(HEqcߵ.=RXt㈄PbϙD S.?HL(F1z 톈RQY iTh_I {&4w~*zS4ؠz  />| M=N~iVXȯhFz`L,{NGJO #rdm޳¿Ք|'6>ŅXx?rRZqhZO[R"TkXAC-R=fSk^.9lojes6)P8wqmw dd<>'!>Pz?Mk].7SJFZQ9ǡ6ù e`&a!bYnI?/ ǟ?ϼe͓/EB%(]BăPcCBmE -:F1@y#=ZGJ?aJǀ*Y3~2J_*MhB Jo)1z{ƠƊ60  Lyu86P1te2\G 7+XeH+/pAr-GYѿtorڍ`FEšqK1. Y&+*j- Պvl-0wVc٭]8i&5IhNjBeEh8aȐ{ AUxAƢ,;<@M,gBuZ gq1嬗2$9"@V80TlDbH @GonFw9\JhL'ͨza1ظD87C * 1ZdmY%0.Q [ t1< N۞pޠ]ڛywXI'dI l`g7(*`!@m¸CѲi8xYq=+ʒdZ|oWY77%˝ommUm5F/Mn3Sdt*-{pfl6E~b< C0%P@gMYʴw6}bPs񬴠Q |K5=RMpv%DЌR3urkRU:Lg-GqXSl\,zxt8.Ih e`-1Y!S΅j(kqQe$&8_rd&1S,4<0(<:<՜ܙnvWRQ(NJ@avVrGxϙz› $NOm PIϣdٺ”U.(G,qL@Č]ȡcJrʱS P(rd|[`q$P9qZr6bx.AtI"#ep$I<ᨵ˳(Z[ ]cJmp|?Wcܽ˲y3_=xnޮ9 ]}]d}õJT[CS\wwΪκ5r} q}jcj-K^;l"ֺѺΩTsݰǶ@.GxUj`!/i׍6o7L[YGxcx_2CL(IG_E"Z왇kj}χ^.߉fAh̚JAꇩ(>>!6YP0SF2k284tՅ2 s쿥Q a~t3@3wxShik3 g:",I @˥)H&>P|)wE18WuabaK'Y:. =7:c=]39Ȝ49m:AS3w6~ڸ^'hoy'~8ZVƂ5-V5cZu k\zG:W* B ܺB{Px=ZCj-ppڳ @pY&|ޱ/enU؁cGuڔWoGԜ>\PE`[Quk ԜsK}^ Ƨ*2^5;b!nȌ|{C0#ez"'22,^ 4bd?jN5(x/z69vIeLvUP0 Lt7UR2b9<FI&!ı./B!aؑE"ĝJ̛9i'?c2fϷpmz# >+vgo_;7grgnHhrzs?pMmcot fV\꾫^MK/l`x@W7#IJ@եW5sUp@x{Yi˕M߮mjVfu ګe7ޞhZ渋Iԅ5wM6Q7x&0r3 | ^m{JBhuu*2M+q.Y2eF`'Hm(4%1Dq4D 8np.T A29̚B2tErf +^C.ȟ0Djtx ;&R8?/;/ +b̂q|If"$.Cdbb(qX-P@mZ:&xQ{28/r˜ѳ͙qh+k**t3vmv_LӿŜ[кƍY鹛uNz֩z/Xo7Z5m\&UEC&r ShRVUZL]trm{}kZnﰵ p:$\K\}y6X7I~S6?l/h;~7MB(/eF<~*-ǻ,X嫥-56-~:70#Cly4/䦁JVfW%^S5DB=}YgT䞂֕N7⚶v AbC*,dќ 7!%DZaP&4גbs6,;L<0V/,zwGDκ.h$LG! (8AK/d3vle ԑZB(x:Sn紓8]LԜݴmc xoos>k}{xhöbWmk?)Lf$-:7x3_SUhK-W}!kuv:ӬjX;r Ǻ{\bDȼ7ӽW?i_=WUkVcpXmgMf'fDXXTv3 7y#wPeLXG'T + *n`Ks% DZp!P>DŽڍB5(CSgNi0_Yd&~ZPeʓ)zj7%q52ѣ&f.랯{3xEሹhq˜>1tt)O#2 qb(, F4H:n$XsxwV\BTY|+~uy+sɅS~^MwAr:`+KR+?0[4!nUjPf;6W3D^Vn=su9~y)WM Ke`N'\cUW 5}R1y2 hY\/QAd~(/mq /+<,Hp*;q$OQ>^@( 2aB9 әD,JJ^PM'"̦# Ik-,bZl>2{3x@ds N~aHcK1,%v AlZ5a9C&*ZXɫzHWoP==NJ;-ޡU7S|7}^]9O2suwiyނY@;ƃy7#7@xp4qOPb_qkycyASei恀`{/nu<ɩH9⒭ zKbQSUt^$yF&6aʢcR_<1Bp5\ CGSG/tGK 2ѕ/5\H8*2rde!d¬B屯$e3q:c,Qy^V8 ]SӲ剼ȱbRg1 #16Ku@8~p2Tމ:EG\BA/ى-k n2H2'h)t Ff A/7FlMϻP|U4D.[-mvpğVx @Z?(8?KCd!^BP9vcH5V @?y`pOv]8Uw,)Xld)u|8bCy?Gׄw0"3En`K$䛦 -A@t \Ɔaf Qq4&6i  E(/b.QUT{{*w!+0}{ۤ'nmqmYɖ̵-2׸Eak%tGV" ,"ᫍ/$ldiD H۹mefk4ʹ9c1bD$K $2  0@>Y4 4Y̙\E K$%V"R=8 REtjqU(I.I-+Y_tH( vNkvF3Ks{F mh*qFNQӴz(_Eb1E4)š2"L1A$abȖ2\<|<"T&䄎*GAL%JQ >C0;x(o LDy&RxqdRX1eD8Q14,> 6MB FW?Tt6򑵆"x ӆRʦbh0"Af欌՟QHRMJuOL@'Y ZٵFYөmT#{e!Ӎ#[lIf5@SO'Jas+2iI2*z"ȩBS UUezR2PȀ7`f,!$BA/J[ڔ>y҆Z(Ƌ\K{~Եr$ lHhZ(FCU >|Gd.#y:yOp>w瞌w4"HR(3DIOxʉX\Z r'2d3ři;79)ti&sm NI32=:^fc9r6 :xsŌ;G+ ʂtleD:$c-+]&2DoFȐwP-̗Htܑ!bLjOIhk@Jޞ g#cHr6kq[Sn^BۈushŌbR/2vDF(Sʬ>HDr.aSc(M&[Qp>ErbM\>[s' rq/S sF̀vT%^5D b; 5@ָ;;59r$@TLS,jx(vTLSQ,$c<.#Q/~(;Ϯ@GQ^2-^ Qxyۛ"DE+u^LcZ%aڻ-ɄۗUy~P4RʖR{wI6p:ZYS]q˖-hfNnl+s2F*&r4vFjJʳgk@ϴ&:,j vz8R܎9.!B-.04,}]eX_չ=OHy.M:;/=s_SEh_NxRvD%"1ŅʎO+e12#|4^,qϟ*xϷDLy8pG/I 4X/++e}\Cc]/;Ω^4#qZvU3Mbxrm çk!UA3DHF$K_T"tրޘDDSXFa`}ZKSFLH[)#u[1=qŽ{b%;KQ.?"K{[sN)eYI˙]A-HAEcĮdU0h?kg{)q8?rqdͮ씃-J'%Bn8~E\F:@Qe1Ⱥ #OLMzΎ¦|,dZ \7t) vV l8 LAl Ѕb85tq&Qj NGѷ؂Lǭ[q%bӁ]m=ܱCuk&g)~?AEGJy^ǧ%P:4-,Aŧ 1!-`@ G!(Ĵ*Bڳ#x٩`Qgd ۾ nvr>1"yظǧ͸6 c.ePei4h/Mࢋ>Sįc~z:eqcC@p6)s.?rz FRy|vEPR6h4urcq?ĺ7w@M?,~p;x^܃OaxXyZAq9ïA Qg9; ~|cFGQߗn+9f`(XmP55 E*e1NbK,D㧿4^=&]3WDKͯ ߝt Gc{̱$Ui~釻{Fkv_Al5Qƍm0oRc6, ]C7@iOdl Fsuk0eٖBS?-LuLt˼d,b2=Ukh޿55AQy3XJ>f/td[~ awIeyO|`q~\5enHiWk6Cn+]7\%ZN}qi-?'o| 9de,䷟Vҿo޳xwYy7|~׎x)>޸q-n8mz.,+O ӹ9mcd0X F0fǮN xou ֵ^M`xҮ{R ^yH9r}8nۂ۟m)rh_1\>jo>7ox]r&H,H,ެKIϐ}I٠7THMލM*Qx Ѩ |d106ʉF gCo ["H9rP9L}'";T}q~0l+0l`` l@S# ## bG"AXy-+x` 6xm>L:V/s"{b0VɉV|+_H,>)ŠE) ƻ\8_IDT#5A9@@ 2da 2%B`6{a 8p\b&),*4Ӵ<*!bVEF}Dr{ޑY%,pXV9kħ#<IK=oY̜ጪ\lM%Q.q.5pί}=Ð,:7!v YxL 9_>B=Wֶ(Wy;]cl>J'aH%˜,Ī7@U+x@ ;sx/`X K* Wj.SG,UB޼ auV8 8<+1ȴ ;F^wҰkpar[ mz0oA/2 %$^%!<|/]8,OA%!_˥:>/-c*V:(iloT36/+nOy-OOz_O3ޔlx/>ҡrvN^0sū^sr>_)((1)=\Zqo| NT, O?|2Q-Uea[IYF/,7$ :e"3#8~/doOKbGp])_xMTW6J-ksI8I?e< Z05XF;+˘=QƒSl5/hˢIvHcSꑊ6~Npb+_v,v Cx eT@`Kb#"%%$I&a]rc..0I_kEuu*I+%:&WA,x'w#ᅺ-.6* ёj1hOGUmH1EqcY>rޡ5s*02Y_~-'`*dCic&*+60J@9R0R\RY,F1tļRSh5jDP;#זaP -SG8.8R>#5ޗ/mW9|;hbӉTbUA<;$FmbM:q,="E[iy f_5,OnF$(qlx5 5&91$&T*DDDmJhKޗ:қcaȹuI. ۑv]["6rhĥ,R[V6yH$Ki%sZ\EWe+7QmҮ88Oue-b*Cڲ01Mcf5sRXיB ѯ8uszdΠakiϟk6ԋReI4#Sg},w䚌Wn\ `E&$#?pV]`FvCTꑤ*[y9/ΔpRh0rZƬ+B7w#X(IoiFYIeۤ0†h"K:LRvK֞OrU$~d$^aZm͔ U瞯v/!~uRy]IHJ赘,l:J=my>Ijevm͔ހcZ(:z+uWLR=\Œc,MS棝FĜej^VTeZ3Z ;mgIכay;6$c_'{|ժ}Mb;z:0Um\QKhUNX]:ēA!;OI7 h֢aB+)kqmE\F%Rj*[cml[Жoc_$lo-k#tgS5k.vr%Sv#%ې#o5 D#+q6+p|0rU5a}c=:ibm5լ{\5;WL!Z\xF6d[_P.DR-v]AKG- WxV*%n%"bȒ)څT~PIRND֒*6ļXJ- $u5Og'M@k,2amȪ,lKonF SN0k>ek|iVeA[>6|cpԶ;̖6_qTYRV5b2-T G3AjDVe[u`sk n5&1p{{6؇͛wݱyۻc̽fӤXUVF]c+_8/v _6}JdA9t hK^ t\(+8U,*Ģ ML YoBN$fY6MOPYjrE9ʠq44we'_||lFR&5,S' JW8';QN*gBN-`'/;NQ9;-A7vF^B5(i0H.7sUt(6Q 'n\OEՂ t&7U.ksjkr`;M\Z؝NP;ױԱ:(t&M?Be%7( C9 MQ F*3ʋhAtT3;L\Ò*7tRfdiӵ!HnD^2KG[Rta! Ƴm!b92cN.& wٻ^|^)CBOV/_ !@mMv :e77[1c>n1Zik%ŹZ0teuy(8^!rIۖ\sֈYJ`\ǧ؍{[;h$u[tb&^tnpxa|2_`xfEUJOQ^_{vv16dGnRaڏ7~L$?40/d-$D,dMXX-s0 KWKƄM܇8ے2,.[3`urō;&eE6_2_`!@mD }-rcd(ϾenvԱYZRDh"Y,e`ԴTm{L lB"#G{WttfʁdzMQ{A*Ib?}-l H?9{5H<n727Ojoy:XDI}ȴ:ԨYD4KUN@{I lWտPT{՝JCQuUɪWGM((aNVɬ5W)fٿqCtCT AlfsÕXdTuϬU ?̬+""ݨ 2dꦼZF6,dS=)T izInR>KIW$Wh 3uw9cZ 9#ViZSls92zh26fM5":jg 1غ8;LRa< nB5"FmAq!0+H6UVZuM$HU[4UVb[ՌR3VDp@?v*vQD*I$)HRE87{kd+&B/qR'@0}26z3$pQFtnk\nqih<4ވ.TgGI {ߎm f.Ƈzvm`.WW`֔ZӲ VeEfq'!\ZzE{X:uqp訢AAS!g@Qʉo3r=o͙,3虮@U^Uw]& ~.Mݶ>N&R66e(O}  ρz.U f,mVnSdoJX8*)ʥ~7D.}c|=ʡ4im`5? [GQD /jwzR?}^`~G38v9wؓL{D>d۔. 0l{ەٲX#0%z6}Ϡ:s[ջdZяfJx6RW& Fs3l6YF4!lv7cEXrc/YI"+rE9ٸfvu.0{2I?]j,˹?]ZP[హf9W{'17fW UĪteP^z0 2^^CĹbnڿrwu4Bͺ+yr/LxeJ,ʨYN5b*J,.R.|?4'$dc>4LN\# hMC]?G"ZZOUY#>[x#tfg}( `߫<jHj D/]g>*>F+wQJrVg}buu7҂abL}fg ̕n܀ ΛHr 55R\$HWe^zJa"X U?{uvYNagZZZZe;,ũ*^VK[+5P#gEN6v֥aS˒-hk6]s kl/?FJñ{4skr5ӻLVhi6P_o kū+YYYlk{A^&=*Vf S~} 2.Ci9dTzi6+HXtRS `i;I[5UFkżY)Q/L6i= nE7!m#^;U]u{_vLcNW.QʽR:E0[a\c}0 ߼3UDphm9l0r/Y4P0Ud,.eƒP]@X #*R x3g5o֓_LKt{ CK!]$Nl*X/!s89pO)5^y)&3>Il)K6Vd\LkieAZcM!Jy7!: wo%3a >-m+$LչNO}T X-Lo)1=D " ędF5Q%yT& vA%Tr a/>(r}.Q'V,gW;if<¹9MY 삸)Kw.,}؈"^Z e~+vY2~ ovzl1BIq` (wݵ#x??Qju.la`{ ޼؋ lbloH-3x` -7% rGDIIiVNmz2tPeay_.cYĮ>PvADd ֔z D\5Nszdt pGd/7dQ."9]$:~MV:|V-CClL*KnIkxUcC1ۙ,>e:o?Y.\\<֯-e|Ve׻))矖mX82 7j4E0=qyIV~ {/;ݽ03{i|7Z:hYKYc5OY˛sH}jON%ڐS=bCNm?|d䖺hkr.[?yQ/t<|{m )Kakc˨P})%#rYw'jNiA+~{Hn7[2']\#Wk\Qz6lZqQr|`v |0ن=ͧdt\=S/}”t5+yA@0N&S6$LEF4ө2e'{P$|t:)9Cz~R a@AhgΛiz6XNK J5Q-ET8QAY\ߙ}.f[+y_0~+zsY=b݈?-200C6֥| `Px>h/s '-zw> F~\e* ' l}_Zzʤ+_-[9vmd,?{wBs#E;M%w I72?o QcISH,N)QYP(GmcO YoEQ|ω;UvrYCr* -O°`mnvwKbۛ"o8jݼpԝ wX.r-2ш5 H0 I{N=Dw/_MISptyʓVkz/*CDwBlu@R$p]C)[ = 2tyW~>mUrk4a=+|H!{?!3_ T܊j{ 1E-zWJe@qM5^Xb1N9ԋ8Ok]}oKYCHŦH7%S{e}+4z5vk3bcN]d=JeM۾8A'IE7z$m-YWfZj{MQxe5D8ȴ dCHhx= Oi2? u͡,due4Z[{}` %&&Vk)ZceW&:Y׷InFxlB0H2{ہVӑX  Tq+ 'l k l}2"#Ә6Oj@.iAv$_-;Ї_Vykk;E5~qg<S Vl1"jlȈDR&4AZMp-!J{ 35!+񕹟^_ϓpp$ vB腡5XAO*b[q҂̹`krlfz/lj m;\% 7G %ETp`ӯ|o)/Vu&'k㥋ghj:s[[l:^AakT{08عNgdy4)UOW} pbWf뮥WD1nfT $_v3dRJ[lm ;l# qѕM)`yWbǽ{!^&~O3Xt܌AABp`L֗9(()|5q߿}תZ^`X1an/=SIAv$_sH^% ؂srO>R'_G./0NA[A. 珌d@W0u5KOc.E_ 3\*  EEcv#$Lꁣ1}ZTX l n'w2Oj~ZZ嶤 PA I\"]7tHHATe. Wt"33`Ep7?\SdNb #%1a .j!=Ko1 Zb ha!1zPm !p ACKmA@S mgp5 z:Tn g*; #ѥPvike]zw??760kUޯR͊?գRk /i݌Uw-G`p-/fUti-kezLf9z)F`0.v>7P-(fv[ P7Rir/P 0)`TQǿ@L⡷mY؟LT*[8vnD\Լ] >hLoRpq5>[oK/{*s ᑼt*Sy]Өk3_`qPS)DCZ%+JыS$bBl0bHt4BEp#$?{|kl9JuZ/`/ HNDBNF*Q ,[cuR;uv#0=kw$_xb0 =i @m#0A 8&$?89l $t,:M`$=˜#ɵeb\VS5pe'`MmPbp1IEt (?w6ک³)|Dp~MdBAl$2q9$%7KLvw8TwglȥbE)h ?zbw^ kշJVynQW=-pXӮdyw}ʬiAk$9% .,A7n7Lw8Ùi2&KVvp,X^j LҬ_P,E0M:q ^(f }A&^RՅ8P^߄eУAI(0daɭ4~>}<) 8Ixަt')f2s\avx> |Z "X\(.Qq!jcy25]Q}f]\Ϡ3v\I屡!=4D)P/*ީSzfp>feě~vz_`y׼nqLWZlK<zv-3"Kabr(b&v8msk)$ Q'(bEOSG#b}:*ܙϯ{^*T_L<}lDh9z?ܮHߣ`L5"iωSo-Bhg%6i66'..Îf@j2A)K|4ZY%q@b$c4lJfr~zӜb4l&eJvCs_ɚ.Nb [x'l/VXhSרܛsa.( `|!L2pًp:z'F<`3"xnVa3dq5ؿǼ-ß=b'"_pX0 Ggh-kf  G]ű7#-SRf*zp'Jk^F S ٕsuW9i_Kj:U}]?eXۄ,"94?Y#rF;YӋ'CHkHӬ!bY3V׈o1G<` x(~Nq“@Azڗ͡AB.fCMA6 IgHzFφ)~Omw*l 9J5MGCqnNV=?zƶұ/L&iӉ*AHe?0xM}OK6w4'` (uHBo@; 1aܖp؋N^I-/DܛO##Dbr'dX8ٿle8Q*re)_cY_)v~H?S t^0BҢ0!ٱh-P n0wDkbm')*fvS"̣ d9vX  *#ר>R "XK`bfu57W]{ l;tni*pblRdMtt0y* %=jh0ȉ?dOGv_M ;'ƴID&4K6wUl7Qf3_k|H] iQB?S!Yh^ӌ6)rŵ qgDO~|0mKpqFlg.-T-WZcC;QWMKU٢|;oP-iNAG f1_`|AI5O"~۞N}Q$țgLSM/XM0l>KvpR08 &4sMBTt{_q,Q;h`tt|j\J'uN%gr`Oe VHxb0>-HU}OMHJA`dY1yZԙ/~V_FE7|RV?CQ|LCҸ'ڣϺ],% b~&lOغʈj\0$F\aV;0 ɻ- kB3xUrUvI/?f0'9MNȼ3m!Ce3T5)I~ed$ݲƈ3)p:de)ؤ})9> &#E@ cSuOˬW`pB7~kWF`^O9L) n8t&1_fg~۟Dz 3e ̸mPӵ>}U}mz 43W?~/fhwhwFT[.Q׶N_Nz><+0(E)~2!Fh&$:>q!|x@]~|n}6s.[FRDVgJKBX!$H1Z\\\'/ic򬖓SNee/W{Mqdt2|@B-/}1,lEOT !A4} }GÅq% SC i VbvP>I51~>e>ϔ j mYsξ/>7kOU[+V2ˆۋszw0p0nO7-g1ռJM*ycXj *ϊV.y$!}}U.\>&R&+&AAyľ.v;޸M)owx̿pu[AcFlpZv1Q@.KL/Ia\kL}xA-#!;7JԿDӥ%5ظ9h }Y ֝kZlZ†E-y)vCٿl9Uлs.8),-9lQY\׺+FV)DŽޖ=`~s _OpWԒw_lj/-冡+wyO7P Qρ1a#2ޭzw֥-cHKC|]zk{@4Pg4O=,C1y>~Ƕڊeۛ7|`|n0(r"'U9?rD?2Iq'#kڞ*|M(W'ׯy_3,=̕^Ȝ9ݾ [VDySZ^ϖ*{g‘.~vNO ґT,=/hD4>+RA>&.ǖ0ɤ@?&ZFe=3CZJ_ns+{' XyQ5EQGh l-6&x ]dmjW6=(]L8Ѽ[D SWɍ"QջtFǛs0 4}wd6i0LU߇u~f\B󐴯z^MdYH\&a'uPp죞;~ 0r[omK DԖ^zjwNZW5`>~%ژfq3-rA,6|^ qnz}NrW\D7t8>'ܶ2e#V9ڲ Uz# %OrO9}[p9=\o}z~ňhP<%L$#8] };N0s!l)u<3=@@.§ؖcu}U>M(O.GV'(O[s_D6Rh)UL'IXn9g4ܡ5M S006F&&$VzizY{X A@~|&V `녈DԱې[fm(Ͱ]|\mI^:_ 6MyϨҼVђh8 zÑEi]VVۆzͱdžaZoOL \+䷻fK!_gtuqQ:G& Ug浹>QixK{!Zv|sȞn>v \ I\ =^Qb&օﳘU/`FNa'u G/sSbWؽ.#jt_d8$duMoe{^3Kt-o{nE/X>Jv:r$g2v<YksA YA¨z=A 49ٮ(#83Hs5Z,UXe2ݴ4 CY-ҬUʟٮ M&˭_G(;3pz5}t⛒-f!:FAdU2*?"?}/=ÃpL1$`_fCO͂3P:I(طR,&Ρ{sJSgunu͖}k:mȝYúh"vw[gaNZO%c7հ\ͮGW2#kC5SOt#C ߇1b5l<ץ0Mf#sGwʘSU-\q{,l)ҊQlbWNU[VJ سR%mQْ[yfuu93Kd/0DH< lđ5r o@wTD秘_Q1ܹLtn45gMSէ8\'g}#Y;wL9ݵ=ʆWY`}ـx˙ b{^LֺUòV|ƗϦWafتXdFz,gQH#]zpĶ^1:,SAl{K:USbVѼqRb-5W:_~vH|y1DgTEBƿ1w1hyZO(cw麙p,B}@_s\LXzօΚP5^V-,}9*e#wb! kA`L%6xw31K}Vuܰߚ~_[mW/Xdž3飒WFտvgl]4LT><`bz`a>#XFe п6{`o:״,,YuOUY_(Jƿ'UhZi,c$§,D[0lF }Nxw@C\C? 6Ζ\Zi<'78=:e23SWƢ Dy4#w'_ ӿڡFZM̊S"_Nأk8q>0Hyi{ <>p&fZ8_0r-!Xڄ{q'Ȉi(>bXq .|(Xe:;[MR^?a‡Yr@|I Zm=|$F~Q#3a`ev˖vq/֘aVh(ֵ'?GB@~#0%o~wX2`za{0GPw񨎍},3caԆk{t {ό, ۂ)PٯXqT hډ;? hv!pb2i\XÀF\@E E<Zr`hשм ~7#w$EB]C0_-C;T'0@G˜lX2j(J2wKcVkk Xbz5@B#ٔZL}&/y)M#O05O@3jx8J>AJ;7 B ŋ`mGR1-PmHZ V!'|"Qqa`CM`/#'h H}lAݖǒ]SyJ.A%$=[,5MPYI<FPw]8ʚT4MzJվI))\Rh =>)@?*;\INR"DƱш_j(dm_F v|1-%*,C 2+Du?JNR$))JX!ʎ Nx5z7[m%ϟb*yXhA+I f-NyTFKH".HIhњHxGbxY"eGMlKt0~&T# ˺Q7gӧGTTJ-B?oiyBs??`s4.y>ؠN:3KIjئ#OӦ2>t>4emBvl2 "<l n2$3Wo@޼Uq$<M1qٱ)V][ۺZ ieٖ횮/w1#(/ne[e ܠS @r&b2G..IHO>:B@` @/Ae3pPWݷnN/$}*Xʢ)JS'T,'y" V[n7paj[c{YG"W@LZy6Lb)Bb]B &DYScFo[ ?=}T>z.W^s#`Au=#a>ڔ|vFmⴔxHpS)ĉ+?wn}K (>~s͑~Mb{?(-WB~_ܹSf.IV׭5~a?|87U85aDfA,p%@HR1`^6(G8]$ָ[]~|Q'g9Y*)KbL` If:tBm7WO+c U|ɜ<>U-]NI[m_)ynx SWJfG~Ώ 2 ݲb7(q{gw%ɔ*Bu`CԬ'H>Te(&}э0eCFÌ#\jYQkTчHR;f WJ7=|wL+g0mO=fvLtMyxoͅ\m*#5/k1#g ,!_IRŴ0[vzęo6{T%Lm-[z; /q_+z"϶`p0 ee]L}qɳ`Ȥx/Tל"ӡm|lw|~YU~uo$S@``rp6kS{]{#=%5W@k*tL+Ƞ`;/% WazŔ}qOLģhoow0]Vցd$40DHJTv}IT(10{>aDnHk1᫵ *!rYk_z$馊@E3|-}A4e$ JkJDĚCq8ZUݦZifƼA[UߌϭrB䟉b?#~I[p+Jf9Z>';U6k ڟw'I~ :LtfQwB_dz3l@&. ekg3y/!"E9-5w[5Y:]lB`Du}`u_s II2G(G#A1ur)ƃdI =~StVg|de|B(vIY='ɥpsֱ?UI UUulyGj͇zG+R!X1 pTy eDKQG,FњMJqڝC=j<IRw' a,Cn66nu޶mDtIo>t.՚MZdyFx~j-ê.-RI2݀LVܗ-m @'#OշivuGk7ٻժ?ngRxgܡUxTYՊNy2Lɗy9t7"B5l@;88UE)LJ ˢ7EEiQ?ET YVgekZZkomo~S0RD32`Ew$|$N+˺,GI ֈ8-Ͳ`aH 3 Ǚy۠x71f-a}{Ķ,PN*#IA`lf+*(gmn6} I`ȧE$"- (@ 0O B>q7A_Y"yvuk)8;ύsFK`J^"\z""T;R#0NKRE*H#|J G)"*HE"wžz_IY"TR8QVk"T*RGwtk=oo$b*i3C*8p(NLܘqC<έH-ﯨQ9x3rjdϳi%41^H [e(~.t580 QKcb8R>}b !a &CT E)"lđA8[⽁#}_I/?bݴol%AvDb.W:wS;ז~p-nYF_#ke~Xp),8< -bҘt%"3넴 )[~n}bmlg} xq]>_0Pb/JKz:~>ƴo#YNs%O@vpࢹ߶=NmHAd_gf&zWe;lz+9ҭFf-rK|ս/*Op0NW/`ݽ I*ra+ӏD>؋;\2!2< ݋7kӄRX#0<)L3 2b0y:XK`^Sˮ&7?w=OQ oJPAr=@Cƭ'R-& J'#j(dQp z}2dbV,~Y7(fޥ5 Fb}-22_`Q=hɑxDZPTJ>Y̆w%]1"\9xZlp L,4BP579T;aJjg2'hި[cX- FKXEDvY [B1t<\YƂ컉&ߜdC(o# p1- 8a̯&V=qd]>~գq1W;K¼FXoSы_ BdyrRkr#r]$Lh%T߯`a)ї!C?1%2'(sZ=v#S.2f"L؃E5 %&SAS{}T$KnX58D+%SX;L=Y11Z9_+ )Ib0 02_!O==FίTaV3Xy\V0ѾB.7)!/xF?%szڃ%Kt4˘{Rd!tp;,(hs73œhr%%C\i5ZU6Ja\rg,aDl@L $MK+%xbrtd\OKyW(\6y.aO+Ee&ۿ0U"0+y=한DFj(;)5gIX:/+y#|w_f c*z#+%:መLe$a{##"̲tNe2f21{D(>C %h}kى ]951rD{ j˹\17g4sA.;?YziZ_#`UBl/V#żƉ)!!Q yXչ`$j{ŋcW _W񋺚:͛`(Ԙ.SJ#XĹQB2- Y/QPZA_DS>_lKi1e7R8gf&KpSX _=D竰䔒s鉶\p U2H8%(rV:l Yh7t,B,ycZ,je.~E2ҡ1*|#u8,bR[NAROەfCSUpt&_n$& _c+av*_ݻm׿`04`/'d?la|,HW?Lk۵r{-|O(96dbY{ ̽KdV컼_%L>KVZ@&|xX4 UAόտ07V3-;=v#-/2O/d](8Sg_ZJ֪ŨB&J~(1rLF~6ٵ,U'džsmD=~M`jQj盤jGր2wL0Vъ UAI ̜Qdp/aFvRP {XzfԟT;~M!^郦jacQ5s z ]Y^Hc^_ܿ@;p}ؽ֩tT jgGQԑH!Z} c/+5[\EPz:Νk9{t kχ~=}? JTsizbh P3O-:,}ZdGgЌ;U 'g %|Ege_uHdpvѢI5edҎPA2]B'[?UК7MW"Vå8W->ֶaysZ%5'+qGT%*|SL W:BP*R:2V}a\\ث҉x%j~IUOs&$=ɐPmdv_ %-Y2bNI&2fp*/e2N.FKKZU!1^!/d63ȉbp0s~ Kl ׆S?_Ǘ`zHIy٢vvQ]Aȥ -|qkcFMsjs`f(klIF=O[rvAnd kum=@纣>iO랷e{ݚ] w]u.9]kw^j$/؀ ΠQ:lKIo[}vpZz00,<on(_yS=y3o{ u>) D&FlO6T"5{7kiZwh[B<) qS~GtD0==Ԁ:?as !&QLG@Xf^^14bEQb\ƬT=̎RûjxxHnseΗ 9?ņБg@Glޱc_g͏=C1bg_b.E+q[^wWɲBB`=^˺֕ )oؖ+\-V ECzWܻ`lM:fbƻ-_ `Mlsm\ޛx 5mHlm5ЍȶO~7}cn@hA!jbn[MT5"3U((Tw50s_/XWs|R~7l.D5#&E[ |W%mQ6aN4RX[\,'dJWXl<ǒwh4W)e{bqjs^gW1LFjS 7._wƎ s'JnD1ɴ|P`H+'Ea"%"_F%]Yz3(/#w#,!)~҃Ĺd$GCD4YF,c(`a2\3ug'иrkxkvnTtY΄"P^7jײgm }{repծ办 -PbX5U`As5VUյ`N"uz9 7J j~.͎x[kT8MVzo?浃:&.FGAB I7m۽W&vE.Ɩx6kYL"7&NOK@//<Ͳ,; nX($QZlʬ\%8xJ9#M98^Kd NoGlڹgg׌9z8_`كiw-64;* Z|"G3mu=Y9l0TF#ݔ A,T6)l3m2JQ,9MϮ`c Yհq]Vܟ}j)Og\7;1x{qߣBw cq<ax.v݇ 0w8U=dS޽ YM%^Fu㣹;H{MA#^mMTۥmjQMN;ze"{,Q쇮#D]JRa-цK <ۙymT=087yh{ҷXr$,=5JdX+l1w# {6#B\Qd=YY-KRy~ژ=xJA,-.X<Ӯ •XZFn6ımp0?w;6/:ָܸљx9|=x߲مyˏ}\eAU4S=qٴ`ւ6T]:4=uz ֓Uo'FMɣV):-Y]6䫿R0j}qݭ:nEFwskJx.*w?$\ nJ&5lUl(vZvPJdjF=~dUt0%,(MW*b+5 ÃO1 Cl!"Ty_@glfd3pͤ*,c5 ` BǞqi$ =%Qʿ Jc͆YXYs3dӎA'aVDʯ!"]`]VmnՍı1_COʲs. kלlUqtn;o|]Ӝ,E4?kѨk4vU p{G*:)tZ@gJﲮ ghٱZB#ShMpn?сLZoUhȎ:;h gt<`Aeb r +ABXmB_՜ ^ieRaD0C*m~9pYވd2v ɘ0$zgޣϣ`{µ 3  !EKsBs gϲ0s@7h&!ġ!].5/0ߋn!:W sVP*TfXhʃ-q%[NaZaxZ{ͮZ5ASD #[Ro<>dsl7Pya1\[7 𤳠:h%Ajkvܣ3!@84#DcN䦞7%mTmX(b]zٔF=cڧ򐣣 Q~ÓY%[亅k}5ZgQd($El_-9KU| !9mKj;nm^50 ΡȉQxE Lbr`S0ieF axSf=C@hrBPsa:l$UD<-I6 {kK?r!{Q=7g &ˈ.Lw#S%U0?h>Ec26M?/ӧ'əvSn>^M:=CyT3*XBbRV:1 i}س#@\g\]ֵ5ee(oHh BL{rs}uHAdАB6ԵFqg CTlN;W#G߼|YW&PB=#=E{`z^H+XP!ej2҈,fBR'CLsx LD4B2vP d燓e8-M4?(=^eiFC C[i(;n#,זəey=poɅ/ad\7h-<=udshEz}^h!5v\r(LJUA;_8݀~!GwxŽ_^W3>\O3$U J;Wp'<E^Ѥ[ iL`1R6x͝1sH@0*S+y`.qq =}!z!Ϳl,EJe2J͑ _WFUsoxIT#̆ΰoZ fdrY|Q1Ҍ}s+m<0r90Jfň2Kg hEae~*<˜<Ia+\o5es, Y(ɼ)uxlQ6zu,tO(CaH 3's0(<qU>_ى‡ ՟[üVo gokom1#/ 鉉RKzDX}}bЀ=7G //# 1WBHz'\,%C&S)L!do9 0@ͅԈCWn[IoB< C^E@24 V?r<ȑWP׾H-vW!e3͒mV`Yte Ze5y X'Q`ѾHx#Jƒ^DOma)̥ ,pS]Dz0+ʮu&wސׁ=*~ 3&QBC =x֌ZvwĿ01$yO'JAPFM|oڞ WԭXYrH^5_e y/g£2@H `X9f$bWjv[d^CJB#C5EK ". Z;_נ*C)H:Enb^6q0qus'(l_c@} I=~0gL2(XHL,GWؾ V?`Pp~hQaE9mt(\s|6eTxe3T(Z4%)T&g-ӯ\C ~촅D;hfA'I^,ZѵJ01+<œ$3"h-jhhasj,.j1*6 P1AL9+/aTy %ij\zi4lHf f.RF=Y퇕^ F!/LĦh'w6EaA p@ lL"8b#u  QH .?7%ڠe,fCL'j7߷'xa/exٟZ$s!򞭒.WmWPh0`8ILPLى9%'1098O1d#G2o9,ob2 daBظ8gظƺ_49ܐ/3__b%]\K ύvLY4vHYaayV8쉞06`-1opF˴F3TXbWp P RsF %V7eG>6_cAqF@ 62&(`pF6YJ<]l&"`)PNZ8u] S\RfL78q|bQH"[] ˘Wl} L&1YG4I.t(db» xMUE I3Au0*)@.? ZwF B/)r&1e3: 1xHz 01e4q}b˛CsWo#ƺ-34O^={.rpkKN~bš>h͇f)2*RHE#zk_}{o7ۅ5r&e939jlԿ[~؊;)h =/H "Tc1"5l hp?WFGq x:~yՒw=ɝ>E_BN4ԫ*jXt/Q胿<'dƙcv;N5jM_G 2\=ff!(΋yfz69҆|1MSEw_Z\db$ű9hhO2TTSZFkH``'j,AUI=9q5kvoA ,|Agf<*CA;./&^3㋘"RbA<-;X-: eijP mB4"`W{"Di㏀"|^" TYjݯ}sv"q{k|fp.XPTbxAִAj IBpz- D$"D^N$Ng@Xwξ[}SÜGIZE ۬fq0^eG/D5|_/'x{xQףFպbؚ}s6Up$Ah>\gF ~6k yfl~эnP'Kw:\ꄩ{O9ZF-Ь|;y?E / _ΞdnnSt͍"H-U{K|8~.#t^ǝ2G h|_Kvyۗݓի{j~c'F_zZަN^۲8JڼNԢD*Qj^KQEWY+h)+QQyܥ~؝Ze$%5m>Sz9X13}//T6ܚhIJC`~'uWxi軬 [,gkK466hG,Aԟ+958MW_3~:ΠdVw̮cu;5mfm8_=;lSJ']NPa+m@m9(͠~ĚE|J{nFf)7CM66˞W@SmYnX&*UwlXQ&{LS^~mK `7?L7Jyd`zlpakM0ᯙb>漸Z@.i+]y>\U H 񭡿o3uM mB4"`V]P| 0fP$xW#cg((.Qdhf ]Z)E4pg_vK´}x+؞,R$(7M,*X /o) p?DH]x@X>ѳ$R"XSf4k$CRÔ P78y-^#ܸN{iqw7췶c/P˕3 9cj^vp8E-VFgY m层l-!S(l/_]K}[7BO:9~ ;fMrw$Kϫ8H/N|ZQP 9|yV[A5¿][w+68=m0u5ړtې@/XP.]u]?-T]I&GY>\ٸx7ؘNn){gkR 7& r >jAzml*.-'.uEL_مIMx)yw&z*?u-[Xu-%ڮL'7dj0(.#rmϕy{uPQ@@7w-XS7e ƖtI#/X12& !mpװ,6Uq_7|)L _u,Rі.z/-cMRyy|" @ jZjYSlkJ`ObTW,>1 ``)O/ 5*z}}vZFj"$1ȨyMxfn16E؁mc23f*; lX_oq,hnrr[Bǿma}Z*?[[qWP3hw:U ԐV@#@PT@?%wR8ϩ{y8>p5tI<#b9*SYGߠǪ;*39΃SH`0$$,}HL*3R+z~hrc)J)ҪSR^"IuFᑩˬ?s=^Gdx)m- IR&y$3]cE #T7K6/$)҅*uLͅd{yj8&^-)Nduz >R#5Uk5{E:Ť F[(rCrFRv ,$"%Sd^&$])'^^H:ϐ<@v޻c=zXu!IHՐfYyyկgNϺ? Lۍ#ꡞ+!HD#Qg{^R09=lmZQѕyaV+4b%t|%xLbۍ*JUc=kKoEʾ۷GË$9/ƈaĬ׭#~ESÎ7IP~[_{S;MLTĨmR]ߜޛP"[]FwN3Tg.֚Z`o}v]&{ZMC?K)PVqINKvj+' 6&iu1t=' h?w2/u47TN;h^6]^@o0ISeO>:G+#Kze_ Pk򮽿uZ_Z- &1F\@/8VusH')Oۯ  ?Z_zu~ ל0kUp͋|ih+0huz5\(a -=u-QuR ɎG[;dZj8cV>p,F&`"s/y3Z@Kԫ-#H3A)ar* ZMRX6kIk\fJL*9<7X&4j-2蓲(YADqd@iJ٢lUNZFR+WRS:?ZyF)/6^\{inJ胦A.TScEdj[7DOqQ9[jt˸㚺5 p3c,<걮:6=w0/cr#Su~*N{SN`M.qrE5Mj>DJ<;̃Q"lGS⊑JS[WNf|SN`\#.t5v<|mivzhp rm')'0 0J޻)5֣;К= .lȉ̸S b+)tǾd,}uRzYӣꯂ|+8^jrӴMb\KjDZ,фa4~ET_7ɔ .]ιZ9hפW#/wU1MSmEKI\oʓ1 o"?ZZ/6ANZG<>F)KVrd q24CPFm"N ~31@h+;A :f de̲m{vwRC3gPx’}u@6"3H[rwUր!>WyS HPC x@{Փ f[\\pADh[Y'@σ,LM^"#8l$'LH )83>7? ? A0.8o1{!oP`p/JI;Y.f_E{ܛ-/jpPM-g}7t{Pu 8\&YͲwi٨V$P"M nԳu]39.vm= 2׆i|*UH,]{D8F*{Wz~hЬfӺ%[j0wo!tHGoV,%L(Xzp6=˴֢tb\g+I@aIx9)rҮ_nۊҬ~l}Y7D3Mܫ$}:&j+)$MXĽ ;DU߿N%)=ADFgK={M}Eoc7ND9.;ͫrr?_'%\X{<1ܧÓuMji2:Vm(H8 琗mWh9P3'kneY ۆODAljgA$6zygڔ6WjU$y–eюq"ALuI r=ƾ&r6]E~IQ:={|)|&Zb^䞒n:;Z FqyL73$h@6,}-'VQݗ~uFg~džcsFUa>6`k/b/k.uU2LEbŦw^,#=)L Xh;5ܿ{ƉKMcX;5{?G$/9 ^<ܴ.z? jxfu]$MC!Hl2*FeU&W}ƋgߒM$%& I? z) #Y*ݼu $!G\8_Q(5uTmTepffFeUZvm9I߫O/?s݇0PVNQxQi'?;;W9@T31׸Na}_$.o@y/{9uw6f[Bg^׺|V٘Te[ Q&7<: خsʛ6i tۖv.fQ61ͯ%64D:ayx"o2SmuӧyC|EQPyݧxWU*LhSnWp\.Bڝr ]uhOe]4mu'["0X#3F_`Yh%J5MJZ`ZUq01ud\Xr9eTi嵁bp7vwv~(-0333`Eɶ{9P dYHdwJ6b/+L, ےdoS4K32%tu#$.zF fK U]?}s{{y1KmXHHI( C"!$ @C;;h:+"{.,ڃ H A"20+pl ܈we&h SL5dlBGUϋɋA}hd#z5핛_ӧVV)q53U#o[oΗ9](}D8:o9_O:mHnk6mݕP`uڭ߄Ϊfh@@>ƗS72||u߻i0]z|~UVnȢX8x;`mNtfoߕv̤m:J o6eMs}WPm'%ՇHLkNIRp%q?:nx#ɍ'bϜ՚ujCȗzؑzYrӱ_}ǭMgo.Ns=A7@|$&IJ†Q`4z~S)Fح^g#E0AtMn5ܝDRWU/>?p?`o;5$d.ſ.St37.'P$~ȯ`RI l;E65h\_zo:ZWv?Un]IsSs0Mz{7ԲgIvuE$ TkTZnDr`O0\}#`T17[e5KR㭒|Vݬ^;5zjbK;7a2ƀoO] kz;Ԥ9g#GAϱ"kνReA0`2/}5W^V/N0H |0? >ԟhK+d8}9;5YE#tՎ>`@ࣁ0`-o`?dݦx8" Q+b0 Vh9 xq/P5S=d@;;S%žoloz~l{;3ňUeMN"3iv>uwM) DQMΩD%YDZ8TȳfO8-in`EN;P kF_Ȟܗ0],E #ΏEP6U ʑ4rTEtubd8Q2y$JX⣨<(ʝcO*YX:>jY\0 q;7Lmf\YTw-9ČċCYh40Zȩ]!B慵s7Sp+c%:~Pfp4;Ҫc:CoL~U;겶)LI]CdFJ8z7\Z ugP%qTMO)S~"Nvr:5JGɕ7IeCCgLThxjD]`͔8$s,GlRk{뢵"EݲvzL.)Jд68 d8߅%#D@#/Gex oĉi> 1|-&R 2̒SA\6W/D}gmjb!ʠ饭R]2@VAF_uI?&t!8}XJC9zWZ*;|Da ʈ-lvÜ `fB58-BYΟ,kUbu"DG>BR%L r)Yp9(B_%}0k(PCc05r-+$~)3U9F/5Ԛv VX%`R`tW8ck4ygKλ@GgG8u7 _ &z4ӵ_co!rޥi1e cq6vU;FtXV-[|h%c5CC4].!֔^Ԕ-ADFsC4l ƨj՟ ճ<#$iC5O!<G( :i)0L0STņ֫dѡ7ulKpZbض} ?h7m֥8yy!PRK[6`/<],i©|̥#Q)Ɛ.u5gzZ4jo`5cU b;3@GزDB0;4YGf>5VccGCbCPܭ0Cv\FӍhysd}0l!SjMuKYsR` ;[-/ !VWfS)ZJ$߿ɩ/X^9eeuB1@hJQlɺ`l2嗙lP0<6>qK ) ~7 WZw+wYpMY+7iڱ?Ȳ0աkzWECXF\tZijAc"u=VGHQ69%>чHcĜj:0S.؟ڑ5f>>-B_9tf%WКLΎu ] 'I0\<'h[Ofs/hƴЀ3gRLB\4Y2KLQt|t+Ӗky790ͿY &Z:n ڄɔWj^l49Z4H,bg0ǹb#'?tĊKx7cϠ}V37/a%?[2~:B.meƐLiB9('^L=oow"f;J]=4F ӱ@+sMQC4ﲄ:۠?,amTwgM6is"o$aorsH[$TퟤC$_جcEPPh,Bx{ȆkjI?@|ёj˶u$CBwi[>57ƀ=%n֨ӫ`^9rU >)%[©hIf̟W`RW70?jW,=I:f_<@l 2YPQ sI^:>2Ykg9==BWd%_у#$f`Gaup̱%y!:&Xi,1XryfQoc ZSl:˒Dh7l.K1^ v1l0S(-@tC5DOn۞ܺHM| As4,>UE"y}sĠ%G aޱsD%C# 56m:l\钑BKchZhc]GV1]CDȒkŲo6# 5-<)k!yBK*Tm*@ZbT jх Y uvAxӋP r Qyu$d*|j݂&0H_#E^LE]M][uo/΄wK]xGЃZiN_O*zުG{{ǎ|/һO\ivL+=1?U|-,nB^w")5ǷUT4%s丩/obX7`_lC'bivL!T~{KmjQWUʒ(ne .u|7Փ%܋j1NGȦtFwU>!UOM,ɐ/䶊5yG M39-Ͻoc]~0/l-K*Uu;]ݔxAآZO:n/p:UGsuX`}䞕8S{ې_MUELo|=ƹuw_qyxl*2"k=ae}8C!uzVEDxWŽ\`>5ê|xϖ0!ؖeP{PYQ ):bA`Ef ZDq|џ}V劙yG[͑s9G]!)VZp|R+lڅ/RN+w/_wʔ5j|EddȜ/h]K.nqs(~\fɮl&reiw7N]@>#邗5J$7f ^͈a^ÆE@est 7WC!=a?GI,)uX)u]!?VOC8eƫ OPOJ]^=a]G>:-¸;j/2>:=A--Q71~{jv-ӱw.*6j7 K+uuV1B%2jr g2\Cb]KγTr:5ulSgE747;ӝ+ ,~5ԥfNЮ{1F_]+HaXno z`% ī~0؟KKcI?h%'=Y[eAkĶJ ;V.|}륮r3\Kl=4eZvu&X7rU0[ w)]G, ?VFlbo*u\>T(#f`鮿\G?Q]GٶFN"RμO֎"w:L}֝R]5;:bF  ez빦ݘA]uĄ֬@㺎H 5g'豷 <_+_Yڧy}Y8Y嚳ױEEEq8!vBvqY]/pn6'bMQ1ס3@5ξw\@i2ξSW$Vy5OE9{¥D)< S B6A,|zGc#(x>7Z/Fծi$|>Z%yD=^)Zx[æ޺ u/AߑwM?ƃ$:' =ժ|·G}ڸ%ohrR:cAAq,rGgEc2Il N :n9vQÔ4Ւ AGj] YՆ}ےo8#l*v>bvE,𷨢cEyO4Z^IfޢTS=C>>ħj tm 51V 4 YW9gɦ~̊ GLj:ҵ/a}sf~r qfFl^MlXNCqZctV }/^\4r sxU{_T$^FU7VtZ*`r>tW(.xXYgW{;h:TI7' TTi2IЏ-]CkR}g[cLjH{jn[_.A"J dcZ85K] ArɣaG=(NR J}F'j+$j_ZC^n<0qw| 0OܝǤ#P66nY /*bPj˹!SkUv=1E0?iOfku]9pM阁/ְ#قEq*S >L2lŮ55f؋x’j9GEs>'lo5ݻ #w0-57Fƴ*řªwыv 653#cH>lX$ kU{RΐeFZ$3jB l烊}P 0@:l3P̽Qw$jZgCp+=Z>){-X{@٢g!jo}5lutGcMsܑ槑ocXE!ݻv-Z*&:c%8>?C$ZHPZtx:V1ܭUװ E#{԰4DW"%ꮥ)%2pzCHKz PMďxݑT[O~d~EUߍ}X"䏤}led=6lD;%F(JjS4߃fH偷"8B0a/tq~:.g>c;Gb( 9O.8ҁ=:8.6sb(8/ʱōCS?F]UFd'Џ$Aߐ\ )-gpXY-v9$to+95Q[|ˮ~Ƶ!T5 /j%.R,*G0ekfڛp}鴟( nى3m{gcY4A;JWlG7SbI痈EB#ppўBd7 MM\KLi/?^+.؆bZ%2JN_f#hꕩ+|rUmۿ^$j5RW^7O-??RԓF_7U!74 S|VnЩf:P73#4^P! AuK4n8 j`H72u" 04&R!ueD `Ƀɑҥ%_v۷ֶ 43#pf`uOto"!-.;iz{Ԓ,W7$%e>9#]@nY2Ӕ9ĆE\$LSH]4im)#~|_׷}k Y$Xb1 2 " XMGQ^q^  b< ,~rhҫk34f2F%%|W$qE4r$*xhJ@1j l2!,E#΢d"D mu?e){egs3(X*C1$VBMP_ p,[-lA)`FL(!NbBOB(b _w{&D6ѳ'rNmD㷡#5טx\L8:g*Rp8oP"bP @ tKp GD}CǬ X`ݥJ44bgZ%sesr| r[ڞ[=ۦKAꧾ%A1ծwzdAPJuO2N xTUAb Uv ?1xDR&PՄwOp^B&- ,lg@Ll<գ{&{S+ (aw82yvw?RYjLm+ÄB2)6kh|!?c6YZB/,)!eڟS #g KU!R}Yd2i7Z'G *iVjb^)ҥRdzϽU.,COM*X#qPI BJ$KG3iO\w_J^g"ҴO+ձi]9?Ue׳%(y'dcs;Y i] y!ҸqV;ZVV8fu R xz%+AQOccE,dVp)Qg? ïXA!H z 8EIվN_)ѾDQHpv3smv}MPe;k!ӉT1$:^uXt8H͢¡d@/B7k_hA_;c eɏ2J}i3U(d1_&})h0d@L|^W =kS\xg%/e@>rgtd?)̹z]AN j2 ݌'ZOeg#;ij:vUbO3De4kJZ3uxmҧZmګ2 a=g.U{T24# @%ZͨMKR %ij Ն/eExz۳iW&'Σ,l} ZW{F<0z(I#UF,0_]VrlGF>Cd\ŀ_!eCq'~mƢP&|Xp$q& I.,[~j9M,\Gf!,U$ĚK?bǭl_:g^:*r3%<_ Ѣkicr.M-0$#R8\r<_:HƁJIٚzct]+OYϖOxse81iY\fs20cC qu e?J)Kaj&51ڬ~V0kPmn!uWzCmZ-U[n{f3Q))d3D̞VEeRWڳ3je2Geɽixs3~C_HE(`v-#ngFtr7S'FZ1~ o.[80Wm/w2+*M@5H$&+Ȫ ѩ{C&]/mWmyҥA^^;}Ƚ7ύ|4I PXޑ,uk Cn.Cϧ<]'C*_T֜˟:&areO̭|3vхz6wyW5lmƌ~jB1ղ\\BIf'iYGW2BkNձçN˜F?ZzGwZzߵmItjs'|YVkŗ~ur=VF[_i=fZS&fgQZ6_uqxj򌶿vjGpr(QW#'(Gљ29x` Y6˩uAyc`rq?zE؛Dž ~X0:?Ș}||hɏ6hpX| fW;^)iZҤBz}MHR-6(N#'^4OD_.I:]߾>?o(J?;[VPBN##DA8z$(rb1s[l"6_Pnȟ| 'Nsb>^c{ߓqB.,۵Pn.&}_?޼ѴWַ?E@S;=[/_qoO zvCd;~@\)7wEl7o~Z+eHFCfڿ#m:bFכ̬f|:Gk%< >uSCCDMzA]z}7h> 3 7Vxf_nAdoXowUzNl7@K'MP:fԥOM9~DK[whhmS(9\x'u.%di"Ai?Z>JFK4;p2?~C{kkZAk $; _Z.UR?: M(x'(Hx_S0n(mmwm;0ʹbњrOzkrNc4et C(56Jm%CI{_羹{ͻIB1yjJ:EE'UFziY{Vi$z#͓u"՗S}ZT9I;HC*)zK!] ,EJXpPp9(d7MTa6I[ICZVêvhFҭ=mҽH5WMІlѷszQ34sVf1b:KBirEJ0mxy}gk\: ITwD,-9Wr.VE+jXl#8N^k-V9Nnݬnk̨*ܒHaXZ_UJZH:qUYY,:ڬ^X&:,U¢WRO5 ؕZmYJ*IF|y@K~J$4"bcEVc"CN= 8'gA.Yw- .~].zRP45%:VZryŨxFIڌ}lss0k.Z4rNGJ,,瓊?^㳆uש:HˬJr/|gFprj95@FgՇMϘy"DC@"!\K*J {wZ=C<kTM!v.]H.즅%I: =S4QVmEvA+ۘ>p1U|dĭ]ŧ uQ9xH eg2,0S唲3ܿOgqY00WA0s͚BZk4vQ "jV4k|;?=8|;9Oөkܻm--ۯ^ߒf/_#;M닿TPSՋU9\,s[)[ٍ[:Y1+ZL &'t6׭=$7R |;;luUMp3'KtYµ%.$ ,i& [|Tp8ox0  G'5vㄡ<w6dj*ŖOnf?3]0Oaӵʺ0I,DNpvQ;?ygݰTSՋU9\,MWuۘA$V }}tImPM7I_O'/F ׭K.LZQg},,&O}`#10I#ғD}yje㏼yPzKil䠎 ђzimz90a9 Wbu|-rA-r%k. Sc~uζ[JLc ҆p`cZ҃L&.-% c0^2jjzhU7|Kj_uP(L%qbwEG<:Cռ)4CqZ2%]>v*z]]ܥ(;o)[}UUShu^FrU]TqNR(l(JTGMЩL.Sy>5{U)S噅MƒjT!kGFy@kj"kR#8*]/Z/Fa}Ǧ$5Nw9,I$"1bڥz@Lٝo6;'3O;!e4@(i_ޚA Mj|;tQߔ~GT:9U:h>EQy>p193J>0)ݣ-=ӗ&H'.Sukh*lZ+DH*>jU[4k2ihVFz9X~#fO|"=W/1q KPl ,iN8AF?bU7I*qe.41!#'9UʇIi]ѣP3l/+J8]SȍT$eI{JS(뭩 W |5 ^I]Ǭ{L l@RrGO4^)äX2/,!Ζ39F|ESw|Ts=%JĝUR9Rb?FZYӚ0Q8H|V%œjlyI&gHk%`LssPNp1[ocnRhfuݦL Ӛ$r$)֟wI>]RZtED5'Ce&e,[4{SREѼF9gȑ][d> {L,A>067ZtE[tƲd+ R譕F^4VtNg\Giȧl @&Ȓh~&~v͝<Ӝ3Ekwuhg$*ϛI|DdƶL^i_"w782Y<$;}Mfdc|7q\Oxg}ґţJ1 m33`Tk 3^u#\s(D Ml[vnlD3`T` }`.9ɱzaWm6qp_h[R0/85[%L.XKP "!0@F~+ h s2W&rf]킎iia$dS) CE!KAYOx2AR}{"ߟLk >Y~oAA?}#pEy6}["oTCKO.ߏ^Lus!E՟mt MX@ðGOŭ`?3@w]xGĂD[uAoj[r{cq]R2-CE78>XЙi&ɻ{ba)G[~v 3+}Y}m_L\P*BtًMҾ&/=$Lhb$U0 *Rʇ)cA:MR#Kt4^0LW}?R9܅\()U],ӥ$Xq&Zr?'tsR܉fE䥟'q AoxuOMJ)o.>$>gMEr1xT圝(N[5BM=h/2G%lUv SU{F:?e <EAV*# E^ a/:T0s 7+qTm/3ZbE&V8RN[:1n{}9USyB]TƑ b[ZH~#U^,U;2;(VS_}ODQ'q;3 IX T?EN)>5kE=*/a}?~_7&pN4%{N7IK勍u^ 螉 SfYķqlaeRse{t䚾8`>PZcb m:vz_zA~vrcOr^Jh&}&y P@ k'AC*^98 (UW4I_GA(2yveHk*&i &`"xm:TƾMl(md~n!%MdM`B E!TɝHe t B@<EE@ ̓4@ ] @v8n$A |3u/Y,hwo`\~Mh@  &;7Pμ@ 'nwo^Ȥ Af {626V&.W&@%  3V&&Ȋ) Ё@ ,8IWxn8A#2L n*\~{ =< |\WiJi{kݹs w Nδ揭nt t{Cw(v+ Sͦ&H㍿ҵ΋x%ΩI&WS]?iw;GL#p(n6-L Ir_E_k-AJ[Xl FA%5F!`m!<5pr澳1vXRhhK!D&]W'+5YAG du*H@ ӫEnet(Bș,tYx}Wh9uEvi^+6Rk_dH]a RҤdon)WfYp^, \xpcsJ_Fz:\Б Ǭ_n'@"dDib]t6%o@Qiq]Y<^@aUY $ij\TAkuwU| uBӮ SxX{OwxZaG-ny)uvJx< njSu" 롦}v%֥^XTih1Te62B7`1Hv+; Сu7ElH,]dE^GUkݍLvgZP\2n5+_4y^Z1eӈ\#'ڍttG3|rBh)VU\PE>}7D u@t^L{gʿg<=\h=:BP੭EH:qת%oS h J6iki^~`Q d"ۮY||jʪՔ(F f~<峮K_!)^..tּTfV"rZ]i׃ǴRP5 x,CHۥjzզT V-g?2Q+0Q-Y͋|-5wTH:kktU~/A6Wv^L+f/MKZR֬M:f`mP}{ۍ}6eνiT &h,>,V/dWIZ{m\fboع:.tů =vy3M`^isͣ{keAc\pԴksaZ[=s|Ρe&gС& njdklIY`J=:cuyts!ɽYƛ?(߯|#B5o`LMO=DM܀%ɑdXwh%,EC48OU"#l$ϲg[o{Q[@C4#Vpwݾ8KI? 6(luWrpEԵokj15fu6,<ccĭ'f1Gr%!oTRiYB f s{g=7nk%gd䓭bcKHb\WH.JE(c)Up |$b}r%B`x0 N 0ƉK)̋Q"5 3_(Ge!I_nzGe 錙\gǘ͚~4Zɼ2K&c-*l^"V,? *~_O Ӽ:ꃃ\$={I&MHc^!2pud+\1# .r7hrշl YGhpٟHKH? tg129_Ycz 7Pܐa  /.OU|AApcסwBq `\tv(+u.ʏd+13‰R/kdr!: s騜V~ < y8brtI^j63dw+K fr|T 8љJ%As=3w)Wv q( $g X^3^̶dqd|ć%0& Ab HvK躺W3(wRDiʒd$yrdz)ךaRQb>)rc3-)"9ΰeb<ʓhsI*/DQ̧>GLq䴋t1v:u=,wPJ.`X"yH$>řF{V0IxM¨HhBO"AReHdqXG,jKlxz{Λu#h˹!ʎ_ 몌SIs+Ic |\g]&i/C? .cs`ɽ7T,ݭ+)+Q4N .uPc㓓K2M*`&kng&V`7$RHz`|TR (;Cb73h%/()9]zhL˳:˸ni׳Y(*1xO`N5eLBDɤ.ȴ~n& 5# HJ#5:":=sZ4d{?7lMM0SJ 5";yd )Zg&lP|lfePJX%mŋ8Fh"`cID|n \v 'DR>&)sl5l[n VMTYM[0^0w#J/'gs9׽R8mCNg7nBzٍtA1*3׷G(Yo\,#v/J1ǥQkBlHJP n pź`dRvY¡T+0i_a[2ɕRf%Dn5<P8y3%-%PSdJܓa{2ĵg("|ٷ\VJpCic^ X J&\+,,JUbz|oZީwj"NS%Jqǖ 'xIXd{҈ڒS:%X(M]Fc!K[b Z(QzE2k2rMiUaժzҤ'u1X@F<ޑ,~b D 9akV`Nz|č%r_9rTq /+? <&*E 2,gNΠPtMߏ}S NM]ߓw]bdKFK2a,)&*$2jiD}DyQeh{k&ɒe\fS R^bFҦ@8a Y6u.&<ׄRt5V>errl5&kŒI2+hɡ{ֵ{&4LTz]%\NXpmG [\ʯ\O| ɯkyv)mS_ks(hfiiJG֥L:a_Z2c5=\VAiqSbȃ^U )imZb |KwiwUj3|Ԕo|SaBR.Or/;BLM,{@? K9;V^ Y@Q61=n2Nk?}p. Ӗ J}MLZoK)5L_J;B: Q!2m_PRÔKnrRL0d_`f3_AVW[(q$`z'x_M;4HM_ +y(W{xXMzk^?eZ=q-)|>{AsiQt0'q?bI^SmґPj=s_=-b<2oj҄9{\5> ,*o ^Tpz(UI)~ͼǗ('p7^IX[.D+Q-h:r6 x3J"r ]\ilEBTG\p67r>QFjФ}]"jsZ-;EŋwSr%j+M¡ri#:%bT7q-A[\ˆLsH߾- .ⰧפN6"㐔%j//2L`94H7&NYrәeq"L)7LgrN+{J xE ~-[N qn2TfNz TiR[D)m|7nќVUaz:%R)l]jSDNI72M*FJO"3jU9>C|r{B>~*UkrҎ#ZX_)jG4|kqMD&e)uVxf4$q~۰rMez噱'qy)Un`M6VJTq LZO]/PXcLr0̲q\Pqr$~i +R*;PJ&uhoN跻ǔ)0%%MC^G_/Dz/w&p7a#=é/Ww^+|\%a3h+rT7+oi59Tl$X2l7w24B9)ZG#\jf,;.8Z|X&."͸7ˡ65"Ӫ)]SK~^o1k roq x9oBu[BB *@d eMt4 J~%|ʗ8x-!Gi!.z"%?#ŒxNjH\8+PI;j5vK+P]7$"5aADǸD22J3%ťpF2p"/J0,a K ;J!ٝ+ff 4OJKJiwҾ4`8-TiONfmĈ>;JP$3!)-$~&=ڟE0p8qk{Af ~- 8 1˿uB޶}&HLuJQ 08rێ5<(Q; Wnu0V;B+ўlR@/eA@sjJ\"8=gP*ʱ04߆Ԏ1(MX4ቻ-`)׫?3wrN-uq)x4iՈutrf}E^e:IEupV=ͩ5GF:"ufÙs^ruE]X#QJ~]б{9rD_+W)uz}5xgQOwM`G UR(AM"=~e$ONFt 3ݻӶT noU@pE>DEo\enIuY)lצ(^.9o*W%3_^j?i}r(fv7_h9I[Ye3 PմRg3ϋt<Ker8/.:]YRIdrFLx@9&=;r~6/q;6lt xAs{U-.r](|_̨ 8bi_>jTl؂Q8V/zaJ*/T~z. 'RN#,<Kܝ " FDX HaWSqr{8_z"і'4Q Yri,vR_F55KKy7ViNlD;%ׇ1% o']2KC BN"lZtYSWE^!Z$:QMeLJB;mHw+Ik v^^ yb@1wr*Zg)bѣ]GT_WoػjsV"7 k./8nibcP&Ċt$O~NL2$Z.%(uu= D(b 1)hfƽ%93wFN(T/%㏪H" Ozɱ } q˨J!DʠfF5vk&ʱ^یx$C\BM!0Y,gz2e,o +듚!)xN)\6āl*ّ %T:Ɋpo!?O6S0MG[|e ;?6lyg-1_nP;ˍtHr4-Šѱc÷Qd)*I]FSN Zc^pDvm\aCBwBHP6d\CKH/xV.YWQUg6&ZlWl~CVJ&b#yzg&zz- u(&+**b>Yv^7R!޳va%㒒 Z$_#mv}7%gwƥ"dHZͱxa6%m],x<`1zƾ4|w?ʻ d'_zg6'95vK8c U[Oőb}͘DLIf88VkWHo5ֺLD<<6D]#|,Jd뢩x&kі(`Q1 1. S-]Ȃ<,yV{' F4JW|pm[{5_3_Jg1\tzwi%1sdAlFnZ&֚DBi`ANJJb$fOqA^FT[N~@7W!=(@BV7Tzm~~)z'\)S eL)IkW1ˈ K?]PMTu,-QKV#3B2õYLCBIw!aKSuP6pTfiC )JdJ~0[U+H "YS t! +̚p E9X |u|@FNK[*锬yHc>f`8Tߝ[x6!#"` #vPenFgbד\b#}f/QNq,!Wݎ3uخH ,f7-PJ1YGZŚ$Gk#0%3T%"@(43/K ?Is?~{   w( vEr֠ ~a}⦆2&F.*2?* {ubk[}g lˤ>T.b5VKh: #:g@bǟjiy'1g9>Mۄ? \r$-ǎ^pNm; vgڕ4zeZVԓ; g#H=Y&->ѹ 8%PH/`TTǛ\.\j~'Wg 7%80-]5YH 3k0Bs-{Nq%W#\e5cx_ 鍅JA7.0FLH9d"o=6t=ZfQ4=F*}L95)Фw,UA_ O"Sh j03!2月 D; ZI(󩡓īWa, Y[:f=.n-lTdVc\zofSm?^@Y}a\ 7؇T0k}SL|M{ɩ}}d8&/bm-HD (YoK"9_mKouWs+#qcsmmXX]!E0jT'1Dի $aI'2"7ܾoVտbS ȄA&0A Ep<((`g0"*N._I<.@af/ab6\0)utUM^z]ZMl pL^]9K_!uy _Y;( ՜#/w?{<vF e,(#&xy-ƍQu`$OMB5} ]c$Ɠ`s%V3n;[zrxr&U|Xfe_|bffƘMqoZմ ˏГI4VCEz3}ٗpq>c˸ΥmRlʼ Ajƒ+yF͊UIi:e'W)cݰABM[Ӈ!)CB[M*CX~$C9^6=<LJ5c:]?$Q%B֧seF4ũwůЅ?ʣREM %$%2e*5#9_dPjv:SBgW|*=g9g.KB炎8<-td1v j0 c#9')i%FR@ NVow/ϗ䓂Kk wqF< b^gig|i6t8TaH3^\~*tVSV(ҔLTa6o`Ba3 ꙦeYGb:gQ'AsR8дT35TFɌ羥TsHpFXğ7܏ AAZdsFp]q>w NCyZ;@u 7ocnVO_mq4v{r~vlN;v{hiD0>ۓn7]oo77Z괞ݳ*ʓWo1paM|EH&qd/ }sd|0zvE{Trj_{; x-y$ %%$Vz>8}~:o=`rq׶Fm]`P; |(Z=͏ ̮7R]1WpwU"sa6Rbn}:uMMz3)Ns~,|̒ԤxRV}og[/(|1 `7ȐBaӯR}J$ .5|H6NnzL/5 - Uamv}`kӫ#RwH%;,Т+~ *A`'-.ʿtjZ?'cO~Q' b $Q,-!޽?mmE;Z +0~LŊ'A'Rezl%5 KGf+9E Zmm{hXwʹo}iz'咴-+^-k:{49a(yc_Av_"//\|X*V^E4ɲBۈ,oR8dQT&aU{c^38SQ^Ģ IZJ+Qp$˱>Hݱ}:?9y~\6PO'6Ұi3|Y9`n_y-i;N@o"XfA l NkAa.٨x*Zyf=y* |.$;|_b=#tܰ|L46):<vVRx ~TYUG$}#eF"{!RvUȪնl D3Eԩ.dL4Ѧ҄7vk[!4R9iFGH)8)`& :IO2|7A3VDVPv8[pbapMbXM 0FRT,#"x̓y̗'i8.׷RhDiT?$mꞖR҂Twt4ķJ%Ytl*HP>"B ;Z05kPMK:֫^ڷSx3$6[):}i`FI'325˙ǖ bm=ᴃ(eevr; ;N xB&wl4͙$!dû|&| M)?ެ%ZCBl߂M["tJ&@X@Ӻg&dv7T[:dTdHw+͈0""l=wQxIAA2q[aI2Xe_|("st&ʞZs4DL/> tn!8o ᳼g+w̲#SĔB/Vc}Ň~oQGsj%LaeD2`/:Dƈ$-es" ͘J(W"r2/C-|Q}ܲ(A e7/?hQUAS!5FX;t'`m97=v>'[.zBT*PT&N_` SuPAR 𘗛z<|П~!LlXX9g(YX0"9qlCTJy`}*^ilʕTX,QDU1BAY]gXHPa*tSr0}+RIzdd6w6w$dƘ .Y ߳U$UR#[(cIh06_D|4] Bߕة[l=_PVN,ɠOWO> cPWQO(95X'CO?yy_;]4^ƃ\0ř6拰.0/D$ *ySS ^]nrvn d&0M00_ `?ݷ^TQ:|X%,N^dpKu~_) ksѮbhǐ[{LrNԭau="/q;w5A=K uYpzEYC1fis/gCA|#՗fy0 `}O݀C{UO|60IM\$y3s~F6C7盷nk5vXg٨Ss=Lz%!/Єp=~ 8C |*ចHw0d!p>",'ltba>@ Uf~`KfL Zc,ҝ˯E 7O[1X:{Gš_\ {Nd'S: @-&|Q@``0)c<' (,p*vGw9hF=3bbSឈp:5aVa}6VNUm^ x[2/?Q. a;UG5WMyb%76f'*qW6R/;ahʄB?6gH-r9Q 팭{y dч 0@- zjj~1'? kaN7?szw> @rs_Ձ®g \27ڛ C;Eg mbF3Q{xU!hreku+[%GSt0\NL i2'!,_x}DRԠ*?h8/T'^bn/̍yl:loO>yV1x,]=IU`}:Yz&ӻQ G ߣºu!C7۔yy3P:9P:16ڋ6T r(d aG*B*z ڲşsYZZњx5"`D_Fo@4#AtG@CڼZj̲m€"W4`0z/!8̃[ƫvGE3 yBI ~x.w8$Vx _L%#Ђg~39NkʆLK5&b3ޠ iE.R-/]E] ̷u_T^ǧ| y`RӍv\}8Z<=vbu;#KMoyɸdX׽Zg#EIԬp8puV1T!վ>2wi޶w< ʁלbUJàݭRѷym%s"Xqldu+oԛmNA 6sFw ݒ<064Yk$Z4S}^J;>D/,j)oq+{n?ul^S6ɷ86SEǜT2kLaNIXd$,?W^ߡ2r\igU\ ^.Ĥ%q: ,+Fk,2]X!y=J?~zUTleD)1̻L"^%5Э5&1DЃp w p!N +X7Uǿ`vu}cQBo!|y> d&v|Kdnarݕ%k%- \ W^ڮӢL!a}Zɥ_nhRZU݀,-Ir\~.Fk| eUP w$ ܘiG }kǙItܜ&@5HQl|Nu[e_.C.u+`윮0Wb6TC KmN^*Ÿ,ʁ-x8>ǩ4:nLaҬ(T_ AO?o|0^ŞoY4o$`#xi) E8 i"p7\HF#%SνIJӫzެK?=3_ߛͳaԮvSC֚YR6d < d {U؍y`l2a(Uwp/E@@KO/.y´6;kc9& 3/׋Eˇϼ%;ZVa:\m_-=ң920}/!x*k|u~߼t Ugw@og]I d:wx*v iW. $ I~Bg}1H[N^:7 zaف";slTTa@UB7q֟?zwK! -@IΡ+Em {js9_NZge-@!~ M^|ݛն˗ Ua\'F1+~Av`:ibD3n ڰc VMǫB^{mlT|A&щ]̖޽ a^_gPZcǫ8uzұDnC@W>˗nG1d  [9 nbSa(.AUEoU|]C: Uݚ-$#/ׄ1MQ(EJjARFV@njbƆs qA2u, J"2/YP3LC*_II.G ~c&M45n5.D^!i@?!E*`/T>Jr'q[|aW+5u}u'qȷ%ygB̵!NHDE KX nXAOJKJ /oԏ /-> 7ąߐj kIf,'%@4_?w|Z$5Ԝ6Iyu1xNk:´X8 @[<Az#t&C,6gRw6Ia8ٖsc-T'XR^jr=4ސ,+0WÔv:a]E/W-b*LD*`F|'1&sjW˙tL$ĪN)FB%2Qy(:ߝW-n@-("Ryޞ~;hFpC<ՀT^\|2ؙcڋCpμ1?',d%7'R0b(f06@?!: %ulN>;%%dtFyB&PvkHSBǗ3͛m a+:ZjwAaĎ-Kg {Ȗ?*"s *f1+CS?}w,-Y/ab5IK :a Q+\ZXXK$iR/X.ģ~5=Ou9Z%Em_VP0mݭPUaYĉ!6HĮxDJ-H)uZ)IE|%|]K~aK h (.qVmximnHbZ;M}/~.8YsC-3yv?-NUц [}_kc?u[,*LSE"0KX^SrĴG)QbY%K(|jO쟾_yg@0ք,ߏMgݳNDm=ϠV#Nj[1dx6c?'R~("6[:Pu4N<1|~IZfEwO16"G_ ,4žλr۲at /|m)[aRF%ζ8Ҙ[3 "Я9f"կg=`1}ZAmȈeoo pl]-:(Iな.g<"D4W&#Hb2<dJcfC G6 ooW)`bcD+nV3yȖ/H(+HPju;#K?/{EZ:o?傭,[+ iSGsigTg#rv]$:yNrk E>cTb˷g-dP'-^Uްע<ϴ5V=B$N.ě= n24"I #p6X XV@ "Be=$EEYtV0 Vc +RibZZնǪ[Z0X+"8ؽ' ;'QSeBҴS7m3ǏaU2-? h_YO!!)$4ǺTR8(qi\ GSܛCZoE}|iWYgcVװzRt#&qϷ~߾Nwwkmuw=UjiK]k ')\ZUSƌZC|Q{^M~fej+{,`S/2UrQ @BSʹ.8\ o_IzQ[ l_;}J/m\1kUyuj1ґJ/mX1"*%Z@PbZlO*%XZ9ȥTf*bT)9Cd/- ܖ(zVx .ZunRi)*l bF FUm՞g^9t8T\UNEc[*|5L2ZnaaD`,STxeϽї9-i[†8gR=ym+"Rt԰{j0iW, =p灅hɚ1/u311x /eo[r^[ Wz>Z)-kE\4HtSye\[Bڋ3(o!ȠjDO\YUk[d> /_Yf%2ZCK479Cf[W.Fp|YzZ .zb_&ⓞxܼ|٥cY񍨆ds1-oeʗ q׉sYnYJ /vMY?C9o{Ikg8(r2RWu8 (e}#V$S3H#g䛺x/'OfҊs~ %ݛvYij  5?|Nh%6Q~a߯:ђb˧)=vPb_"v푆nb =1M[@R]/~Y5:by9D׽C]|߈/a\ `\3LT'+YWjGQy+c@VF5 //^փ0hZ"Gjnu9ٵg9@ 0% ?tK.yR:O[d!v ?l0uGIG:אe$<%1 5.2@++҈?P_n99[}1f7aRGq'Z*3Y" T/Cm[ ԟ~c+?Zk՚XZU_wm6xg DF3{}-2|ju :E?{'Y|l6@a{|* l9TT}T( G^Qy`9I+թ1_8smC*FtY,ڴܓm # IP,񝧵%7 'V:\#NZE=[0/Wm~榷-L5 TTښߤѱ->84 [Sĩ,KJb蝾}(U6kDT񉮑l'Q)󻴚*9沫GzO֘?Zѿ|^}ły܃/nG20t#O9  'jJSjEKp+Xm0[ccp]Ƃ9@`߇8 ڞAktb^q"g䳚Wڧ D;q.v= Q׃z&Z`zRjP)=LDGҍUkLIYfAM#@gVXnŅk[%2k"M̲XҺ`D_Le gdG KXTi(,DIŰX R!,|(rM# /~6>7cum5 f^8#zڶ8ܨ LpЃU-jX2 ~BXºm:`H(EWb n4%"p`{]ۃ۱suݍ{mvv1kxa۩F2]-YKKmyLhRoQiCD4`E`/޵'y=ɓq5NDa•^.R),ƴ1 \oW bL>6Buė\J#48B}|F=\rkJFV` M383pi"F0_gwq]eOW/7|x<YW"?[5Ik["p#"I3""?"c9eTztUp""D?`"nt駫Αyk XӮ:据EDRGrw ިZdDuD3'#"QCQ" !c6N3* C""#;#/"hD A(DDb`DDv,xQ8d9HMpʝA\C1^E x S@-wD) BDDʆÉǣLW%BCD'νǍDX%<"mDG**8Ec.*M&*ְq&t"#kv\" qmk*H ӹQDG1b3ߍ:q8:DXvDoWzܷO#l0ϸwaFLx|rwLtaTnAO {&C. ɯ9~iqvwO;=7N. .#֫r ߣq+\CۺfF}7Ʀ#b^ʔvH6"@3"|p$R"2$DvD-_J8giu&.Oñ_P}:7>!_C*z\ պu]EX#ȯ\A`ɧ`d|ʤ㏒]2׋z[%zVS uzY_L@?d>yoo|&n;%Q71Y Rq eOd-} XxIgɗglDMŭV_6%uNUJVIVS7DWzwvYRʩl,7`&j(h' }F`W#{PqzW? ޯvq.E!C]W2z f']t`L Gh ɀZOK5(w1y.>쉙fa=Vŕu"Կvz#r-!%,2QC-`Ab2XMd8u~%)^Sؙbe;N?͡{찷D݂ڊb=nQ{<۩jīFh 56!}{\V٥u]^e3khPQ=Z66}ll&J2l[H&f8}Iγ>cl=넥b @AdB f$#jX0 NPoY})$jͮg}Ͼvo˕hs/ϝcD)c&h"B,Ƃ.q+n9cAvAu_|twV$ϑDFcd~W)"Y"$|rh7_q[ˌ.u_!m\^ߚxݷҲ;p/^HLjqe֫-av?a\Et 馹\%_%d+yo݉+cFS=\qkE0N0R􊡯^vch6l: 2os|qykbbX<=S+ԉ'(L`Ճkm/W}X'LU_{Zċu_Re޳QX7e7:nk?.j=rP⺮E;|1sPi@|660k̬,xu4_bNy㊏vI6 XK0؉ z-x_q@b`eWjO\qUύxEƶxx%=W \qhIʢWB1t~wTAVԼ, 5WlVU4YK#H`  [jɮس?d.5YVrw+myܪ2ɇKLq_FK8>GuyF.zLdX_k Ø<=S[Ҳsf-Zɜ!W_(f_unԋ GkE{#>Q7=1o-ASNWC-b.15 fV-#q0ȚtlV7ʕd,|eAJM v `P3E.i([,% @iK8D'.^P* -Dy45q$sC=aeNŧ蟒]DWhz"!yYzG =0 Z ȻOx9F3V! I 癗H[΃n:!FZMyl痼m56% {u0Ȯ!%35 Jukg;bۯMOϜ>_+-^je$W!OX8̪;,Wjo=OЭTlLKn~XM-fNy t*9) n7%A?P%v·sqΰv!iT6De(R"U+m۶m!+*}͌ >@o绹t~5|u'CP Ԅ:b !DP(b$h\ߐ٨-c`GDIg!|C]_6[u4p0v`BbR^D;zΰz{Ch癴yV!-+Q`U=JFje$% k'Őmm)$KɀnMT. n@EM_&)Jڪ@oM3 L;L)+J SbW1y2jԶa+ e"SrQ5v^ {df+mwDfq]Q 6fl1c-mfFkՖ\l ׯ;ok &=͔϶[12@;7Al @\$^O|p.u] ĞYv5l=i~\(8ۮM9L.f>]ڢXmB4:g TG \a,yP`?\a1/o 8+,s+ SO*(s6)5BTh PƸ ukr܀ޙ7ۖVɯ0 <9YFOPOaI3KӪ $uLZTltG?DddMD–a,8 57_7im ^aZ@/e;k#Wux}Ij*c CUk7 6@ ށo TEiO\HFkf_u/B!XԈd2{+<ƕ9ȉSdx% mv cu[̹뜿ϛ/Gx|L bU8뫕ڂ_U}ڥ{Pm6S0p μl| $ebQ4bX%6kNhWm~ʽCeG Egd? 28[>1`eCZ䈁V{Aqmsl6S"z4?^p4d>E 10<YT_` ẙ#g<H0$JD6ive ZkyL(׊vG;[ n;O, F朻5IZޝGVt 9Sf5- ނIӛ:4،_vqFh0 <{qVhAqH?Ѣdgyh0 Zlr!"X#!~HbaC$yUȎT݉bNou$T>{(Ɇ{Q2Y/~܍6Gcҙת0{1t]6]㑂 W0UG97?d"š}UġIcHlk^hsT_PJQ) $; ֧ eGq{o6aP3xlS\1fk=b-ޮIN/<f:ǟya@Mu?_<`Uc>Q[}Z8sD"; 4L&$:GQ>>X2u_wdEϣ9o*VaӋq ֋QYeR+ι4(7Y\NK5}is0D@C?CG1?gln.G{ ѭaz dY90/f9jm&ȵ 7ijc~ǻ4߭.Қ-Hڵb0="/7o"'9tDMε3JM0DzÄ!80kXlEjΠLtSt`@ Yhp< /_m&p]/$/T2yؠAѯkS9"Yr;ФHI[e٢M- vi~21{f"?-AQb2Z 'jiaIN23NNIMp.5#ڻ7;` WkyVLbH8?!!y;B &IbGCލr{Hh*9^mFh]%~`qL&"ZOvn.l1w[{VJJH5^v<^ ϏGhz-C{Qˆn=U~nbQ,5 [Tі4UB 8-߯:7o|RmψAs@fӢi7߹nG<{HgO!%P}LrZL3Sj)n[/%F -G>y2 b3Fmf˙yaV_S518Gh(ȧ`g& ANЫ|E"U Jв̐2jhe[]vl8C Ĥmn }Ncf#իPr'oqri|T"ǿG ܊ROIH@%ztz$Q3ި8aL BN[(?2ZYlcuilGkUrhQBW뤮zO]d]G5M uFMIt'wֳ/wt ,=è`}u0"K؁87PWm'huJA}>쬽*J^-7W]rWcfI%a"PEJQNFKĸפtQfYI#$8hSW;|YiFit-·WӺ`Gu9,3궽}kԁ{IYV4@A8b];6V-֮ܵBҩQk\U,?&X?3>ԝzGzB<,etX@z875gsmFi\Ojd52[iKثm:M~n^mK|140K'RS5^͡Ct2%F%x|c%V׳Dy 3] w|h1 ;Z/U9cÜT_ڹu3*" OI):VQgLU(Syl]$1" v֡ EvOsf5y(*|2v)BLa|D7_M5+ɵ MJ~0IE AE322|1y7C&3NQ{s ܈cUۭb#SGPY@i1S fe yѯzQH*9tk^ָCƿwg>4&" ҇5;A5K;FПC|0&dtMSAVױ~qRb#f `a1N *NyٓO-Ǯ{D:; i6z=ʂ5_n߾ZH._Ԍ ¿N p^kbQ~PUʃQFAgwMW+}WDY"1#:)S 竐p@{'s `d#]ٰY4eq ̠cjE<5mV6}}ϩo@/ Mzɵa[.Xi$:RaGS8{s`S%;aҳ:PxY V'[}SgZ&t;N$G`yw^$]Gk 2At]z?J~<3bݧO6:GvwKQC  g"U>e 8A 3ʽǂ &wǥc`<}8ke[ C _/w4omgx SaҡD"EbL]zy@A9Rԅ9ù^]U^Tx9Dv zuQ_1w>՞Y?UBk׬NK]^c^XN q {Nk(De~OebDMY(KPX(||SY~C""Nl+]a*f]s_*AXmNc3hpz02jz6~y\j0aj{Hح}^+Sv`GAǝw&Y0P|01IKG7`Լ- S&y5+@Z[d[]pGtoXm%6)^̱YKHKCV?HFe<+K4ӱ)j{j%¹t[ރڭ}^`w68o*cʼ/@K1RMY5`DZ&p驽oŽ<_Rq&p2L~6bn0`9  cM`d3BPƹQuUykN/!{hݎl^!@X}UOK_>C2SQj4C5 Fw+6013Fb,U{v]we03oը~oBJסN7!?yj_c`NXe-Yp@ 0Wu~r{?e N+ lV"=dY^b^571N*D:^kǷ^7:`]({%du*C|F Fؑ}Bv5+5T ^9z^:*/O;{r#"m&>ٯ'Ż&gq]0GoG  fu oqT0\6v}Coo`tS` @~ >P|_~p/ob.ZuMw"njTNn;%2Xe)#W4>_[oqX zoǚ:oj\B 7:i)(//|k vjfxBHKƤ|OarqDKˤ~Dj;x1#aù 熓qUƙ @IɨJo5ԯ~714ymխsou˜ٝ fܻb\fb~@-u.?7ל;?ߎr[aSUك+J*&|~gO=}BǴ/l_̲PrHyփ[NjURvūF&8Yɧϕ! R5ef7𢴕{˺ូCbwzf a0~N\gv=oh; q5Cg!'d|my' A'[qh|ցQ Xmko{{ڻR8{նiPY baY%nݮ dm׋O (4"_2w^*Lxa( 0~@ ^ۿ7;rY) 6P 0//Z("Ec1N{""?|߻Gkvꓳn[p{#m7]Aί#EWڷw 1-͸z'͂2+ϑtnԢl1Ï>y\f@}$_:;Ժ<}OO[qXvqIE{=:¾[^ë`E{Iw-JZ+ 0!gޒp`}48nq{Px>IlZ߿Z d||Z9Yq$vn`-L|Pru  Ju^B_mjG)w_ D >1B0y,TV%Ty7 9#8&ޜBE]Qmȉ 19:ꇼs" S,[<ڮȸ,dnl"8ւqB/v0@-e̳ոq\ !9|8-X›s=]K恉\(Ўi+Vy='CQE|v*uMPYXkdzث6Wp4`A,Bط]G[4ms%.m$Dx\gC5,!TN99Y|$EՑ7RͪI'[xFc[AJH7tII)u#7N!_Eu誑|*D7Bu(/ ש'WyZYI4`7.nn_0шYqݿ醔eƦw]RÌ`?i7U}cqN}]K4($k.t,*FXEXFT ?{c41.3y2*O|*BmCI<]_!iC޴|-Jׂf!ThWݍiAZ2}!֚:ۅp0蘴tz7\Aŵ!yԃ݇ގVM`m-SwbK;cP9eGT_&s6p0ƚ>K#~1ƕ>`zCmsUD\ vt>.R0-G샎XB-K;ӊE5Ը~Z3Y1y@_p? ATġxiDH:l)N{؞(}GC6-8`Rdqz :=,cV032넀[GAuA/3K6kem%Mkh16 Clz!Gܷuo_]eq!pxV7죔bϋgj:F(i#srBc/\a/<\;,6䆒E'yY`& &w=ǔy78f8oELg8^ePȑ[B|1 *n"ݠV@}4JV1B>AURMf0'Kޟj׾0 woA}dkcpEW|8j0?m@1a^σ#ao 0=`04 Wh /E_%_[wA汻`-.wxdU0J qBvߤ00D dp b )`p?Hs0U>?'(`#2p5o $!$H弥CN|rm[ձ5^hZB$bEm}[[v_o{o{k@U)+8G_}ߦ#kuyts= rȥkBSk`ҥo+I+<*r$ؘf*sp{[z 'p#iX1[n A"E$vfP9ysk92,r3-fo2J.%hA`Wut}EU]K  ~ 1K^Lt'\9;s6毙sF2ɕVƀlv*2= H XLyުV౲`.QrB,>hI#% 4RYU[zTq^˺ U a$*^Y\ϑBp޶je=uLǸ $KC1wSyrlӊ:|#Z=-%e/ Pk I Ҥ}?3\Ȓ506,<%d4NTCk*K1;FFi'[R垒,0U:V%jF9nhSurt+n9jpYH:E==^5@vzs} #Vs+2ŘBm1o#3`7j[QUH1泿p98eQ[4efTUx ET I'|&*fWQ%~uz=8k`7(9qILHGkckao3o#`4}5$,;6T񷵹Z~rpCo.Uph-ͩуsZZO4 N/JxWzcԄº=8k`7( :cc@Ձ# 0,Dʶ`&J %o2.Yo sE4oiBԵ;T=Wn@M[i[]e"T 9U]3ڔ/==3'ϪtP&֤M8Bt*W{?=KS.vZ99Y0kvɭr/R*771w} ?4%?wEܾ\< q`2vqFn;KU{t0/+&V귺'V\Mxb~W*{.ǚ2 Ψ٪E1 Wg d_jm5bCO ^00n-}QF}5[%ԹjSU<>_0tN*癚 5uCuU3g aڌ.%1U {Q[Y?t1JmA U5'\ةV\19ysտ( V y*3Wa/зy|zA/3-o$+} ZJ NFV)=!2賹2.RSk&# . YJai4V4t==!=Ϋ3I8DA?LjClsR V$Ljn|mP|7*9r3@Q_fIa:Y&g>kлCt6WmBgMцB}",N fTt00x"q18NUTp1`voQfOQV9J$N7/C^|_!@!(Ă`@לJ-mb=HgXQ2VΘrgJ4?QB$#gsILZgOCZ[LPaϚxx YC}p_0W!258^-ܚzÌ!c ~aqZ:&.?"FLkl2.0  a.6T:6b:!@C>mE(r8sȇh6/lciCk;!t1\Q >()ÓlO#g3 -.l =];03,,iH)gZ{!`I%Yv,ۖN`S-&'`M>9^ &[M3\IfeP)6|Cb&,qa'6 Ư#Aǰ3l_ʨ&q*dա]*o˖#$!xl״\8,ʙ)P*#!M8΋ GNkdZ,CqGadCS3U6qU~`CHmQ9fvF+5˙-v Vfd:-6@\r6)/i1ԝ͹ٵIoHYM:ۂ m{Eи_$O20J=ǟKzFَ"_Lq_)Fǜca.yk3:nW/0(zV lsHWgV׶ Ŀt#Q?I0S+$HP*Iͺ!{݆ Ibh 2Ia1U3à ڒGDMp !Sݛ!b%n՞#汵^!:L8֎a *ˉ"C6!?~qI䰹 zC|@B)2`M]Wܙ #Wb ;Ut9a䞞&r,;(J!LmgT+!s$*rA88:#`!^B/_ ~~ognd'Kpߎ9z6~z\t]Fٴe:]G jk%Uw1t[ :6Ť1l"<T;[Af8 l0AB~:knVM ID*TLad{vodH;ȉjT? yآ>qh ~7uܞ#i\$'Gv v.^;a~Ơ77/X&7 DzF2*!c8+]66XEG #^6cwLݸp.<(]}ݸ`w ސ^n޻|Ӏ 8R+)<=Ć|Vowː b@0$.}jD#?|6`HEU)* sC{mo^JūHDk Xom 3>"WX6YT9q/ތre?(i#/۰38SN^Stp)F#~S1gd[Cn͡[!(6葄JJښ@ΐhý5ݻv^w,RܯAb8x1Gem9cc/`Τ=b0C w3hlyQ摻muw7 5Y4B-?yO}[5 8~KmGWGc>ؐ*/|wZkL]D_/k~'aKj}*岭KZ}x`XKW JAE~f+rE 0|gxj Y^r7' KҰ(^gt%WP1BXMX<:/di[&"kf'Pt^$ 0˽Ի|~ME ,>mu>|XLs05jHC|щ4CfMLAq Ox2/N(0GDehw>@Kyl5z 8f!V iCDS\ETQ~dEFZQjiݭwov t42`Fu{wyO f n"ղ[#2֮FwdcH1jmILLĐ ݶ.tII ~̀]{{viN֥4(Zi,++(R",T #B>?}~Eg 9:X}y;Lg ܫ+i(/w\& Cwb N73<˗)`#+_U̳Xv4~|Kf{s)3*sLTxe݄A`oP4&[iXFg:WͲUWC '5^uإ8u'2^?B<6+ǰUtۭw`n8[}p]: w}]fnbzwIdaF=5}۽fq]@k5/}Vw#mrModb>`xzW~U}+*Į2jf<"fmuObdr& ?"@MzW[\EMBsu#wW"*1cȢᬈ<&r[RtKi ޻ :iX2gB9F2<={}I#+QD|qu2IL'; hE a"U)vJ7 iZfWA˧ݯ33/w '.XYQz{,FΩcLeI d+~g;*یHڴWf$8 tpFt*pe*vQe:"~We4*@Q6G#U.jX sm-0ZP`e^6,^,Y|h̿[+y1ᵊLw1D8/)I)|XtÜ-1hN5@ _=u77 [bBj;7ŵͧoTmMMϦtm]PyA~V:iOz6OdlZqЉg5W{v95>vھ_F bP}oU/w*ɷ;/=I'F2v$ljnMꡂηD:O@ZߣO\+^/#ωniQ=k\ Q8 V[xS*kb؍RV(r~cT+7Db eBƐMu6GhʿmW#k2Xd8$>VVZ4@XK!CVZE.SZ.ܦ8>9?D#׼̿nInay/׍`s74ĥ%% '.PJ+T*݇۫V|K>/k}Yk9;wꉗO*᮪?Ŗmnlo5v0:xkT8XX= mj *Ŀ}蠰*GƳfE(Y$rVdD7%U#8\JW%Ov^#&W,ْqjݰF&*7 UNiZ $"NdX&&lpc52 e2k}Ibn-djƔ&D_8h}nj{67BLU&;-P~Sb8`/UX+1m I|t%ʠ#r*Ȍ>`kٕT}S. [4( 0%O/!jl–[y/[9 _|)yml))s/`o5a|&M:A3\Mh~w ,fU UkkUVjTǎ|ՀAhb5ĝ͓ q]}B{:vO}\Wuߊ+g[<`e**:~ ͣjmv“E#^6P%vU !k6#\c[&h@WT C Q(q0L3䫖_5$‚-$H"4",$jyAS"lك,Z4NQ!pa_dL>^|+T#ALkrxKj!—bcs87–dyZ/A)~>%kD&/:)#Ћ3 y+H { n킄3ʦʃXyOD?AŦJ@+U6ſS_2Woƴm_w UD,u""4sl:Uu,1riTh2}@ ::FsyUF]h <PW+TL0Ppfy.\0C^V`%#hkAH$`eSHV̥I`X̲i2EJj$<8~x׍mI(,Clb/tZ:l3^\VF69\y?EWnzRu(B=@K)E0/  ҂z=҉ǣO}1XR/dCXAH;-iTb e~P_ 3Ed7:_~@)ϑl_꼛N^Ǚ28<gi4W-63E?@Sɕt6VD UzK9jk?JLD%9ω*/!-!WRQ1 لIC~K>e"rnax񭬾8b /[^]EFEt댲/cY x* ! 3=; ڔ@2.*owحm yTN9kftÅ,3[vtІڿVKY;KJ$ecËMwtϮLa<5zSVlߞh! o*l0 uJZܼBbƆ/',bjQLc FҋZ*~sz,|щrDUBnDCf79h42kK? J*Zc-K4z '7W[pYB:Æmh Wksgi'T)g)QdE4R^ DFxdWV#~B5m8)A2xH"|$ Nbx#nWL&Ҕ@QVHRii#^v}5R?O jD 0"蛐ILbK4Mne yVZ^d~PZ-Sh<zx! <)s;YaibJxѤ5SXy2&U\S_EuNn!ŠaQLGl9ޫ.K )2E2KANķůX4$@+>MM-2#u6Fyanwn^Kv+l=pN*_aTp( Q1-=,.H\? 0q3|Ċj=ĥr!v-"F>@ W/TAYp kc9vZ'`S$i t6~SIј諭NQũZyevrJ2a nЈ4!b@$--x1ez#Bۇ[ p&bj7eSƆ(uդH9`s^S#蔜!{&uh^""8[|Rp!zaK=Ͷ;iYDӫ) y4a7XKZn) 8h+^5RjWP8ۯ0MIBPPh<8Y%eQj)7%?l)1;?b[596H`<#X#$˂lp[b SVPR`zz"C 3pF՘)}GG+xaLkV20VTҖhuT}_UlNߔ^_3@;%m/7㡒b_Kw1nPmek;B:9]ql[pѹnίv Nn^ 4G3`cT1c7SI[Ǥ-I-Ix)P3pDXD`{87j?{}NPr~[3v,sq@~~$L(7'}R ƃwr작'ܵ6⮸'/N޳rZ5ž9a?֍m5PWkb 0N$c_O7q xn]]N_ M!6^X}GM*f+QƄϫUj#s'T>EW=Ik#"B pL}HyYgW|\f5]$==B|0x 'r{g@7`5yi ⪅q߸ 뿯'S!Cn9=K޼a/^ATMB;MYstkg mL-3 [̺^{[j!`oޫ#l wotXwH_ך: I:8d&w[8֚vsxp_p[i<} ^jk5ևO)7+/{"4Kά y؟uEX+v(f~Y9Z W0 `+E AUZ?(~X.&ŕE݊y4iVk1ޯa:lѪ/ޅ 0eAw`a@߇I"*F)W.bQ1cLQ<G|d,7( € u~>jiU2  񯴤҆geehaQPb vJ!̉HъG̥~V.FE&6B #E Y ' S ]C4[??Pk׌Κ,6aQsTBSy"L`>kC+L1s b'G鄸Fo⌰G,i巕8di1nS0^`EP/u/Wz*xYw^UY9tva~A#B ^k|>&c,'TV7GGiyvb0U/&쿯_Fh9[E}m$o( "nXZg<^g]s SR9~ɤ\s+Ƿ옦nS\+.5I2.:3 |2uxg߮4?:=%מ~="Y6'6[.A [쓿k,'MF| ki {^lޟ|زr+}+ ba4nԥ#)v-K:u4>6Γ;| 0]O& TFo,Jq8%tk]z߆kq$Yc_9D\V |L٥mcssEy8>U֕9rΑa&l_.0_0g| ̝bb9ħ궁qnϞUll֞z?@`X>e7|ډFR @|s}u_r|$y%J\ A ^p_@׏u3soOG1#L$y*y0;[x~e8eu `u]Aeekh[ q<5(n5l/0Bx*k~᥈|X 2uγx>爗m8 uLH>^>/KVi{<FY~E|%c fŃCՕ.eذkz֚ʊ.EK&m Zݝk^Yǒlʡ` ~y6vxY{XѺWU}tX:5L$ jRnJnhL*2'~Ӓp5w2@QKc[ƺT$\p93=hD;a30_|'D%d0je p/R#H3){||pDGͅvFNG<p^T'P\GE4Vp?>c/2NrKcqNaH@ҌM4ťL!Z#"_E)$A? _BO @S:?:Ҋ$qc%3  30JR5CƭGlݯ׬?Ғ $NH|I[G* $-52"?q e~+f {eWv9}Uӄb.jd xǯ:k23[1|SѥkjGŬYItkH]%KխLqe̵:<*qC>fL u_Bz曌ʺ4"M{@7Hja6$41[ `[75ɒ3w뙉re k b\Fc! NWLż4&3)3Sũj^ҮcZZ/}J!C%ze\&OVQ5%y2ͷB)LB,^b wR/i?wlg`/?~yk w[w} k&ؾ yGax1hpwKyV|)&d_ u)sl7ߪsmrؿoqP~;C_ q+r֭Y  PD ׺B>S!m̷VͲm8a/˷^yp"?C}dB%䫤j &~]g)u WvEbЏmV>Wb sAcu-K+_w~^7r&Ƹ5<_5fջmU #gNR7i5 oOofZ3*L kqBBq_ruԜdRX@8Tk.#%Yq8wÄA,&oSԲ8-H{!a+jwҌT vSW*vR2g n6Dj2!^aԻ=eFk^k/MNܩ-(iC>=OHN蝤:Yu҂dKY'0f9-5"T^d,ĒvvIjpoy!G[.TNnb+<2*o$*4ڑJ~k60/*&fXDoHQ &I!v~v[f4~#-ZѴ3[Y¸kسUXY&ø0v^njlK4;>1SKO'xboa:sc%ၩXp¿J'kIF>?+p=B6%Gql5HvrQu6hZm7v]ȡ0 7fL"l| |y ž\8.:Z<ȢGHM=v):Pڛ=?z*+pX"W.\`;C ,yA|hk{ _!lʧUn e 34eGGY#b+"W7T^Fp 3v(=~v >!9x3?a8:/`0b8k(_WΰaeUk3ugAU {\Z.s_ʗV3um-/;gBРJw})zHZwDž赨=3]9]9B+Ћ+-E]u,J%;N'o;%,4qZDe1ls q\c݇%,9J7aI"vLxu=̅E[YMe\|@6)x֔Y@m_j2Sijl\\ .\Pm_iF07.x]Ӿ_w;Uܻlug_!o9w[n > Tda!C=F5:zOn#V @M|/qFNj ٣og=PoF7P;}g|󖏰l@dߌpp_f Lt*el*~al^~^6tm6 h @ri_HK$7kܶ4- &1tu};ެ Nʶ4- X_^&:'ɫ9WF.JtʛUͫ:j|=Xdړ'g!S&/L,_~iFm2cܫ7]A-φ@wD@fK?C$P(6 +|9̦FWI?~XKx}yP.]%1j OZ&/Vj1ڃ_,*]6D{٦que5gk:=˶d}lSkdqM0dYmf <Mn_Wי ƥ4-I8L/Ϥi|A#-%/n*k׽zG9z~:%ɉX9Mpxp_I~ey {y:L]ִi&ۿI?ѣ582vBjdE!/TTD'v&0c:/eQW[hR v8gKc%r&TT1-{{X(&`%*|9T9VLDdue]-&c*)"9)|äD\j+¤%PN1kZ"L8^üg)_CT@e0$0)|X>SSqL|gh89Zdz$(bxbs7{tl1%@!! ەuŠ2w\6w??xN/qe\kږF|W4NDmV}ʖ^‚)Xo^&׿;ㄙi¡/cI ٴlrrY^Sq#/!IlY$e4Ԫ ]$ž{^ 늤Vc C&q*,1r;"/5x2Ia%K;pxCUOZ3kSCR\`E)Z=a_>( ;T‰:CE BAaL/Cqʐ!aRF _=15)+إ,T]2䄪0ƿb".UDydr!>l3b4 \S-Ma0ŒP=.匇˜po\ʽ<؃I9cx3Ж[vZ7O?_KϢs3;:;`kyE_/nA'uMȲgq[8KbWwY;wO\Λm\6-?} a-Rweŕ*"lKʛ;ߋR'A#T\f{|:XW,,v-![/ZC f~L֩gm?Zo {VBZ,RK7˄WxNkʬHj^bd)LVU ;bK)Kɒ}|`^C08[]@~^5gx -EQjS[ȱZ*aUL2'`-R|pg)=8%n 4l5( usx#:aNKE9_}|ԩ*?" ~I @l5?/+/g\#Ʒ-lbV=3Y>T-_漡[Yo[:O?mW=VktU"-Dg֪UKMEMҷY͢=cTL&Yq#.D=OӰ/Q\558Q~DQצEA'!ȅ}UN%m.RЯ-X4:t/աh,$+kųYm[̘~tkg%U/A0oY>JV6.qIdh8&S{~VW5GJ9NQqE8GJ6Nm)8Pvְ _ts0CҏEgatc2.*UxоTW}!kUX1gLMڭyXo6g29(5yeSmY&- 1ObtitoBJ4ͫ[SBOaBm(nÂms!< wjK*BrF6StYv*=j:~R }RËgU3g[Ҵ(aC6Q/#)Jxb*iS5c٠Q+wb%_Ha=3:Y:kz $SP>Jx%@8gm1B9WY%[?i%!%EIƀarM^)ҕ%VQ)JȨQY ֠7 #?-oȼO Y@kx$$B6Rcn* RLj 4$-vH:$&$,qd#j@6c'@RڴHrx^/xGгEH Ԧ]F?".lѐ 65'X~E\H jtw!F ֔67 uqGܰ n4%"`|o܌M&nqw?2a xEiG#L,,434( @d?3t~zQ+< % Yl*v kК!=i +M9;T<Dr`fHo>qû[l{O^Z taV) \ED/6.0.!p?qBy {sQfҿ;|~.wͯӎMq m|K=x >ܑ3{3C+J[| )ݟL.O I Ȉ-jH-ŗh|o]ܺoU'9KV1k;v]@'2 'jPQEH֎y_P21=ъW6ksŗ;']Ƒ0zh[!20Fd}@8Yx|s,\yp7{]蘔nJ^ڔ1J]vjr\+7 hcbړ`滳=BeU+-#0r. - ;HavMĄ|D1W:·m M{ os˜5/k߉}JL 7xm۞OݰJg^L7{v z~_}؝rGe骕jé% 'v=̡>cmv wzܓ!UY EoDD~q[JuCIDM(J{8\q/m?bѫ ޼xd.l2 ?Y8pG:JC*?/ .#Vk[4"O4c~|9*n|o vRzEZ(/@k?]J6kfqڤ9ص;ǘ3p۾Um^u]7vԎsQ]/+w1NӢbXp~A`y{8p(Įy`{xaYqn 9Cƿ22#~3g9Ao tXꔚ;>)?g+/}c7~r'~ J)J-1S[әyBpbf: CʷֆVg3Bj<]^>XneJ]<0z-HUˆf_:iiizӆßk1;Z]mhyXvwz )GT+A0?ՁYxg/E`w{SttTzD.T{aT6ֿW&j3Sق2*iYvfJ9;\TZi;ՋU3VHx՟yqKjU5ٯ}` bO\}hKʨ DV`m7f5̳9쩄AJ&,&g$`ָ2\}.K{匣7a,PR/~j$SȸLXF"bYi,vXbK @[fmT] GeXVy27$iADO j$#Vg A|d ڪ.cE.uEóZM߻tWV ijwFCj2ix%&`<exˠ~Oc>Y ]]*##dv=MF#,.p4 #YIKq1"],PGArѫ]i j {{ݵRe?jp]W3w|`nb[Ru֩zk UZmc'5czξ4L`T]wꩯ c=@99~M=FMnjݗM~9=[$9ؽ^r})/Bho#̀p5j a6#);~W+s}ݜqCT0eɯBgnlcr)/})7$i~} `}iTj`׫hjexX ,_,L UmZM0:7tg q %a~%Ep%焝op—*[.v_ČxT?XYwte yVW+ӋٛV^e,vT-5?4s>GAO\B_ɍ:f+xضq[^ 12GyD+[5d!rS%Ǝs5ܫXPڕU/|hi ` 9_RYqC˙*WXݥ1=hL#ZXx?ϗRfVs?vO?Iq*2,F`+/s: lz'ۨc"je.5 rlNW5֢0 aYyݕ3ҮZ$K,Fwl^+`QĘ 8a`L`5n85 wa7gUZ$K`9+"8((us\gY90gi&*¾$bifxog zy_|xG'ha"r4\O}5Өe$[onl $| }.O9CT@Hߪ$Q{&;ERBq&^Që͎+NR$5 )I%̞BdC2JP7x&E+ lz/ 'Tʢ()JpazG͐VҬ֯Mǖw۪~ 7uNC:,BYz1-\FtC;5nnq vV|k"ٶ=vʤNODTFрһ&` 5FPsWnNMȲ17iּ0ZM[XYS#o`;(Y(wY\QFIp"/FEA,FQ},(Rz@UvN|lNUi~OZi@Ow+9+H!3*:RB;t$um=4bK֣}frV@ JC}Ѯ5HSi4 V}-,-.-(b'5ѲG13;M+Xrv^ĠmDz2*袦BIyC5rsԽ_c=T _bTtrwgUn1d%3t)UjUM@{ KDz: "R3W[j;6lIG bmn#K$wيWl4OmM>:`hȠ9M;W&%ˠR8&% r=2aa0ɷk'Od$Vݕq~=XJLb49*[0q0X1clr6v6~i.ehn{ה)K8(丼BaI,ZnS~~ mzkrҐ('"k!Qii_^w>&oQس=h9[u+jcf>*[A . <1o hXC2y;Vvzvk%v.DLKt0l|!&wN?kۋBtoi Fg$PO?'-=\~Nޫ$oY5k\u6lM$Vkvsl{?߱A?5(M?Ïb\/-Jӥz+̞oБzM]Ke, 际8Omq!noҘ`)dmƸ;YR炥cztkͪftz[ozyEf|Q-=?jUz{]f :QV}>f_3ٷkg8'~vjgdJ54ܐFJO&Hee*V6U{jkqf8^Xy#iBTFQWYi_7:+ܤdNY)]itP: 5q _CdxqV5(W`⮆&QCi8/%?;ݱ:퇌0||aTjy_/J]Z{ck eظ{\Eq*uƔcI0P돆"S050ǬzpPԬ.mu1t˥6Bcؠ[ݖ2=II<ۇpԢ8`gcgu.⒜ 0?Zh*d˕1nXҀas }{zk{BDFMcFtv%,=Ek;?\ba1}C/WlTF33L˘LIO @26=`F/h ERCK/*<107[Οl+\q ȣAᬅ0Tha*Lqj>[}4 XTq(q9-X%).X4- +%[٥KRU|&ͼL4u bd! Oށ#jy_^مQZ*M8st$~zJn<:aiQ_% O{ix"оȤkPB L(œ)$u0mi!.lk n7%1Ov&0ی]luRALz%rHTSڥQQT)EzD;vHWTDY@ کwC̺Xv07B &LSʈmLs9/jĐ5*w!cvkEmB2e \>~{cWtf-w0%1L""" /MS4E"/BZy(r#Jmf}g4+5 #=ޖ+Іlp{ʺu\젷 vפ"qPOBLg](@tQŦ+R`ł9[S|_MX< @;_FQ禩!Ҽ$= ,`Ѱ,WcyZVhEʥW7 X,-pƎKN X/^\tâ,G \^b Rr){@F@;! i`PD^set3 }߱WJ W Vb.,;Z0  pEtrdd~haǴ7k~xeOR+,}Zq<ȀA@ *ZK4~ϟ#*`*cW iҀ`DQggF,7g=WMXMS 9n__x|l\Ymzt2[=kT1OjGt=bӜ!Pp"=yVKtg'$n䉫C@@W7~N*~r@ g Ul)Kg^p/wHlkc;o:chMVUǞ+zq̢lmX.Xq-Oz^k\b~fVl͂>x ' pfόi‣Å1_JV>xZS5Eҽ6<@"X1r&&P T4סS]Ylμcw?om;zgA07mhkv=:b^74|ו;*۾|0 w7+Ak}ė&*Zv U]`bS"KkIjd[JELd(p|5E+CKt2Mt~bkg}ODRCs`ޯ ~;%^D ˵S=Pjlk @@&:8$G|6w܃H0 5 cv( h40Vv JnU ؐ4~[fiqB[m. Wj 8`F bDѕCgW||$)`@ Sf~4*<\X)PbX! 1wG+e% uD},]Z/B\VRV}eeAě :jG#QFKoy[ρ!`ݢ0|s4c"TCw; גEUziudN` @\ 2()q@ziW~/'ːӧ0MxPbAYBJV폘/Ųʄ쌥]E+N ۙ?J;DiΝG"ae7{3mNsZUN*B4Z:;J?0`E;0# `] KZ >cfP vT+/TR+KcI,6(vuH#P~nΌ<[ ԙsA*9w mG~L@ ϼ*Ig^ Kz@pNobk;Z&\f0L"oZ/Ig/kfzA+h?Ыmpw#w9r3F5@ZGUw +>M^kBl_*_ 8M)f%APk{F1{Fꁷ;Y\\g@Vbgً+R:ł}~fN2Ei4rN ڻgm9Ce{wtm3޹+w~ƌPt q@  rล@g"0& \o9?P lc+JŅGhڵryu۵tHkʭkñ.>bd߹cp#2RNwy9.7ZEﶿ.9a۠o[Q ` @7a z%ȃoލsrcp)r_S_ː[5[>C>{:mT:&f<?&> n7Wp蛮{dmEh2䛤$vh@VjpGXRQhoog8r;o42@@ewȇWwhp+_kY-ϊbOkRk:}lo6'hwYnXbe([,7'eՎbc]LfCɗqf rOʑ'Y o)DJl¢\fq&s^b: g w߶A~#qX㶬d}/(˔)~T8ޯSWp@0h~9&!ɑwYj~O=q ٦4-00,mN[L6YCRZ~9%N1ҲVLqk^?,Q_|0aG%9h%tY%rCf_Z ?DonRd5\+]GkT\ݗZ6(7;1!_1wi-jDo,$1*q[D4hf)Hn$q Cp-fCr$CҰ2?pΘɃ7˃џ JUp?CD%՗TT*,w;)|I}`Ԧx]&S!ϔ';? Iu9G=k^rUH;CMi{uy+V Ғp/%1$fIsʂEG{ّBZhֱy(Steϩ;f~>F$c $Q3PjWA\ MRĜb>J+}advڰ˷q̮]0Di<̟Oƛcok$?ؐiH}MR i{kʋy>`cא}+ݣ* iUj3@~ψ  2ʕ`<3-==7%?7ͥT~ΞcN1r{y٫ųh76۷nW8}Fqd HJ..zZòDJ%ߑ{:F*чO'c+}20$t';^Ѡ_3KDUTH*鞢pp^GDt̙+"E[U'7*G%UV} Ʊ: vkO9y$CIp&s09#\)c1 bs??krL{bŵb}l zl!rcdw7KdS)b,#:Bݖn-cQkڻs?%^y_輄kIʩ aIYB}b:vW]%GO.b !)S9_}tC#$;T%fIg%g,'n?g@ rlx^a4d=7# =A(w^$ʂwYԝjrɨ u~ݔ(FD6fЖ^@ =mޤQ1a-5=hIvTW?$A b)RP]NR7Ү5`gD;( MR=IOɏ))Rdq!ս|ȁw4K簐0L{86UqlB 8G240*m\xRaѮ[-/' Fު E=_#dOr`h{yT8͍Z KbVJٱh$2PR}yJČc^q>hHԥ:,2Dt<&n=ݰUpkCI]6Bcԕjvſ|;1:~#u8ʓGLuh)vQa/ޝs#*8C?%7ц|P#Ml}y1G:kD` I@5^>|q$jmlXsfwĸ=A" u!F.+ ŰsyH6a*Xd̨')Y -NrJ[׏[6Jx>Zf ? -^UI'M]~؁IImÚSZSu=> `I" =_/6T6E+Zk>w[|ENݶ#‡]}?־F}WSRv23yME_vV6 jŭKn6!l%Ha|j$'}L z{Q7 }jSO0cl0H^ r4s%"o=mmv   5"#v`+Ll= M4*iJO}jeML"{m.C)=D(tnG.d- ;@hqMi((a'Pk= V'T*E>o^^^Xld+/ YvU"θAUܕUs~~vzYbzN6gD&-m%WYQSIϡFlƗFW!E M'ɹn.nP?&̄d9:^)+ܽ2c]q %s.wA#IDyM!$1oniS2ywkS;^5午ř1jz1F.j0w9jT mF>?`䞕2!Uͨ .߯Uv N ?V\Yn |.* R1-'Ho b^Y1].dl't9~ 9վcqYp.9q+jjǓ(`U)Nms6ozv6O.guZ$k`Yq[7t%rEvh_1, Bc丼Ogs'ʋ|+cHt0/W=u?p*t]V0F/۹*&Lzlim鵊Z8ۍ_nO2)%̐|PУ8'to}y"^OS)?jYZ.:̦>b@Ox~I Xh̙(;˶OA?VwГ'뢑_>'ߡn-} CtOSތ'&(*L׃Ɲvy6,tKwMxD[b(Opǖ.4(žVovv+x4`@ω~M3VRfQSL4ϴb" @ҧL`*6r:]Zp1a>L$MܘqTHv 1.ˌWul|I\thM{"7b%:r fLLaFG1Wp,TrH0h<@u[8s873)P5f0I:欚 6O@hΆVӬÁ"/i1@67Mᘚ=MHDh: jיs aS+ `a3 2Zsً/evՈʀu f>*0WX>2EͼtQQt§Ohvf3Rj8k NCJ`D7Xk3g^(GqT_,BA-;t*#E<f*U{G,ב+?uokqSFB[a rTde^uC&S-YTÊYo"Q-SV-5zYOhchwfM;>Bt l ='Jy;``kGDd{{B\ ]l[YtzN~J!\ƫVƶd#BYR9 B, h2Vc j"Lf*F VsDv=&cqhSS{S7FF5RǏnz8k jD,u mQjpU<)" 춹jh{*%k!6TAplLQda -qrjYyeqb֚啓9̩F-5Nyr$D}-q$T*,WXk-h"ζT~- n*]=u-ӟ"G&glƹHR !L*?Z11*2SiM9h~hbNDOLu CCF2)Z( ]kL BqRi'jq٥t D̷9E T.z-V@Z~n+I.d_jBP&X;U'Ԗ4dN`|2UYc'( b"f}JoJ)b33aa2Q0 \}a=E]QXl枭5ȧ`jyk#η! ^ ,蒫W;~?ؾ&ׂ&3*KNc֛#kzK{"!vo~(FDU\ф{mLZEb(G|Ӟ)1ja=[AM9`"Ď5HҽgAdKR;VYX.M8_B7ZBTRCwnk Я#NBT2 s+ŀ+Lh~ԓ GIoج_ݿr~ p8*6f]H|C*"녫کj^.KU2!HSFC~u /erզ̸B VJfhq?Co٘vڿ#iBz_;ȓ€]z*ݫS)YY[QttAVjM1&Jq^93vοMq4u ZvIiS`ҧ{#;_6DRM4uR\ր*_@Ѧp| S>DqS{_ԓ\+`9:5CZ7*`'(lڃ324_vDs_\VlHJIXR-VߪUl;nwmwۻwmZ@Fh fv^vPL6|^F04Mr! L2N1S (#Co֠A>_8 f 箟/s8^161)* CRJBPu@&HUIQu"\*ԔJ?߮k=!ohכ,+8})U0dK6g'^J@A sڻIh^obt`LڭɅ9MRfC8zB8svv3_P;-S=9(o '#P%s˯ew܀bHݽiLHunZl-+)*np,Pl'&N:OMlZ뼥(M2\ D-NU)oRCjL!ك'G{8O:T-{tv^FLIb'_5*;UZk{)0uR(؉+؞h骕NZ&Y=kބsIX:fX4pdd+np4v*pk9}-YcWy[Ƀ\I&P'Ft8pt>T4j]^FH~eD4D+s5$RRtW8ΒWz)Λ䋙?;Δa35rGM(s#G?u3CDXBAKm&j(N3ˉ8iHΕlyU cB (|16ϲ.C5(IF ˞[XkUBU"^JQ~^X wY5_` d&}f4ZsUk}Zj5`[Qׄl%攟}ՙT4lQDn@ (M2 xC7ɒ0 S*.rݵQRyDBI a*ʰTv5}gu4L^R"-+)+Dn&ꆿ0U?ˆjAB+Qk Dy,\=*@# ? aJ_u "Mn+eԭPzt˒8F'Nы@/E&m\f /BʌZE)3h?U4ꔓ&Ik EB/7Y Yte>k@*ZaU3V*'YGJq@'Ou3=8tF@瓣{ \ >2w:qhi <stL̡+ y,DŽK[](Hf$)UvՕ $#am^jK:"=R[斖j{ٌ̇7U+1x6xkͫ@&PB{%+[7 Jns"t{.m~bL6/폵:1.-GbJhvinz|ab~5H(C2K /eĴtU!=7eDtm%Ξ # Acqm?R8Nޛ(CfҨ~%5 X#Ea!!]xk۰T5Gk(.@Z(_>T$0J/ UpI_~eg\eLj=_1[- #H輍^x Uz5Ni^6pUnqzZOtdd9m !p[Z:^"_)[昅V]p=sq^9x$,y+Zy\GwmOT[cSa[P*7) G#dž#ܢ&/;X9@_I/}с\oԇz-2vリЛ`ODx> +Ij%ߔ}F:_{Vp^βg5wY)V\VLD_ך]>]:o'aQ2B/M+BmWNYA-*vE#> z4T. ,TU8QZ;*>mm:48 8:rfu3H,աhb`eG'L0C6PE0ɖ RPz2\w;2-1SkORk5٩&V&F H"Pe _'LCPwK}aӢvRFu5iKW96מcǓ3\E_@ _~ؒW u욈clu 9ׯ)-"VRgwG&Xuv0]r:s 7[9KHF؝|{?Mq-M-شޤ zQt٠S7Eɔq4Eu9gPf-'TN%5{+P"elRw' ?7ȫz,X2vPHv,I&>< [Xg?eńE073Ꙫ-4Sů_C"&]4,֦?CumasV.J@D)L=l`g]s_P+HxbHeEby0|EuR _ +*C.j/$/о)ZZM%=FM:򩒼0+. ר ywg ӹ}Q ή|ZT~I/rLX3{/+p".xˆ'h8?s.zګHJ#eaa}.Aخ{jlӞFK3-vdjB~a5 \AILHUJ>ӿCF b42U5Wp dJ!d!演-s(z~P8[ GΓS˙LIJt}"BEM^``a*f `⊬̨թqAZTN.,MS+<-ۭmyiwFhFuw_z+7, 0%IڑcI5Kc-7Y,Xbw}-+('@VI9JM%t@h ]Y{w~ݼ[fj9M9s4LV[2,F)I F//2 5^^R1],mng:c@uN lcx=C9szR~epfo%/1TzRN,+a BWHĤ=B0J_w`i;A,F r]uhM(lB'Ԁ; pa zLJ3(Kh$oۀ5߰BbUa:VGFtAem<YGa}E|% @B"'*ƿwюCyVba9.@y6 UAKvFC17cV\逪mQEp5 re31n9ˋh R/Y-lgC*2.ˡ^IV;uoxQ5'"Pӳgp8R]c~%exIHOG{) (4!1?Y+(_h$M d ڰ*F@,%Y|@>hXd7H3 ZC~-a GǴ̋?Iu)̛# ##+U5"ҟn9I(7-Ma!^_XJ^&aiˆgj#5lNfNŘR% A5$Nde AK{沈 Ǖ%ex*ČX:`h̿CK#$_*? ⦔_Vx}! *׉)o=1ť]Jy򫌈N|g+:n:?oZS{܈s-фD'qP2A{sEKruvmCj;k۬p;ūvg9nemlؕ{%vUknO+vO>; ]=7o~u_XK@3=>]!y=5_k֙ <ĿjEBۛ 'cs#0=W=igΤ U08t 3^CsѝX"G!ln15Om66\"f(# E/V5 by`IL1UXd0~5S#Whv>WY4C7s^ga [ūc_fMBC=8o)ünv,ɀ 9~5'+ gmhgp8ڬ<'uʆˬKhVD;m{);slG򎯩v2?:>d:*ӶZr6o/q<`lsl{ \ğVy=PԆ< -F:蹆j0_iqXcµA~<喧3h;11[ea!kbOjv'|s筨j3h RQQFÆád|EXzg 7W$ A%ΫM(Ɗ6 {LXz&Iワ|P`x1'EẋodMqV:y+68+[itR4XʆC"\ƔPrr=I1^^20KޭuzC3jk, NVqr 7KU#ᔗx/,w:E.a̻Sӓ{j}:]7wCmUt`Y,*oi1,a:_j5!x55F0[nV. k"Xqʞ۵lk}fck|R܅Ͼ ]=Ц c{6 ɦ+茎cB]\R JcY`u^^ Ը: SxIw' j{/w|E{xN_&N <-n{ؾUISr6gO;fI;E.7T=x%LwAaZD [fk[Q"BaM #Y`ﰿlRexfSC:G{cҘ,oœ-KIsXc"s˥`>udA#k# Ԯ&(Ũ!$/ -m <;KqX`% _6/Z C*]u.hWLƶ/(_6v}^6:1o؅]aͦ0>0XԖRl _iox2:RPU8+ .[Y;V[r`Yޑ/_J.l+!4e;pR߶~aUYye;լ+.gFOB+"΅7ADW{kg"߹-nY  ¼]-re7;?qkD7+""vg-=iWd1Jk͇E=c`VZ9Qi\-"1XGsv-8 "1C䔒f뷟|%,p^֞c%Tfh ^>ӹIurWO&BX_U:ə`.th[j9 Č;<#oZ7W_!ޏ6EZy6*tVwPW6Gᅭ1T (BD-Rv+qk֌4F*; WyAXIBk\~ XI5gQm(լj\&δ@;ag/9"g:cLhjOJ۸ r7dcu%X !ESK~E|B_3(U6ʡ^5thbfԂ]T]Wd^WWNᮿQ6KI|doC-R|يD(BDG?ʒe)>irfWtYa9tY>TMNTtB.j@#9zu6t̻vA *h[y!wX[0ȴ>\î?~ *BJ1;߽U҉8Þĭ/1/c(XF93U_- p\ 6xa[,=|R*t ~gIbJ&%"1Aeja|4o!-6aUjPynOyv^B9xhμw$b/T;|ˈ٣ WV_ֻ]$JϜyġ?@<Ջ YroH]`j'iY1^aHA 0Fͮ0b3˳q{igzXa`Ԟh㹱q{ۜM4d+ B1g6Y[K(:tOwӐ.D;]SVgZݖT7s;X;w/z"a/]uиBkAu1"ĩL@65rK-ސw#o\%C.b՝};bzIwR*t>$OΎc̿+cauHgD#} ?M W2 4A_V,RZhS%pŚ/[ 24R9f:ծxVXCXqg/0/l9vU<;m#x5݊bYdTIQ"~y󗪇E.x~^բNHMY尡.ǒײAy^-^=/bZ(Z3JF gBXt!*QTwP>.g8|kWɟyK۴{PխQ>sn>p@;k?DR; ϮBJPԆ< 6u싞F) kh3>WK;^ӗnx6ã~4>J@̌_ϼlKl_+T1=QگP~f c <XjjѿH [Gzb1a)È% ŋ,)'  1i>{+qW;¼q|Iy4k,Qu G{ 5( m0oKn8>faA15\_f&B1[e|f&Ûi,Q5~=_8pȤm&-*2ٍ ۖW˙ eZ"?ZIW>baCs~k,‘~ya:TuCNvd;/1xJh4 bt1d}O#:*kxgcsUv}?I3F-[{{+ZNv $Y7~_gu1@D ~o] a;܎rhͣ=Z骸kb-/v"kbd V3BسѲ-W3fz |~\uDT呣1py 5Pؕ!^oaU_;+!_":|oň*_coFY˗HL "r ;@G70N*5Lf=Ux{L&Z1@| pQ[~iXFb=+\?` Ԙs˯?b YYQJ%H;IBȮ4D'Юy50L(XA Iiũ?L5k6^%D pU9ƏO aN*y` El8T./1Ϙ842\O߉:+W&aFfQoZ 8W@_|#v n:;4 p7Q=L:<(Hw_qb͏^뾌xiL>ȵ+h0X ˪ f?~70{y9)Bt72bߠ̧o:Co桛T]0Vj' jjDWHnHQC ڭs?80=G<O:O?\ŲcBƾID9մU{L&?t.ō&jA9<jS 6n2gONg,3/1/ zh/g1Xꐊχ # Giֹ aqJ` ФއP?Qm,6Sq [{a<:ϒRWsnH2csQ0+#sƁ8H +i8{^n:,Dq>z!8x@1@\\ aOz7aQVAc8Q#NE0Lx-2ȤU Xz D'60dn%q}*ɬ(͈X# n_iߵ4_óRe6j ƇX,ᅵ˗P |f,t.pB!Ś:FGz\7fMf4q1:`wP1o=xt0Pɰ3 Ѣh3Afc<6"M*y{(3 53\3f{afIGbc9c| afF]۟jD'Q63 0&0. ` ,x [03̞/{a'afxD\325 00R\V~f%a2c2n 3?Æiȗlc af؅a"0sX9oYýbT}fk߼odӱ;Sc q2s4#pPoSbA&u'a@$J2A*i%d, ֊@!,KL 5jH{[kkշvmmۤ 343VsT{襁V;BZ`K h"(PρAÒ05E_PmXaæ(42 ~#BT3fU@>ܳٗ'{VrG&IHf SIE, Ӆ4])d MTM(@\ھAי.3I %-: vKםїEg>ogvsKrRTcq"(mm'OCcLrk4fch2_E;"@![\s2eurB="(mi8?d!i#c5l|֔HFٙ)L?~OQsc!;J OT$x14ra)1)ᨬ1}Pe//c*!m&HwȐ?ڌ.{BY*b{ P3cя1_q"qq : O&ћI1a^rA .:AvҗgLvLr7ub~ٚ(y^'d6V'W;aѱNa-zVg WY\Wil+o%K#Иhg{1x cŀҰ9gwRW;Yװa X'z!>c+asգaokday籖YmGvˣ7;`J&T!BNEq>4Ko!%37{Q&\oyecWME1HvAŗ.YeE2TST.AaBM!1i}5o=:n' ,F[;IQ׀XSIwoyLqsg.d*lJ4o6ï"q yϞ;J[z2]䋰Γu=tWkUrYf*X F VehzDma=Lsthۣwc%KgrfVz*Tl/#1cV#+^'vm2I\Z:JT`o5΃dz4]4C!9 GnyȋI-|wI?WrC7Փa7S f_5r.4~,[ [ d 8&=|bkqTbPHi 2 j]}¾8rk^xЪ"h̍s_tUEC#Rh?&# K4vhwU5_iMKaKWX# G4tvjѩh"& ISaZւ#L"W4~gs'C`@ 2FncG$ @Pg@DVI+Iu` G{b0===JGǝGg5ׇǃHG~~0_+Z9 0~vPQ/("pK xv웴`;~bHd zl"{cǵ69t"ȴ^d9>4;sv20˨ -_F5 Unf`B(]w{J+.i.i42%5*+AT{jVQaAS"7`'}[.Ԝ֌oT{!'牻Wl0ЈuUʺȕ:*939~,Wle1ň"[[wgRO5#?K ŠhuMcQjOvԻlo$N ɠDdQ&jX<?r^<21}2qnhX( OtTz0k^#׺+ol@**>k,.8kkn{u~8WP1Ձt, y5pV-TBzZh?AK{pP9 SEM?Sgz#OԸ$L?hgRcPp3#LJ? H9"z LX'7Y a)o6bts;kCZjGEw=/?1X>OWKM7?/ȟ+z1.>C >OI[?_T1TGa4B cUZ]h޶U `eU[Q޲ΉJT 7vVZ1Oj[BLeVgY /Ub8> }_Wi(O1Z`]q4JDUpL9P;VGJutpޱ(!Y[kuĵQkSk % -wZuR'+ 9G36YEun{"[T,mV%RXAZ/=}p3)`wW.r ֨M'o7t3DJDQ?R *y8-" QRќ%M$8`\$! Giw$zIL"H@Ɓg(.(U,bx>+5W}D̶##35_ wksNii(M E$'%BHDÉr8s) K!~K( )um}o{f.Fhu{zֻt14ZJIbYwZeܘKx3Y%O\6l[kEq6`Y?!u% PEC" x*BI74#eEVݝmfmFI %[H+!D!PB">qA" VWO+POXAĞG,'?0=bd|K~5=~nӧ k5g=F3 u9:OG;| -?h]rf1٢zSǩ֜'AXKRyu']?lv$#Aez/DA_)L`8eʮE"˛|+ǟǟw_CɅӑąVyۍ \|K $˸_[Gtv˹T.rßhmL̓B82s?moB .kݼh>c/'{KfTM=xq v2] 㻉s^{)P_F]PIPV_\ss'0{*_jI;G 6s=GX˗o#?N,oگclg,/zW}G?ȜT` ?}o@BFDyN{y}P.9^Hj/zG殼ZW>&^{y&\=W yDb9wJ (0N8|3s0DҦC0 `_Tva9!&2< $DfP')!`(0s hZ'5JN (*PK\>: C0D DYb:dž0@0` Fa`0 0` ywX6]DC.'NA#ylGq)xb-!FN $L@I኉êIDDIt Ki6&`Z䩢"¯_Iq]Z$3 'tH&OdV'}+RR&1p otb=Uh5HFQ0 a ?GB" | ?R.FaE֟Se="J0NILN 9fƞxZI. /6!ڈԭc<hgqq .w&40=1؍ws1Ǘ eg\#fn}iwzlS\_kFTCTu4b`%XX:]dޝ`:N$G~ ^qHEtGy'?'bd`hebeq6]R0exh^ٓxdlv-Ń=fl-0f'+gG)C\Nʌg`&f{YhФ)#sc|j7ՠS-gM]2B 9==$|r ̅Pñ?+%}r4Ű$ o$C.ԒRdfΌx75B3F4lƵ3wpdshA}J`N_U_#4&I8+Sf9Bg;a>%)H!S>' Fh_־շM˴vy,q0ba!0'}d|$Jfa6E?<#OM1Ժ,,vqAZiKprfyG#It#/JzhB٤)'`Ї(t6L+oŚ V3W;M*1#Ǚ٢d ^[+<:3x6Αuwe ) ^XL(?.L`6܂Tc߿ʫ=U_I Xs꾳?M|nF/쌫b43CڐGe{D!m ^slL2xa<}Lfz8xlU{HC{cB]{[~502HHD( K"Vyh5Èg$?;DLv :B/\ȩ6hH-Ш$?U4J!oVvmLc_l* S:₿lC*JJ FtGZZ"pM94t4nc+*FaJQHyoħf4hYE^';F@K :cَ~'츠P.k j*ф!&T~1\e֦{h!{>Y7/kݟ*޿j*yooIk~GB7*}}W8$7i0|hm3'cN/‘j~$ڿk~`Vm=TUR*y Md^\v-Hq{UZSFwtį hj6XXsif8@=3׆Ifƺ%)*ߏ=eozm2冗) >=.jU-` ċ jO9DЀNKbXC1wsGPY2\=!ADX;N{"l|ٵ# N.<]>B:1^$mgf$XuJԬ-ѾR3!XKȰxUh4'|m),s+KwUt M|j~tg|[% #y \0O`]IERW"񀺐m|{|@T~qik9C kxUm-ǜ GZ6=N xЕ$AМF|9`*0 `,ʛ+iD/!N003%M O3\ +kx[<[-oiQA[qnw)C\p\@]RAX]&Yr8Y+r.@^Rit(ә3ن$]8pRA_$%ݤyA*x? aC#/l͇ V%OEC Pf7L"pzIW>S4ӢK[&j.ʳ;0[Bit)3I+`gW●l>ߖ-r)5;}E'>6VjSBsͱ0%`,cz)UA7XIKl4(M=-%/5ߵwݲ %U4H͝k_SUȜE7AnR e ƍ  `Zqy--q#̈0'Z-ZzQƺ% !'oвvU@mɥ{(g8 - ǎSUyF5tUe-^l,i̴AI\@ P9{r)L־V{әFALdh .(0R@_ۚmu2H)Ҍ4 ? Xl]-8T GSM_2QCl_4稡ZtpxkHhQNBhlӃUyh )D+C'(g.>C|U* UP ll<]1$$0W ;E Jv΢4bx(B$J⥉@(!NzEb۸豻+FvYEl5gA '-_mk˶nkAuHy\NSUۈxO4m;שSxv [&j/.8qV(KZ6:eђu@M4pnfDh!e8 eIU=k&19FKNG5 cA,:ޤ7 ^ÓU 爀M[)'u.WExz66S hIA}e^ hS - /^C( 4d`!fW`M |z9hUo]lk''lFԮzmm}]PԀ ݍ$}A]rbx?HtjZ˕ `=VJu1و6lHL\=CuU%w#+D\?mf>B"ոARmeZycG4>ՖNSI4'WC^A^ldBx2$x?Z;5L35bP~xؖksh>VF I Π3B%FGUe #5q2y^3V[ވ#.&H0M;ًbKFW#6'"a v-Qf-YAz;Mmп6?p]5`R? mma+8.Xi@S.PZ5S0Fr\<S7z-C& ̉a#/牃b3ڵ򿓯,59׷;P/P)?sOX% }by.x}=^}ͪəΓؚͯ'pqy3x`fWjWabcR@dT??4 *5O jqすOJbEg5f0!OA'' ELܛSm`d*7:T4 Lzkrw]6ǜ+ pp[O! NdB?\=Sԩ`q.mFN~t!oRJ[ u%-IV^չSsZ<&N!|D(B'?9= SU!jBzI'=;x/MHW##1G!o x1Hc3SRqߞwO0<0샗##qR0nd8p$!Ut1B¸"VBFe$T,Iƹ3ATOrsYvˁxHt/H@ 9R߇ }^ F?5MI`sטE+t130[ކYw)oԗk:>f9e}V2qu)_|E$Өqɔi©*+n^*ED@M6x92f4ċ J 3RUGLx2IR1"l)2_?M&H2D--32QV::aVhLYˆICfΆ|h?۪-}ՁeO+ ۛC Nշw_^\aP }9:uC`&>qm롷0mdG<`=y~ׄKœOW$GEteE+`<Ϝ GD><# \O& W|8+Ye:^=]([=!OFĆTMCXM<|k·_—["7Y FWaDq%^VU2ZƑp#,<I1Qmdp"Nq/z lc JOԄAs%!4ӱ#NAqJo@q0mdOlb;mcz=#{&5hp̢\Rx%~>f78, h1O_ 95yL_4;F|ȵH%`8 @[<͖$IUh;{ʃ,OG^CHBX{h94[4g3Fpj`13$#T$+D$a@ّJ6dz?xXLĚ6bi7uC_PMt8:g_I\3ܭ㶸Z_o~Ov$2hpH4ĕb|p!)6r:B v!1$j^)a'' KMdlf ֌?bm80@r`RA:Mv} zm46 =?@̒,.إhl4`)3 +ë.R$FwcIvg"E'`@[" >L7'‡dYLzO_,g›I Pi=_[@{*6qkUy<ױks^=P/r +!q.p民м 0kDZz / f(GϪz(P+e3! E~rs ` AD ׌1_O6G\t{hp[ghTAjNmE;u{]d b W*ްAXfK%~g'nܠU9%qYZn~u*E?l%1 4cnP`|r[$ݽZ|/p/Ҽ ]'hb= Q$=U]:UDAn.<;aӼg'_~Q4hbzUNֺ*_UK g# ̅<PJ^/M/-pUX}y*cx nܓӅ 늳ae&暖3p yeLWߥ3-_>} |^ By*@jyQ>8Ef_dq2*8^?Qj"ߞ>'ExjP=??y&^"H !B9InNByIB*>Y] JΌ<#Rǚ9*UIhLH'_$؝5T  / ^9ȤTBI9R:rLM<胭'Ɖ&cؼ2%ԗN)Q`J Dd!/ Ŷ{R{  %2hD$HTuQdO[! :\|x!2G嘗Q:PydFJN!)}詇=,$MOĵ㲜0`#{oZJ&+!(Q` 0[Pc`0(p¡0``x0 8EȀ`=|P@ S"4"pg_$┏v?p0m נFQ3 4F3HUxvnuwUmmwgwݶ+Dhd ۇǂ$ƛZ B@eQFE!/za"7"n NrH @x qN`{MOWia2+/_pپ>?~PukoJo?C51fCz1_[}>#>Kwx=_q@ʾbr|ye-\}۹oDZP1\amYq` l(ډ!,/ߤ9e%wAkVg'Cf;Ϡ_+m]W3fRc=ÖA=E&L,@m+TԦ^xi`FIٷ߿X l:r WNj̓BWK;`. zu EF(&h>Y> 'xqliaSA|!0cX7ٺ c[fwS% LP5w^۫l u?9t)l6IJڰشCVdcPI)o>ߵW(SQGxzӟ-3MRhvt:1D.3M@lJ(͑~UF)gEsCO*'%~\2?U7ތY(Ea!TUзP{Y=t4JI=Zɵ(tclBOvldO>VywyϜh'%\gs_  XD|{i(c%s#vCYsJGQoxO `b,@#+=o`@sKdK&9efɬYgSP8IJRؑ~˦@q+:ߒ 1 ('9 8SP2&$ߔĢɎIPx&77&jbˏ^xxW(X(K Oj<18) 21Ҭ; 'vg³ЈΌ8'P7ijZؼ'~RӦO(c) |\d3%x< n4F%"`Ct ڨ^^eA_2SU3~eD/kL5۫-/S+ff\olwaE@@la'(xBIQPxN8` ~Aġo ޖ0Z։ I@"b~#"_]ho?[Ϲ:54STHv͖ۖ%C) SK4xg<$!%'-='POu?|{HztcWiUM?(Y0o#Iu[`WGq!~*Y' }Qat3 2TT(.uD{TmYAs!I!O82m))8Ty+Dy\'-1KcC?:r.dnlO]+%Y'b> NL<J7=L"޹J'+ ^o,ڲnM5I _PrMRGŌNl)RI.Ipqt\_yA6 PwApry:B7i"9'*<Ý@B'YIMjd-q je(v!Gwwx{7գ=괹MF Q '?C)G%@!8”a:S.'8 G)Π8',0;vNӪP;Cz':ˉ~A^8%'Z Nŗ*8Z&@܈Y|b׬ [Ws =^[mS~aR7w8B`cZ˃t(ֆ.({8Ʌ0N1.{R[?.Rm~,_JϵVfzS&dz185wrBpHAEUK<q'Q\R^ʍsjvyó:*f% 10֒dM wm5b^j0XEݝy0 *_X=w!Qx !`T$H8hJ.N-GYm͜2!J {Ȥwe(9 ''G>&͢ZkdMꪤ 2/}/--]MpLCٗuUr:Ϛ:h6|i#1=(YJ=+OJAH!^&⅙G޳2'#M^7? v:XHrnSy%s s|ڽvrZR$kڤJpTUH/7ɚI9Nr; +9%rZX&:i;SHEfL;JSOը72Z@(ژ0ÀB*L`(uCʐ/%|>.%foT R ﰠ<`ga1H΅*[YjUFBUnYCEG1[oN~ͨՠ96a֛cZ<:Ey{Fu^[hp݋yQa x Tv>_I0P'Rd/oHgn{W.jK\:^i^!JA <<4.LR'gUzUՕٻzNawSf,pRQ=׹ -$!H!42C$=r٧lI?4 1%DHϧ  } 4zPvώG^\&xZU<kSVotYOwrqu,9̩6|_g2Auk+漝cIEN$ a;3!'']4b(&!&@}vLQ 0Te/AG&?DM3x7o>?ugյ,յ*oM*-w:stsE&:?q!ヹ&%Cp ot_|}|=ҍdi?!8I|WϤ(MH0Q ./wB)t2d qKEY}O4]̵ ([n ݳ68q֣ZzkA:NU'T: ݜ Tmo2(ԧC1LPi 1ĆOQ?jpޥup|MB!^\Y['}l1d8LVm([<r'&R ʾܭba2jU&!"V(@yQEo]"P ђ&-Q k?ލ"S`!?p$FNOO0= 'wеjg.OggSf,`|ejUMj3qofuy6G mP'0m_xTo+v*3Ծց"B CCE g+Aެ{AއBH6(ң`jxSYW]z.[zd+=Υuƺ\U/A35[ϟq<>U]͂ʯ+E @@AH׌q Ƀ)!_Uٜe C3}~ kX+c;~Qa>Sm0{8?+`Bm.VC$vnqS׶:jml\hWW{:mzjm*/N;D-Qn "`t@\N!C_ xhp!j=A#(howkR´+v'oAWXsHwcugtWzmİo\3,ٛS=ދv݆ʌŸ>[%5o|kׅ.QMHG73NN MHibcyvIy G![K4۝׬M^h| )Gd49|d`yWGv뺥^oc%7 6@CP1çF|P4  t;|PbXa BMΊQΑZfcR3c)/57224,ɕ~sdYpt P!}r~p G9\bXx^cv\mWb?"[nuĆcn ({AO%w`V]06-+gpzY^J^88-o4xMhÃVBpP,˻ݽȝ2-rYQ&@( d(1QF'8i4hԄ ^L;_ԂLw;ruØ|[mgnge,>v_ qHu}۾qҏC'D?^bdcA`X!85yV_U7+Ưap{5 |K@ziwnߦP ΁@}UO% .25Kj6XfRF:ܴ2"L10t/v!dȖ;%G & C!,J!d">F BC!'7x!ːB0IJ)C!yX䌬 !CydH2`Mp 2 C!C|^p=.0?d2ǜq)_k%܀iG~IGHjES_MZV&呖2r[!;V'W t]1]vCn/uKʅNWksrwMmpH+1%51kŝ)pY)a6qYEɟmb•).&D%4x\2fH0OQ̗F .a~Nt{Ù.?J (zF|Bw:M;bc&g;Џf}M4$f2>ǐYj&1W.-4%P<ÜD5/Y6qnCLLU4cߛ3:\]\fJ:E$G肘e/=LWBMkFx2x]L}\ݓyd UH! A_ʉYL[d&1_E{[d솆i FLP(PeB㧄ј+Emsl'+bd zt\H!mrAfOR$:TK?g *GiVcSCJ@&򦘵ۥ|իbO/9fژޢ$ {TZNIftb9'-d4ȃ; T_ΧbAū0)n\bGJzD'L';DYĠ3+'|bCi+e GKe=Iyq" Ш!W@O˂UbtPBUJ^MFEH&]gDWIړҢdpU3('*c wNMdIA=&n3cSȘx`EGI9gp9ެ\u,;J'*;>NM& ;7]:THϣ!cl\V)=k`HVć䢲{!܂2eQl'wĹBUȭ-"OZkc_J]REP$B]XEh%짦h :YIH#ȧUm^ٲ`טA)C# ꄬ't@g@&.$K1@ \Òϔ"BiO/Q_c<=^)JWJ̔T,VMձ'VXTx  L7PGnT˙L1 =,̄!S1 Ԟܼٓc;8ŖJ d[eֆ wQ$BQKhWYKpA]ƾ39)[ x+@PJ^7P RWhd(:!K7Gfڑ/KH l91 ,R J" <&g"ʡ Be`cxH02m`֞zZFձu㾼wZߦ=pWܘn@jk6Sc/;a~לnof Ϗ5&-G%iw 2ĩ86j"d-FO @K8h(Rʈ$Յm5ճ\pu]3ouQ9]WKubJ+sH?}^wK |a"L=c7j3ڹ@$mO an vWU;EKj<|*}O vQã+)Hv*FSV OlP<)(ZwcM- ;5Xex)Z .Oҳ S΋#+*.xQfZ`i.뙤8/ɸxtn0WI 2Īћ̬\Rܯ$޸^iV@c L bRaaQF=lX'1P vRS,-j%7,o^<ΤphwW MOI.ʂ:H_z ߡ0M~n(|`z 2M|0o; Ջߣ{ )O ;XQ/QOagyZ"8wI+eF;1@\$ ^UI;*n̓0A2n0 /U|JLFXo; իVvQvwnaDYFց`@TD[}6fa"*dyZyRc\E+leQͥyI߉CI2&4$M۷;<ϊ>_ 0󈍾w[}1gF_nofwyNzr<9F0h8U@ǽkl:.0D yrj>?O $_-y 1C2JyU8]с%f[{*ORJIURrT( k= U(n6/WngGC`p,e˄KZBaȨqSLXL@~& 6,T^Lݜ<^L}5lVw.yj{legk6; bp@>6Ri *f,o@1٦zoْ-lw}d4uqXjRX) Ct`j\.ͧ)[+O6 5x2wy\QN/x12 R Ez+P }-I*K."uTDq kc΍vgI3ai"|&|8&Af-'-Li2'3FtdD}ȥ@m+^a]O8x?[?_=8jbpL(xzWAO%{(`SiMmͼ7yg^Vlb|=(j6$ )Xz 5<<ɚe#}nez (XXH_&EjR:H&;,v%XGc ,lTHUuCL|EN'+] /h' R,gQc&,3/̙+\!9’Dh٘<L D,xRuû%f襰>3 ۿAa.P jK毹&OSyqM"-{[7_[W ,f@Ĉw|C@#_,Ŷ_KBcJ) ͢;"OrĸƦhXv6;^4I9dY`88g~Տ{y-ELyٱXZ`1@ 21AWbeAu{ nI4{K艵g]j=O{o|i8 #B<8L8"Z#)8K%1q?3LѤ=Lxp =cg>yωJY,iag Y Pj!\(ʂ(%_%pk&ؠ y[f "?,L׮U@EYOT1`Ħ(<"t^@t&8JD x : niw-@2w`RKeDLy_-[=?m_ߕp\!ApEbNM/65γ]cz0nj"*+pkdJa&qimJ" (\ /a>R*0ɘXst#^A"3TR,- * oX .θ=B`u# {JD B|$I LAKܹ3Q-k+,mXQ,߈V <<T_<.M;-T{#adE2xɳN晙GVyD'Y H5@]5 +uQx{`JkEFgvCF D['[{(4LanA-YГ\'j,fW2&U<@E 0ER$O](bq7o_*='EX/F;j x+#\Q͹(d*/ߕιNn>*M7]rJD 9\G.Z[][: V?^a,fp[CeOd"@=R_[-J FU,"+5y $ $+vleDY(#]/#-N,bn% aDOX2̏->*.TǶ9`K@J%k.0UhrEw}Vn\C [2 <\iR' Gg)"JjHyoWg_h1QJ<7אZFsǓYO$ 2K]A$l6J4/רOHʈ``BT®Ra}7>js- >a=gBɍOO,e,L*'#6@hX 8 0q(d9̿J_><_%+%=,ݹ "'aI:C^9倵VQ ]ˁS#0bQ1hG^ȴnoK?КO)A0IdߘT@/!#<IpٽЦdISrޠ&ӝgs4 ydGuYTMVŪGċ*6깥@AvwRP,cwrVĒ2'ж&=e"q]?!0#)&t`uV+E=tY.酗O: 1Z ^]L l\WqDynWp= P=G>Ji=Cipuf;>{.7oXSYEӌ}ȍrJKecd`Y>z.cʦe1*1TJPSP`(LAK疒"MJ/]R95SJf,h*D(|_:.JfImAȕ7d:dtc?q_Cg"֏o51c){/;m٭nY?o02dw 6=^f6:]5@ 6S>^J3>Nx}ߟ7nnhԘ2d`6}>{Mn֙k5'1s%c [ ug_ ė+m ';ݜpu›z?_fqT P\}"(|K hm0#0L:'?-oOcH3Sj !ȉ_]Mً~X2bO`ʰ #1a9ez?G'QWbRpL(cݫϞ>v%9\.-I/=7}#fܣfhPٴR_b9}0cXoqǑnk=QӺ[^4F.ZZ #+ ?繋G_bA&3Sl{Tc e^:(h+ PdS#Ok{zJ\t<4y_(RЁ=ҋݏv]G?y.}軹D?\ X1rO29 ONE%C!p;R ȇ C  q4"WXG #FF`|#:u,CV Yve(uZ{U2kmE4pg̔}Þ)@BK.J)[ ~oxԒ_ֈX))SqR/(+"8(+lcj\6s۶[2-}K#Ld"r ʽ~ Y=j]Ixt:eWmUWX No_ |NΕvx* )Jш9H4w/%=uЕ+2DڔABδ5k8i Z7 WB dG+)Rp t\-ȶ=>(\ 5!Ҧ$cpJKk_}\6(0@BL=Yo>(MKkLqC9œ]}i.s5nÛشl3OuABAr 0fP 2WQl._#%>8qz%}:ϳD.rϚlI /$Q#'#ԟ'Ǻ>'$Otwc9Դ־p$i/';KI׏FaI.r{U(Q)6"lDQ!Ikd6jIHCpiYr! ZH1VTs*؏TI[H<>oa''ftV$K/ '$ ]D\Vy'a X h,b+1ǜ"/Dߊ d.^UvA`vb;j#of?X3?.#͗dحFNz^:;"4,bH+XlxcL %p^I44({Ӕ.]揚rٜ_y 3dkn( v*qa.hT?8 n3%2`DgL24f4pΔ(!ԀBBfZ㡰4wB Cv1G1o&9+V@ YxBAd$+Dam~.CV[߽tcEP\,|ؑdZ$EfZa c-=9_JE"N@i{G$S)l,` IM8?̵6,Gy q4}'!uҟ KߦCΣz/ <^Q/ab&][։@l RB խZA1!U"q!F ~d|N{2P><Bnbn>Ac7tO=8⦥޿r'H]7͹\%"'LG0=v.ʁіZPYթ :fXHn-T4)>`~=KI=_SDg}=|wɩj>A{R(f73j0ng]2#m+$Ϭ ]5"Y0!79d͎SG &eǾp&@d)yxN2]rCo`{Uck1UP?NY6=I2R24o!!^ߣ*TQ=H#b誼t䊉e6Ejƚ#BT;,uE2$5iYM׽'EɨE!4 蟾S v iRU钊:"lqàۢ Ϡ â$鍞ֳ.TYl"tl)9gGH=`tbMU{rΌظQ2 :MviK*e@E~ym*d:utw-|hMNX1v5Pʛe4Ynx|\{m2p_wSyG.b{<]-PT[;%mA5Uz-U>s9Hhdu(OIFƼI,6"YWy@QoDؕ:VmlqW,)Av5.Mϼ{읎4kT# ~[Òi.l~ ˟sHx֙B>&]QfGf%~{ Qml,쓖sri45E;H30$uR0Fz{j۩65)QҿOe+w}uaqW$m)5KLJ|h:&߈(HNdTDa+NSh >"?9Axܺ>DLld8J,gPTo!ը9Ԏ=xӨ^4v#a0(.'L}?H Odhcug/e2Q2  Zc!^|6†Vm|`;JGz*[2ĸs*sH H@9T5O$#J+A6!fAw.#uG@'EYIMDC hBF2|+ѥ 4Wd8GI9ِ|AJ@G)^TdaphIJ.CV֚(vي[_#`L~TCuhPyV[9W>0.(E 3G0x}K;7*RnxzͲ@OP2H6Ŀ\ M+#Wt4:×L##$ őD7q?]sÒ#GY+{ɶYYubHl]XD/>>5Ya\'n?R;[U{"+aߑўJ*!rW0|FBS8aX$&nI i}'T;NH\-{i]%qR:)TIr>҅T>g1FdHl$vnοEM Զ=Gx<*Qy]N+h;DFSC⓬#v>9pLV'+Tv=Y[vh Foص:5AzIWA$ƖuFdK{C ާ ,EeSQ;@tCm#ǢxM n2$4d`EKDt;AB@˷DD>J1ξIL̟fIv(Y=u{u0{޺;bҤw%Ϥk;j6:u--,Q".46{^oAQ7VSWB #Θx#BHww~wm:ʑL%mWK $ 1 qixxEWXxbTcԿ/~JuvXo:2T|#"GL-Q:.4EۦxL྿Q4UIeh >bZv]Ih6wjIEoOV[N|̇j-y?+f V#%q3/Q[c!sD"_'`Nơ]#ҤM4z} }e;f槢mNcO}LŢ>N7$T$ܡIzƍFIߐ\Šl {OBN#Bjm~JgSz/c%_4sԦ$FeyaS/uyCKdntRGBiGEDFӌС8oi0C|8B'IV!tqխbvDJ'cBI96X(S_IOvi{D%3:Y}bDAQNwhQ!)liPP4Á~A?9:#J?L??x>4@> fgi@-{j)j>2`PB@;΁)T>D& 5AB%k!|nS_F ܒ#ian7;E;!]H^?r% B'4]vՌ};eF@;Oxir|pFghaoݸЖĒR"kqcÒrh=IZ>t~Bw1=r۾p(=V&s.f ?E0k;oؿrWwE|#=p6]/nŜm$;sikҍt/qr򣈤hM0<k@p5ρ1Z Ki]Ր{ro>/QTsė&Ys\TXt u﬷⿄6K&kZQK�7̐@݆~$,Sxb{>~͕p_t2%>4mG:bf.]8,iXJmU}cS C"_BWEhť7P&0-7 AbFj`te{ }*uz9~ŀK\B[-CoI8C|ݾp6T.Zoc >QdKpv[ =5{ռaw(O;NM$4vB[{~|XKM E2Na1~ Q#4c O~Λ  6 tufm9se$Ht9w3"x./֭c7B8$bM%1ЗC~bmr01NARu'Jp:2]L%Z^ILlbaFH1HLNz nZW 9jʛi1NzL $QrR ],4X$rop(A,@0u +|`A y04u!` pH H@ HRW СAgDU'B #/ؑoϬo|l[ \ŞE8">\/"0#YޘGDnQx]?G\#JOln ! y8 kؿ#"F?wZk+W;]h+H>Ͳ%&#bk+|nK[9LECQnꛖRQ9TGsRF$[QƇJMV>sqQaw}hre+i~G#R"0H"V &h ewc5ђF B_G:9&@6I~$+{<G^ QD H Q%R0b,>pG?9U<#9V +}N>j,EXؘR/$FڼUSQ֛wDDdY~-sfa\7iOq~P&)2-c!&Y+'=&IL"=q_;Cϔ-ɕL]&(DNEGپrH*1#Βk.2{qq"398OP-3g]dwjר!zN-#P"4rsTҢT"4z.pobϙ +rM/1ꮻVDږZϜhԌP z[Ds~ӶȟgXj<]pbrj;i=T(0!!@cD*:S%yz;iI0DmWA˒or:gb㌱VD\HJ,mj$ pXFw&EFPtTc \ ]ƈ6ۖwnü5_BJϰ^^a 2]DyH#_JE,ZI*?XWO~QK!.4QMN"*e؏86!TOURHs5JНƐ8DG\{BÀ+18X!樸guvH{GpRq&}0SZq-%}-ݛ~\?cV@аK!$+7|9 2@KMȉXFJ$IݏǗQG8m"RM+ZVZbHRdPV"IMF|}@h b!xdT#N/Άft-*Z?MxMEHnLqj KF4Z|OcbTRIIgPQ<#X"RRj8x8uYMfEu Rӑs$K槜l 0VL c:IJ=!:&czݜ]'T\/ww$흒SJBY)Ub4ڐɟŶ8x1"S~da"F檞yOx2t\ j.FmZVrr#$4.ȣh39_mRb5&]MT>I/n<}Ξ HrRy?{zMOUWbT-6o O{YmԶ`t~?a=&>g~NϺַ=߷} ,XhvHP@Fn.FqD@^mi7J]=q$] Mi# t5R$aQϸ^ *׷5XYB|ġ'vrah`[,EƱv8`8Ro>0JZfk}os=e9G=qUrtTQ(#3S{աHŚ\Ea*}Cw#Qpgu&b='MCh#ԙ9^(5XamChymQ^n t3}4gJqQ0k]},ѕ-6DgYV`M?G6Z hWEDާ><|PZy$qO _ϗ5,U %Yhk7͏*>[V<2m `;Ɲ@pD'JTa.^.(P+8ә}#n_Tv j&U4zgږs/qõ$1'壢Y"̇Zj6QEM,-l}$]0LAYMG sG,Y0 XFR!AeM||Ϸ, 4iy=gn@2 yilcd#'vH"c *jF 8 oé`J ^^\\-sݲy^\t`==jEt@Wx'K,8b@cXjŢosu}:‹OK#5D z{rҬ6/$۔$D!ռo6,Ji"\Q/LdS%޿S`}RMc%*1m(*wjz%aߥ2~4{molk\vswL,;t̳fB c #v7SgKJR;Dm +TX;FH+Mt+=%Otk^t,zHPfZVX߷X=SU&-8b:3!juo־9 -mk60dYiB葱6N>bPs.$s' }$f hS SVǺ|䗔qtMĹ&~S`o.5o$D)'u֐(>*?X.$/]eI» uFG(TA"!v}V  ,0#/3- )~XHjG(D K N{EVΌO_o(Asb6g]hs7P[-_ˀN߀Z|+S,\VdThmbѢ\qP`5fWc CwRZʦ4԰YJ~}|BEԲV"t\P ]T~fӄHsut8`}%Qr_|cX#5LOk5-Q $Q>hTPZ#IԫvOk`[qpzI @ 6L J#Kԉ9A|+ob%zrî5+XYbȅ0R^7ms2vs&zs7x?>d-9|A+ҳ8'^cpC'UCZ+f1g.AY1ݓi-*"i8r="chn=0Ǘ5VpO\4n#csL$Ek~B{d;(ce_0o{dJ>u(hÈ e]%,TPo1>'2I99iqXD4v.73H~}D=<#l%LۿpaN.iT5 s Is|>*UTuT7'ǀ~ k^0'."Ye?gSs-HКOJCtu kt'V)@-Jv:ǧDIm;fը5qBՑ "Ъ /xo*%4E"T =fUJ}Ѷ'je5Α1Uje/E vÌ!Tk ]i rE}kP\(R a"p=aʇ2Gj\,(D^M΀-XRψ?GA`'~h6tT­AiWʧ#VUdKrp[A]ՊрĤ Q& 1fE [ GXtzOu <P=xZ(`.|2.ĥ>K(Ť5ݓ2Q2K/Ҝ;̈́xN_ p!)#qǒ2*eҎ-èa( AJkES*7;IZ+zQ?74V!͈lS oSI={JыW/WW5pZ20@6ʜuk(la:YR@εAqĥɠ5WN}tMl_jU|A)n.7`ܹ8]8~2P1k'<'Ը~,<S]/En8s3sE]ѓ/j}G2FR9K!ma`GE! )OB;Z*@ i;-=ۍ?@{z]OWS'_{lkyL]pi?07gf;'ف|=v@ʦaYӳ[(>ytɺ<灞x/[^C۾@5W‗eUs}eȵkwy}l+.,Bߎ0NVŴW6&Y?/8 .,,W_u˘-,hB@ymkmnk:v'l/͇;p=oOSՈvbf2rytd[+ZlA}7DoAi897L97@&1M߸O7W88zppVY=I=w3nAMp_jkz۾soQ5LiSuK@'X)S ^]uIcl;;~ٿ=o0G>2;O npk:Hl0K}STSUҧChycCwMF;gn{Y[,k,d>pnboc2Z\ڭYLN 7i&ͅܪ|]_/D ,OOLSK&aD_NPO2O0!Hڄ֟>}]_$}OI+ү?Nd)}9-s0N:}e/ӗanRx&(>WSyB؅r‘$'әڜ/u]~O% ЈD&HHTr q/۠}^N=rMuA"=Wxf0!I80s'T!>H$eẴ_lm:<ۤLY&YsKTlL}5rD#(u$B]HB>6 byPLfj=FWy3lx9#dy8y㾫3)s9~>8 xb{wfs+s1qXVWˌi-jçF#w2 @埜e;a2r*@ # ?ˮQA~_B R~cSL pͣ @yX{[@ t"% @{vd@P(+&"W>׃_p@ 4{'Z@&/t4i1%0\} eP@k ^z@MKRa%^ @W"U`UWK";U< %Ԍܛ+@6S lN@ Cp  @ @ @ @h @2A@D JϜ3v n!8)D*PFGH$#; *UL);_s61t'`=; @uc #&  O@ $BPFm&{<p` ` x *K(++[fw^3fFp~&)gl++Dc8xq%Rp'uR]X={Xmi]&)1ì+A7s!E1qs7۴s#{~ʯL=c݅'[|ЪEBN'a|z2U:uҘ`l<4xDl\^ %g* I9`J2}8Ɖ*N0J'] d`̟v0SuvX ßX-`]6=M;:R 6j+ ;75W\utw-P:+\6{@+Յk H^yn+|wσg$a,Ki^G3TR)GaML&ZC<\gh马+n͎|Ѭȶtlyhdt [VUKdy!*έS~տ׎]ΛTm1g&& S);f­?g.̻T?T#ks\O{m??IKuWa8"۔pgkW+uWtW|xKl0^?.! &4&ۦE `. Vsu>)tuЉ,o>EFD)KoVtҫ00FQjZl0S,M4nWkmߟ5ZoyLLܪ]XY`^`4~6{g_Y Щ@ n4s%"ocݶ;qwvmؾxMʔE@ ZRRmƪQ|fzQ%V|_Z@m"8!du}Qw 8U.i[lA3"qx'LddchTB$=`),u__6٘n9͖"#N1R1xQƻk)ƥ_E|ss| y^NwelYn){IiLQce1|o&v۝ya`!UWîhd}sۘ@+;t>-g8B签R%qMg.!h.Xr+J2+Vѭ KCkL&Mw\4s;ZUֶ;*X5 B5/_L^8gjVGųt@fK qmbYU3B+ʰǭ;΋:3(}UG{ưݙ ``ѥ)/_x pzd ׺'ceQ]$o٦'].lڨSbqC` f_&|)Y5z$X?%E.哏 ${黿')%ߩ)ث%UQW,& zNDY9_"uc¼ާ<-n[#m"gY)ϫT0˜Zz0K4yh3jwA.&x/3&'lW5&t2+˅f| &i˪}gzUk~kcp|s % Æ\hbOc\,_`HL3) )/қ^[B!9Nc 0F\WE"䑪 1:KlvO+ôWEm)$ R}BOvM`9_ኸ#am>rHjQ$mK镥యY{9DI)Aw(-`L1_tռkc@/J8<]6rab8& d!7'lwv PlJ.`d .H7LLv*rbWjmfֳIbfc!d.5DhqEf`0v敵ӾŞh)DEK j re,Ὣc>oj-ƄSKqyK|gl AQO.կ뿽WH R\fO(pp%qKzdJ {zO¶D]62|q&sQWfp AHVZ|܎qKƉ$(coRȵ36@c+]a\ם|I6dpaw= b{m}&} =f=[Uo~_O^4[(E%Qo*%<2%EgQ#§T֕jMс/f62Tѓ-Ԭ`OR*lOkZݨz\_n//$umɛMe5xI[WprfTuy>7tv-1JYgKƪ7TM0R L05;dm?_2A*i`;ow {[fF1n82"7C9}\_6l\|@ W țWDIn^v{ɮ,<=z#><|?zzBol w=v MEqx9KgV)/mdxb,zwM{l{0O.WIG1"QT)ѠHUCsk =pe["&-8"bmѯyYk#F4bʛKWANdدv;c0j{<=96?|f5s y}%ʣ37 3/b4{W֞<?[JgE`uʑuFůoRWT,F$BYqzŅYxF]!"r@[>8l0Ϯf),0L>&r&b/h= _=Y cRT=/dd#UrU+WjduK,oQԂ=@CrM-[,ރK'MnC89' ڃulaвp)!cs"pH3ˆk9^Q7~\<=0_a-o~>+\-6Wݪ6%>*=o6 KK,-4b5 q|?7$J9Y|ve+ RH{cteMwY^FΞ zv.6,=ۦA;Q|oGEfL=̣^BJؓŰG5vZMha [K/-{ U0+J~/?Î? jr9BIv=2ͻM4 hA0˘ű7M`Io6F57g̃nޕ/}s8ܧLiX|2g+9rX,~m"X[w‰c`Yi{|{KFܻnrvYYטrg! 1}KOəL=Nd'oHtK ?oŝ.gY!~Pa2|=k,^ 5l.Oƙcju1RZS1l<9+^ 0 4s:D bN ;-I9LCKMGW*\Z>]HvCiWY`Hx'z4g1h`z0L ١N<,ԃ(=|:iS1@$]EDS*DeSi/P"pj=-oJӻ|0 Dp1R)Y|s`I P( `N۷{"N)09fAoHC)Y|90 ԣע"M  ϶J/@)~r{TV 5l6õr1a|Z&-5?sgM` OBU' <`!48S :q3wwGaw;Ll\k*f(< tnCvf6HBh` Gx#jBSv巽Cܨ9zxU`A+/yۨdct9& 'yk7/UpGQ|jZJK㬪l}^f֪[ Cf<,ÀYpX]̄y^qgd\ѿ%i@0X\tRU,iMgp#vW&A$Ae|Ȇq~Wj^aȎ}^eeyp]bwKPFŤf{E,OKs\Y*YNn n6UBOQUf,)ʪRDD%[-E ۣmm{xVBe{9 3rx4p{BXkvfQD"B! ;"p3B}?qĦ5f*|8ϼe/y,_L+hI#ׂGԴSwd-_q@~~ꚅ~#UG?/7~+a>+j&;OPN贕 E?N+u' QbNq "p-b}[$걇Ì 29v7cݦM y!jr ,NVr~0!{}׈^ R\WF3AYIwc(/=U=viLk ٜmPj? v|tbcQ9\3Ӄ6섷v\C]K|bSɩ /T+.j鸼! rԐ 0VrW=! v/lޏ0@2fm{;`K׳3~r5.?a]rrsoT_e_o/:- p0hz`lMQ &?! 2uoR(sm8Soa& L3a|YӃFM'X0Z/g7S1ܓjQxƋ =/O9ŮFzðyIO=+.{^;"nqUtnՕ-NQFW7$#tf"]%f~;߰j'mts%1̱h N׻ ?oaG+xx=ec/+B`DYQǂ琑e/O |42f3v Ys?lt1_XXEv+(&f#$ KGRh@:g,2Gv*2}yErf60.]`_,"y*'bEw')VK4SQqr4~&tmЛGw7\*lW|snϥqP,~Z=J'"2-u, ~ֿU)a!p/QNЦ3_ ?t|R7E^m=Dm9|xas٬8$ *pR'@67U)@ojyBt~7ICwdFY̜:xs4Ica-RDŽGo|`ْ>vyIjO/.:Z Wa g+=ǎi/2xQaHj4zmD~>Oo&68OU-&sD "hsnPoX v3TQkYd-_`pL `^v%@aRIyKmV;OT_!wH`֤3&%L/IxMD CEcL̜T𔕇0x*3,jd-r!\G`G tC]6µqd"$ْX]̯OXS6 œij:e(Õ4lyZ*>149⷏s sTOՇ1Qu''2ŭ)|tZ OA/! '#}&{"EGVW0Ou>[#W|籩lRz>O3V q@$T! &$c k|6Pb4Ut{6]A`b97$$^9=Ax֯xNUc8qu>[;oD2aUҪh2QLt3e]-b ٜu~>Lls{D]0ʯn7<_dYY}I$vy^.=]c:k\)t86﶑2ʞ0UMspq<-t=컦0 yG`%S2sI"`Zw/A` l ׍=XI"󃚟8u$IEM(&eFa]C.ڽNVklU&^5*%rA^A$nQ0&uo>}q@k!@ 8+(i@a!{39Wa*gԵ] S_ّ>ϳJ#rE7{'M֙+8ʝ {PA46xmh}kq{r|oۓbj,T)%^+Lvh١0m(@q@Vg;Ε0 !Zd&4yyVۑ!={q 畹t|b \=Gs}*QRo&TZ.U>keb,_[WQL֖*{Ё&zIIYҷ;|r9טu0pS?Emsm_kbOt%z+~ZS tZ t:Y=Uq:͝\I:}`U ~}?\TbkNڞYU}y\ vZ5,ʺ&Gc F{ ٥0>j~ka;٘Lz^CQK+L(>Z//u8֬{mT,[V➮MHVӨ7HQ x;\Hu}%Zr\+ Dv}^Xnwį{Uz_Hvƣ\ :rUn Zrt_5.qkstzB"\UˮphmQ /k"H>VvՕ&Xloyqr!yTjץ~V٬Y)-e6FXX+_5WAy=b4ET6z+mb4" d!]\;5dFw:]n>|;ԃFΝ$&{HE̾Е!{l5:po"SuDАUޖ i%h,%c;xFyq]c0!El a(LƉ;R <`}<*/;OG(4W[:D_ڦjpWptm{\`*VЛ"d)g%{AK/%RS⋽W$<%v[g}zw+w\ONUӥ!R u ˴AFio۞2 ߝ `[9Gebg}F`PWno2{{͂]xO4>NbC7%MGةQRXY,SXvq_ɊcÊkaF?]ٞ)kY Id&#+FRvƳk әݾ7Lȟ&;q:uQKG.vyǿfڪ׺)I*\y"qǹC}jU0)]q9ci@޸WD`TT"W~\e||ɉIҖeJТFC4yy8%Ǥ^1miښ# NTV Q\9bOd%j*PpkAs,WIߡ{ 44UA@e5$+ vU$N">=goQcժTߐ&nRo\.vR0'>Y(O4뿜3?U,=SuPyQ 9^}PL M 6q3gNq9R_="HR$'Kͧe3=CksP'4E?3h0RaVs=m9EAPm^K?yK+Lޙ R }l `N.ԎVA/zN@,Y^[rth8GJ4'~ǖPp*ͼwdĻn!0e_ YVH&Cx?>P9{hAG+ނpQNpMV C w*p,Xv֢ j|kD0yb;䴸/0 &. $9}TWTב7C!a{vm/b1dROa!"t)EB.! V@mGOu@ 4"P^ۻ{vnllxd!D˶[BI @`ȲBd,X!sGm.]nww?dl\MhH# R@D 7$=yԃ)4Hi2rv%l;7%S*0%!3UVƓ˕41\&bH$ cjic_зfb)ODlÑEtj{|zqM 7 @Gq/m. 9Q8X FwvM[Faw+> {B(yC =q ?BwHL`&08~;d'лaFȠk`ӅQm. 8Q8`~y|D(7RR!y26%H s 0`L3o6馒i væ?p`zahmҨӬ3g1km1f bm#Uf*+ŹKsϏmHvH22t=>8&WeH,kG:᎗kMrK7S]}F7I6J 锛Ll&xߞ Zgjq)o(em=5Lj˹ʭhʿeΖ^6MvrRROlukR)K}t [z6ċ'kSF.=`&tn2N!)⊵Ab2dbbff )S-t`*r=/m63) ޣzMt\6n(bS,C7 2z BN$#6 rV MYgjibQM>ml e5k'y66aP-.IIX`g)c@%y=g,\R%Smh4SEo`3˗>f%<-)NFP~bo`R+hlk16?H1!]J.+ž0%d+|в~$ƴ._r+\

xɅ*bJRibj`x vConӦ? {/u^߳Z u}iZSn/+;/8zyiSx uMjw][nvmњq֚Cg,P8,wsP_"_\ ~>K=ݑ߫]o;l_o*[(1Z*Kk)\giSsO}:wNDHTīCLx{Nг!vUc@wo?maem13٩(i22i3/.1ծ;E6Y?p{eN 4zv}ko3?uZբSX?KhhȬęڧnͽPO|kɴGb̖ z侀-zOqO3QlS>cԦst:>Gr`i;W{{, Do n4c%"Ro-ՋR045%RED? cr C8;},HW)7WM3SM S1(TH u?ѽ%KG|DD`H.Ik͝@=_IBݭuYsf ^B߀}a"#@·7?z-qС ! @cCy EQ^?JtݝgtļC9viupW_;ss7D092J2Zw^ƓBgW8ݰg#coo9B|Rh F֎L'W̾4H0{ď#{ҘbGaIV:ҹR`f$6ͰOc[I~?K^2/T]ٱBɠuH;115|Bz/;Z CPi![uyt#$g|&(J59D-VxՐU7茾un`D ]#vc˸@h.6E7V:P2|$AmuLX18>k9`M(ԥE LF㥂1R9Un]7˥h[4ʝuԐ"*#tL4anGk6zxƽ cX49[_+;>TSI/M~t*4?߮x䍯e>ӨZ锿KJ++VQ-iR}# v2ssOc~WrLW!k?`џJ|^Z('F~.6{8Ծ3R4~tӗDkXu~gΆ23e5D/O`K;(S%qdS;ɖd9 r>S7!g`}a`bS4Mޥrl@l0dpE0(oo$KmYE(QT"^ Vm db!ū 6LI^Dʣt8YFƟ5 n6БRRct}zɺy2kS TWXtb5Q9U3F3u5aV0G*7l p&OhYc'Y1- >-;vmeȖ5-y%zRQf\4S:=2G?bLR0NoDͷ5ک*w}uxg#3c`%߳twӇR:Jڄ8ϴsQ!&Oo|:9@5=:*)''_Lq툖ۡV| ` 9yɑ^߸k Bm q£FcNMy%w߫تU.[kkizziT"uKU+W:WH8r7!< ΕǛN>U)퓜jz5nɰ9!?g7tu9;C^)aO, G&}v,+5~j}쪠8umdtG ]*]V[{mo)4D}H^&-',s+LGqg~ePLvow]Mw>&.#/+ lڍ;;ib^^v-֭>p޹&淧pë}%/Zvչbam~HI[['_(-e܇g|`ǶQބqExnBq ryWhhx^*GfgWVqaU=ϪNSlzl6Z䞚g }R[ F<>Afm]?lA<]`XE1l;lV^]w-װ`GhKhEq( 8J쌢zΫ⻀ L`pv:fX#oYvRk_>r²aم|O zdDԥ<5_6f0Ms=cLڵ<̿[űm{P>Ta?VGf=pȑF0H5Sc h+ +/\^` :XJVҹR_Vl8_J2WN\T/ğa5,u3oEUJjZ>XVO$Y92smr_V{`!Ғ: ?_\D#` S fa0}; *Ce4-fˊ ]0-cxukבTo_SrҭT  Leb>1גrF=W<'L*[KjH*gN`NNqv fCu{HN:jo)Nj u8T2eG¥3*w̏Vָ"$B|VK_t n=Y!` B n34&2`_EP_ cmβYe,Id^$K[YoJ^Էym{Lv^ɌƆlTrPz?z{?[i{b,&I;' 7ޥ dMk(NT*tP L(a8 %/s Ux+ADP *vswYymMƲnVc,[Rp$4(1CP+*1``X >a Pn[_sn_eh)rُ? žI SAH󈜋zLȱZ9ke?:;ܵ8UЉ%߰M!-9}$ %xnǩC5U}׶q~6BjN.irQ@xqu@TVAZHk"."}KG<&u}_FNmQnMlC4,"0<\k: *bby ˝ԨT|VZ8~!qΐ!U9X-[g[,/keEeYD(|>@HmҠX`ݾ̟9cq~=GQ'3ZsqsZYBIh_q&pŏn7_3=4º|+ʛU9YE@ Og';6]e8'8,"<0苹V (fvY ]4ͮ2cjZ ˺&ˌxi憬7~&?|M/ȿ͂Ec,$\O6XE(оOMc2b#`XWVzv)*z2."rci;k]74( x=2hg%/yٺ= "È,0f]Z45"`eRѱ2NR!/xxwkD:GWaB=f:yzGE!Bn߻-G9] &K>w7J5:vc>ww0wzlbVE@{ʕ]Wo33U{r\KJV-kj;?}O> FLs>rw=ĔrvKEEWz{9I-nq}mm v%",i)iYj23F14)aTQggjv0{ 0t9mEcIkF^K"OG#Vb6lMOY8t*$WU}^:ӫy[Xn>-ҳ-8@H߭J8TOI ./1~g)3^;rnbo)l""&53 h0'f(<=_ a/wtOLn aYJ[W"P?'Pҫj7|jJU SK]/W].yrx,V3NKg]c\1VɊ`Ŏ8f2_G&<7-XW ZԢj(c}Y1ÇqW5mcm~߯/hU9!|嵻lBVbj2.)*6FR*bqXӻȟh5Xw;]_zK8$>}VuYNnhL:lz^z|W:pif[ C6ԕX}4&je]D"S3/3b蕼?a?*ok@ =tg^iz{jw?Bv b?t]]G})7vPҧ,x3{J Ԗ匉b]BOe m6&Cf0<{TPW)>t\lx+lkj++"{NcaZhFj2."@-]EB2ifx*QM;s#` LfK fEJfk͔u s9׻ȼ:N ;\e2D"X/TM)>2`Y?aQ֏Q=> f2DvJ!Z-V ?\ 7Y[G}#V`QOLO\D +u-]@*/"MuHf XiCR LVhi4Sv4zۉ;5:*&Ѹ։;FjrgBQ(kѮ0c0Pf;`QSJ@Be]DL8Ènhj: .|``u)+؀e= ^DUY#ֽlSD2Pȹo2 au<FXK%^嬾dqZ}g ]ce r SS2?Qe=zT{x^ c`!2 @!)z,<"RYa5P ^s~zabEIMϓ+/l ~l)I#; .Kn+zDh^00>24(Mbp<BA3=q\fRD\ R HIP(!A!@l!uy3G[LHۅgB,RX?B[" dc"&CJi5tkd1E4PLE3lQ(>K*. 02"X/GY sZE$gdc`5>PaPT{>*R=`U,0׃Pw%mj8e1YT=M:SKjXwp9T6}+u_'/u'tYӱ4OLxcŠ,%}!Sj&ˑ$v )w:mi2"!dï\L/hID 4/rsg̀[=XpԒiDZ]l?H{j(`[J>a8r7-|rED\U};- u&[|%ړJs;)@eR)IIvK<|b7T9禋I%j@,$)4dndJ?kI `HSw5LDȱ30%K^i=SaoنX]I[`cO@0AZ4hf'6P4d0nfw0@RZڐP5`CouꗙEfC ̡I'߱/gc`/U35/XV=d oeo ƠR:.®ЊHYەa/hoMY<̳J2f巤 f.))@p|qӚ.$20B@!dZFipi©5hLh-2lC%ufJ!@-$J۩ڭ'y QUZ~@P2s =2_ʬa/AŜ:/-OرR b\b*lAobj Xj/Mot]8Og?6sс`L=jHNe \ȯ0]X۲"DLeA2M CCUoRGH".|909VFcPNIC@mVj yΡWmBh]k*Ļ%m14Q+t:b]:.g.A1 "8Ū@iSE@EɅҋɢY(h6(VHžA:QCKvčx;aë]#9 ?UIH &'XBkbcTS2'b8"-X(0Uo&$/OK&F#+;*GVk}=zPF Ehk|]CHrʗKr-M!] +c&c8c B8/`6"5N98k]Þ7^cƉq7Z%I~:R&u7@SLƣ+N*CVXnzN늙c`(-,|,̌#rJY|LzY3U Jkb*1Wcc×Pláo;z)jZ{26Yԩ۪P1^/ !Xl^O$0+=iI Պ 섁G7r"kۺҝ= Uc 4>5fD2tHm! ǒPRljHF1q%*jv65|O5 AMS&/S[b~34#A2 "rrP h +vDb0enlZK#N,'ADk0dJ 3|+ӿ0tc 1Z0#Hx$Ǫ03̒rEqrc Jz4iDX2YT} Cx9=kf_kW*}|zp l*˺S4Kf.0v=BXf e#Ηau`,.ƼySMH#e+D!_DnX"eI4(]-iA"uvo,Ivd"" nA5Cp`;@!7Eđ N8Uu=G͸NRZ*Ľ%v[ޮm X>Lۧ\I!r%HV%b*;5*Sgao˰{"\M-' BQD1)#n`)+"8(ٿwwWoV5˜b)vfLiAsϋQxK^RWy09ۨ''%ז#<$d7u^[Co{f7-WvV"QRd2v*pͷv [2[^[ʭڵ/}* CqT[ dU9D0g &Ȋ`AWϴש"W,PPu䇾Reȧ{Pڒ}J; w"a$@cX>zqȗ,h FKzjoڕ/m9Þr )+l\K <+rzo١ћ>SZAP8 ƁEA_Ϩ$Vi&gH-s,;# 웟@h);8MWid4cҭUng!5%^Vu`ɝ}~T\i:/uWE,@՞| 1x̑jU\X9c<_~b=~d8oax⸴=w}W;;Ky(9s}/֭!dث2 99|NGq;Zg} m+Yjz7w̺Wl6[3|< V#qO<}xF N*0@} N Mq7 A0?,ÿf(?]sJ>a}lTO \~3U 0#=(/Q7j ;Nw`\uՍKOF/QoK OKҚA`V潓3]#? x]=)fW4羰\m>C\bxZ{ɤ!e;8,) B_Q׾'"Mu!Td;PּWb8{9z: &J5^kgT t܂Ֆ4~pݨDa"*0&lέUXT"LY+&خ&LH)6/s7kP8_59 ۩٢r/i7>@8cy(QUXH? Q8LW?{{Kf2U9--<7l0&|b1W&gLU%iCŤ4sݞPjԚШ_$uyF:(k蝑D֣\8e>$PC$7:3+K*MI0:`w^bۅD:f}9g`0/nVvB)d>vջ6![غѨ6+"^'jtvV&: ӤS>:cj*݃G1ŬZ%_s;L.؜$eu.1|-8%I#}gyBOהN+tnWIm(y7cD&Ckؠć)jDvvB^LэWz)\"<]O6HܕhpB3ծX8+1hx2V̮ڀe0ԶPi+3{jK/NbuGRQ9$<ȶkX~/^@SCD_e+:=U= dC;б ʅO9tQ<=,ٸ 9F2Q_)enL*_+=/C)OE:jx'w)=#K}Agh`]f_sʷ O!64WW8:Jg7^s)_=;|ԤKc3Ғ7|8 QUԖ\ <7Q/ܖ9nܼYc8l_Wr] .U4 J@&eہU,df( e/DX0$]t zPhZ_ܛlǂ;,$~t&+'`</l'tp^2C5:K@sXU@)IoI-87:8S mU+nv6{{{{.,k@ff IW7n{$ω=.hw-t{yh=`EɒK `Щݏo}M JL( B5Ž#}BhhѪ~eܝMf]VaR$.7!/ a䉏@`CT͙nWԪ{ϧu.ΰWݘO~ɤ7'٢T(wLdž/XE ".?P?` ^@:jv?pBrPdxa&NI{ UW]^5kwzuti֨lКSN"x?;UR9@bf )y*zwn0D9Ƽ/; /\{pGq?vBʸ/ȗFN?e(j1gA:Oǽ®hb:@wn=_s cdDgr<,]{ZAx^;Z t c(q¯8iWsTϲQM6~+˹!(Ć|y󊸯:<d4h9cϺ_@$KE-!pgEhQ3o$9[R1 T{_̇ $0GaK˝OIudvovej\C::OaZSf #?r[rV \~?`#uμ=M뢋A#\ F `MNwQwK6'w" ӿ;uUfz$]=i25G~_ aZ4ML?QL)\ue yaX\=M뢋A#z鏋%#Daeq:=Q0kFc={ɲf8tF]8?g,@H#J-W(R;u]~~ltƁ`1&J{_h|D#DJR߲ ~80v财msI᳠x.8G<6;V_8ji!nf8N45jLCuպ]F\&)rmYW~}y ]I~z5ʊf< ķN8wѬuZ!7$P~'A18olkm_r;ۋ[C[\'RȣO*V;aUdh?8G1ٷ.ioHeugL}$GrVy6r:՜-'R "$U(iPwsfj*9rf5+? ~^S^=?ɸ%<~HM_p,yC]u uDZ`7_jjԻv=BiQ)k.$0]_!I7Kt}Tr T#/Qd ze*oM6q!#˷pX?V3 3"V6m7K?n]`ZKOVJ9r)6K*e֛5֖>jj='\߭PS)[,[JgPG}A%L*#E)nt/ SH">N MhLњA\Q(̑QٛuC|/<u/CܖO33ڳLln dӂ>%ԣ7hM0 .yZmE NyG-i'3IyhnI~lM^ <88De>1S;j[˚EܬlWQ#ǹgA3IN奵wУGz,qcwhӪmfH4t42S3T">If Ҝ5TDlyI hȒ卹~"Jj/ٸ45`V]YMr0a%"aV!IFZf,*!Ė}Pks-rax^g*W^ZuʦeJi.WPe($n{yd0Uk&LQ"Ȓ"1:K?Ob !qv0" h_hF?0W>}*0*ƴAU%oJ_X]r"A5POVFh@Y2(WEX,T fGdK۹0Bd덜鬩O۶'6fyvBɕPsyWZv w9,v<6Ϊ3B旸_ +r!C$ L_S$}(AA{^IB#@f B0 W[Oc??u8XYv"l]iђl_Py]c :ELyA2&:D^ KĺBdس/ 1/|q'4"l]${ֲVJ<tsԨiPSO҂zpL75܅+AT9Bv &br֊WPBsT}em:8!cdG]2r)/5ɪե?dž"dž0XkcdmDD3?ɯG_mc\Z0 A[5țW$vBN s"9/<+(q&_LڅKd&lh,X_$^a.3/6~g ,h.jfA%tNfV82ona+F$^D#y?u&cd,y kܫ_d=YeTGA=ք ^ gIp-ؿkذ~|EɅ1M M!^ʕS*x]JDJWUvTR/;*a1~uLؗ\/ 8p=$I//3^ko{'hۺMe;hz\!d4ņ=ojBv빟IUlwzmC J;t9n\~g"~_(_jWr^ M"FsB$9N2$x̡ۅj_V'6|j/y/,NGJÆ7¿t;v=VP|gg]Z>%b'T3yf(G yR!>Füq (s\=9Mq:]B C,XǐdD#ꩠb=[9_i$no#hG֊P0WȈj"BDM 3p  <}E~a\R>Ͳ2EYRf?dznջooۻP^̀omo6K!eqWFVJ#WQmۦrD4 \.N#𜔞xh( %@| F]@F¢s[QPn@@nGIUAwwwsn,*kmS`hkGSe-Ad  ,@DBA!_4U}M fEc!vg. luHkQ!r~p y_ ZOBnĀz0t>F$wΘF}(Sw>ow-_5 LiQ !)[ L֚rrUHe'r}vKTLbRVnJ%7odw '/ջۛg/.c&%wQ1qLOa/c}^cJoάͮ5"(vTx%U:iHWX>+c!ǑG]@5V^:DžK(>LʠY;]0ۅ9G|^(U*߉Gf91Ҟ0DaPpAC@DF9o-+L~] 42Te3Z }oECW3RNg{d:e3>JObRQ)oCt.%Շ! nd*"!qA,~ %1)fTORb6  Nf%¤_'9oUupPwLXesA`u%UC#<u؄:DkȘAK+Biz{u LW 'x$=L0W=X-LX8y,LWzęU`obHTrK)S1_ A$0`P,u}zVʓIWSՓyxoS1M @V%FxfkH[bo_40I(~vIX>̈́*')OD "#v~f<r޻~JPIUTRzG$E:)T?.qվ2ܟUK=6RKOAUF}V;[Z*խ7Rr-Z-[ܢa>k*/ ZשZQ"?pڼǷU|_x S 1b=nzMO&"&F%37lh`Phĭ4ϩQNm&)2|-?Zb$,YyJxs^dbdp2 `^\, cҿr z0_boRk1ΐJ {_  ^f&UL2>81^b  ,yYÑXxLH=nLP~yq{/h3 %Oe"-a8J>.ÿr6Y#RMhdi{ڣXP,_+Oa҂b}U:~,ybbďٮ 2#$DJ\YK^NiYyib1BdR+Kģ 3+DG0 N^1@ܒ~u~(TdgD 9},^~8~ݼn,+N+3x+;A\P1Tz6b+#Ck>N?H&xgK}wiS-z({`{^x^{a .bks:_4pU޻n^û߮׼*A\P8~{?mANX`JxbJ_߾^Ck-ʻꃕ DJX1-zC^Yҏv=e<?f"snj:B4+I{6e;VR7G 7C8B$vn!cH2䤤& K_)]W %c>[Ob22?zH[U$l`T'd8`,6tvHq> M=3N' "prǃ_;3&,aKxMFN ?0zk+lĻhhH\T1 v!]﮻;N kNq\WMapt@-=8Q CLkR.ͺswSx۽/H>5޴ {}r 7]Ӻ%Opy8ݏ4a ?xQK"5bHe_ym,*xׯ6jrU^Mb3|;.ɕroБ%{՗*y1՟7bP  Ύ>[A^M<ᛲtfبmOa4̝E*1!l 4  ^e;1@+@(ɟ021d_^4bLbiO݉u bgDÄ +""Nq+b+z;P~2 ol~ b 1dG:BP̜~.1"UrL:wӻ߸n Cڍ'qI~\F57R7-aq+P< ayEM8XKxUYuj^[F_5m%[N;R4OQ$J*5/"jr4dV.4>PغaQ5rO{=ޢ* Qi,FM[]LV0x!}zV|{qRmحr P(Ӳ$Uنu[ oNY(* %yz.3Ÿdń b2fZl$Q{1:ڽ~mAD#=}d.ffW_PQ>3h?#}Ku(TB~ s* ka%KW,tT5Bml-2fz۽QUaݶku3ݥjn/K|oB܂pxFtc'El۩ĥ0]v^pvU2_ :UVbL,!=]V/onU&".2qu~Ha%3Fa#_zJ]:xZt;7Ό25eYȄ i/F`DUw;lNR0v)m; PT>?k\#Sm%{\2g2 {ٍ,b4̤*hG'XFFHO :Hșmq~Ųj4\MN}%!l"h?oպ:+ njLJ{K̈C KDR:4ڼ:'ſ̐[ ڹ\^Ŗ3k8Ʋuխ<_()'OnkƲwٶ]Ggu[J.ܭ /k/xuNrӊ6(yORcmK4mRqr'Ws.'dum8S)[WsjL''wݖg}U!#,0} " n0+4.S4%m[-Z;7v`Gs_*O}Le_0Db2 ,?8dFGFMi5gOlY*$^#Is)+0Ӵ\I~Gg'Ǹ |&{?^"\ex0f~S L4Jټ "e*#b} \_<'j W*`@r,5 װFm!~g*;+1T&",wm[8:~4Ҳ`Ҿ. Jednyvokv@܊iVSd/MXlu kvܛBr#"~-O~ B 6J[ko\LrsF q@"PA7/Dy E3򆗽 { yb`z4x_a.5RGHkW˻bf}iJT&ij.TxN͒N0Xĩe9mg'eCt~ŊΐG 9(yP~A<8^5#eaEt!Wy"lсzPuv5׼Tכ”%4KaN`U­\R*t$obR~_ Sl1,bԱ$҂N%%LuB99"!z,)lcꥨ" f=sYadeE` HY6!KNvɂL|v3BϜ `޹nYU߮^_Uxm{WY D/wu,[Q 髥2Js^Z͹o7/g?oIڷvҀt.ڟ6Ѷ4ufvko|@@wPѾ J-%^ lYHR$޶?zr[vG7")+)]>-O*R8&?ZDJ],QȠ!©E/$8?>_K:Ɠ.m}8,sҭ8%Q'aD6\,ғ:!CS ~1:b[ vx/ uٵ)\t]̱bYdd)W%?O9.䪗Wc"s!61 +Fi0 e z|XüЗjKDW_:$h덤#:ս_G?LL* 60Dv.9">QvX+ 'aoX} />K;ߓ/~߀*1ؿ;oխU`YSR> ~Œ9vaX0p\nԠF`i7jjཐeVi7k定+?y[hA{W>-_%de1 8qn++?%~IsWثX8zQ\ls*~f~ͯ 1 bjD=%wɄ~Dx~y.y@#G0ܡ>b ι5YP'=('F,:5a[SZH]ވ0Yrfܖ\,/'ꑈ6lu&zBǗَà 'P:/PWx'HOP*U"8Oi1Kaʉ%[ žĖp78,<'$jGo|/YfvAlk03c R|w :)tR6tdWUmV[M_{|hFBG) ATH~ #'h+ 4[3QWf rhfaib |bq- BB1YKcP|8£bp& "!l;g&gna/O#WD^E "kXSYP,](Tt1dSS8 ubK!3;F^Wsz "ƽ?G 29 xĸG| ڬVkVnT7XIxxA! #~0`_9"'+yܥb6EEZ_D{1 IbBђ-W8dDn;UU'ZTpHm ~(My0,l2 Xu_,|iM#_٣kQz.^j/&Ă2Y!#/ߚ t˿TJMx, T9m(k+ 2ize]WɎ~͋+sAQ5RSHa # ”.Ẉ8< <*CyƊU HZD8)HnFw$Ȥ\L 6rS)K B*,{OS2%$BVQ %%cgDgWYUU a gBh4] a(7 ~mBIL|0ځdӱgb4`@*Չ[̅ޑyub*Ƅ/=,6>'9zcO09Y]鉱S- %Ȝ |~(OYVK}4E/ͯOB͹ ~TFG ѳ ͕S%i)rzl\3O+:щs*-œ1DbGq#^8(_Z Y=ei `K>{9in$r gP -8*8 ~^9nLF-)1y*Hkz׈ 8?Ec L.DL/GJ>Ii(4'Cd`0\B/rM^{3 Uꇑc#Nb+.4} e3Dr*i RȊσQ$GOjT/~t?ݍy=gy[^b _Z?lb/1͎ٮr@ӺQ{ UOP|7~>g`_WDRQ4*_p*q 9|[l} e( XNȮ, 0g-d3s\C10)-ARz1hD-IԌF39cE:ڜ:ہY 0f6'G Y_tLF( *&!S+5\4AQs#6.E<'OGL@ 4g8v4wZXoO5YP-ʊF7qj\ze6pU?Uf|iCQY:LJ0f՝׆K#*^ KFW'f&$LQa&#q7MئJZb5mIh:nhAFH`ܲ)/9dpidƢT( ?{oGˮQ~Gz?Ke1ɅM%\A<$Ɍ%2Ȱᅰ"Z0.&f@>y'p.A/j1$i.Qe!z pȓO!WYlkU#1NR<ͲFYϲw׉3%qD("EL5bX-<)+faҘvb+L#%"_l"Z%`I"A:t&Q VGVd#6xZj'810,J쵇sa%02A̅">Gr: :4 zXەo2a/n~ѧ"gt<"H>V"8t;v~F;l9#_2OLBAPLO@IAV'ȍ'WiD$,k -! }C`})gHXa ?qS֟MC^aOJK枺l7)}rm7\}G.KEYUl{cS.hK>9~OT6z]M"{yZT* Lŭi9Sg,˽TxúNZ 77M9%R c8^wҨUnwz#" BTJa]}\k4^vgUۃsb^yZ+2a.|=S,3(5ERV_O+i8ÿfP2 e0fuh@4#mWV9w z3EKIzF`xǷ22F(Wʨb#O&B&8 usjRoc#*/yrQ3D/S9+dbr=:}CeB_&ӈDk7߭u./'nNfY>z'|[axs~o-^y]W:J0 R?'vZhR4΢ T(Ү 004Usx(#:^g&ڋ JC*tK-ٛzdb*WaoǏ7ojl12CE) ?ig*3C4 [KWFؼeXud9@6!8Pр6G'_A}}r"t iQPòGeƉZf))[P0alËM lΠ,rYZT*jN˙8(*!0FMuGP*Tq C< BPh CH, U4 Bؚ* Z* h:BPМVg ) C]l BᡂPoV-8[ҵK׵n}*v˩Fd21غXLb7KE6PCw7xmhN񙾦TiRflF'9tNfRe_\dQCȠT&jKmBCDz8N&ReFoDR-:Ie/=@\M-/'~gx@&Req?Fy?PV^2ˤkYuoX4-MϋPA!u0H_tkNfRo*{M 5ž {fưa} NnɌma<ü•F q3$"V66]u.ddD66ζ2%l2.Ckbd )a@jYjQX=l췿-tS=Án\25]mZLI 80>Wx>&Nj g1N1*"{~qg `C'3aU)&B[:e.y2/@E|uj r%\:kueE,ir%qʌ%{ {?}j̓SrQ(@BޥތHD/YΉ=_%zS 6yB6YrY4qPч2ʽt+^^Ɋ:>TfxGo\< mWjo;u=.q5;D(EG],"|ɲj9jXi}kY=}p{( }[srkf˝EZR9-z3Ьɽϱ<_~ݓ dhY5iϏWesi*08ʉ\jKa]"Z\qګ1B-qa=/f;u'- X ->szkȄPSde{#tJy.5;)ؗN 1橿YDm*7E$cU#P*FωԺͼrJ*|GJdz/oKX/͕ oifaɞyNb{Ӹ:-"&^߁fC41S/o]eUi5F ޮ$H{BҾN;|0bNvxI0H=&!m!=K*c@K,zJc,|mCL kyAC/ c7#G)%{YJ I_҉qrsd!◹+:ey rAy.ưgp8>;bu?H\Ǘ#b\&_ƗХ0|NIlA)BBm u s g߶ObvS̵@qZnm'9g0o+vQ=q$&qNol*,ʻkU>*J].P%MZ9qdPW[}AYħPdLOYRq5IvTTйcE=pСb3j0-+)8f]uAOF'z\7Wi'%6 -QgX(%\][YGOT,lE{%2kYcp!ӝP׆kP_rAnk,`lqW~:G}OD_sKeNrlX[ 1=cANpu(ʖy F+?мb6SB~injieL 쭗BUDTc3. *CfK,tU]zf;!#bG2v+CԎ&CL;*CfH,>t'ٹ@ ]f;]be-@@9SX H??ePPkK>=-r 2׵6eeFfP@  :(%( /  Kqpe}w q2$2`V _ܬ&|,@ō*oĻh)1D*0VlUjCeD7i'EeB4ٌ.ʤ.=[aW!cii%6dHl76Z\l ۹{wσu/q>=i̟}8ɏ8,Wb) ?tl2bn<;{u[9v}p?b@ @ @Rv@ @  @yj: !PED Ah%B/ؓf!PdZ"@2G Cr! 76e4&L5\*A yi LLr^z5֏ɏ~g,g[@ @ @ @@ 9:@ $$D8@'Ҩ&?6 m#PUWA=QVH. 79t;A4PVE'+ꘝTQtamS'R)i{!3`5UMS"RVz9nhSwOʸO>×ԫwYױY Ey޽ʽ_wym15Xd[lb85h{yE50Gб;ků ~|t;igx8?"qwPĀhl@5BHϟL߉m'ë&R] 'M4M/hkzK2@J w}@(@xWw2 Y\Պa@llOh9X5 @b.<@v q2%#pFAD<<8\#HZӻ0jU8ŀ02 8_ncn` DI”ڲ%E(1H)=3#\2ʍ&Q"KQ7:ϻ˸SeSvE/La!g渁x(wL2gp>>"/ ,ovWۋ|lY8g:=ܿxޞ{ڸM@;Y\x*J~ MLܹo hs,60g17î2@tp \_OrZKZY2Ɇ.jwo|YkI5k[6b&9@FO\ X5c#d ,cI}N UkI5[FȤ\^ZkJFjȺ%z9F#HR= =cVښ2.e=Y$N[ 3ƙ//-W bH'[oz6d ]Ʋˑ:Wg\hU 4ޥlB.ț2.FERZ̢W*gGeShy2z3ZEB^zK"%6p6~7z&S:Qywx_Dڵ3NoF=*iO澈2֘M91gϒ<YfCVaQ#Xmhb΢%^N=LZ4a,L$ |w紶nY#jtwGÆ#na"{{HšTʻ[KEͶzwlz5w"gq!U,)QRBaf Se !t3cd ,cUrvu}z祼?5ŚH c?a{K~*,ŵ]nj scHdzEt9h+t ,[\h;:qP/W_fsi[o=w~tOb#X]TzIןucky>3'hp^Ǘ^Wnk3.P] %r:=it{RI3Tލrˊ] 9ST"X _D%Gfu)+.|GYLSR7$GZ{FTNW!vΝQUWOgrv5?e 6h^b_ a4iE!P7z(ϧI\(q_OEs)MEZ\%Հ*eQO7)*dU&+e&K2q!0:e82.lr>VM™8}2%^m L|O;җ;"Y, q233@Vn" BH^xxD<%J !8G0"dC !ͶvdfvLuߘp Aۗf7.P [ A* P `t4^(ۑt,\@?SF#A}}[m?Y.'0 @2"sKn( %"0xpo=Cڱh^mUev[c&XǂD 5穮V>@^AY(<꤀LP+;5 )MS7iә]r$+AD|N"Bu—"l[$F-|osYZN n۬gYKMtSv#n۩You1 -볜;qjmUۺeAnj wsunĹUܪc^fo1T^ɚ1$ .u /?c9gWйp&[6qr]"2Rs2jMd7Yg|A(GEA2sW :X_X(q\(?@!xr'Z?yDrͨd ֹR zk/WsIupF%Y,Z0 ̴)m|!|uTA*.GYg!"ezf4XmYfN.]Ō#z=5\b@z} s7K;@]mu<]tHB:qezT5~S~M Xmoi]Sa->=99F%mK҂fZZ u};/+ ˓ؙ+U8if{*.04flof_J)DUdA/WQ wX}4%ӶMG *^{f;?bd6%LJDH[ h&Up0'hۦ5b4ʪlf fbz"s y L.wLfL]s[t?![\ tGvݜHK22CmVvnw9eC.mƶP vKTxe^x&X/Sp fk.Mbq aKNs.lw@8/Lo"殮I_V0tqKڴ,A+ׯdCA4X)LC]=K "}yk;Gas Y䃨F !";ȵIdJ"}".H4MXۛP/`BlRHؿq`2*;lݗ|ݔ0hH%M _n=w~ҟ)"Y'4(t;mYdsѸd,q?/ND$FKI}o;GAo)2*)\AvaA`Nk-D\2ey\_N`V., =_1\r,aoph q144pV~!,7G}'Ɂus_]2sffQ7B{~wݖۘ@f eo7VHӛd+27AWI¶kBF0#3@WGQk|$hK9M7PͩɆ@Yo|E@ FΌ ww;{srMUrj_ |RKVݕA}_S(f_Ǧ;mmusUFuv6DZhz7*7?QعJVNJJǟIjq~X*a>O- *;26d{_Cbi6J={c5o%Y~}g("2l\eY1 9*s ,!)g("[yziLjNb!.zJx6 ּM( ELV14,eǦ ݙ+Mw+@Bzܚ85zd*??ʱ%i2YSqr1EGk" ~UvOTb~]d,rSnR3qVS=/Ufhe=~+fhRcJ1B%yuaZA3{C.Y/cR=Ѻ1bY/+S^+|9~ש͛7]U ">9JfaOyي&e۩Sz%)byP0`>X@M7`1?&zF9L"F78- ",ے<ӈ[ƲigA3 1'c_qzd"L5+IqD{Or` 'RfMuUB,i0e'*qL26w4q/(7J~E.t/\{ ^O*~(u&BgXA `йd< Ӌe_\,B#_,,H`#$@j`AEj}M*04 s/ 죋Wzڝ`P`~%J d&bMx~eyfpj6_sXa`fʍ|q)#N^-,{>ͨVhvx)oK"RMÓ< Кݬ ; Hmn_JEW^vhs٩x@2= XfH@5O' ¸p_ɾ֯mr7Ǝ7}j4bJc#- E=ݫtJ#)4uV *c_/TZ ]lQj,,wʞ05?9!FK'TL*PA_0n( +TI1˖c%t/z q?T :R #)n<7恦5JMl!6P4 > /u4o8F@3[F=K䘽(=`z+ i?2)Eovݷm佂{۰g B_>IɃE2e\h"ylQ18P'BeHB!D":n!BD="J"DcD"H>'3g78B!Yk ӫHc!-Íw#q@fBzFG^zcWg}`A?ºa" 6$THa8/TIFROAsR (פa$˦Ev6'SQ: 4:usݓTsC#ꏨ @,9T2˷C1PMIK%*6a>3Iћ0P&`ȁQHiGɳ钕LR*,Ry+JBX[4!X眷[a^-SbnF+-DHeP ݼ>sX>a:v|h@?D%ױib3PI:icܦS3Ԧ&*< o[,aHr112βٗL\UA36$Գ1TJ  94,dcN-4)ߘz P;}D[ tz>|ᰑ!;!E(tA$iXS|:|ɤpwe1hgaUgdE!SO Bh'3Lt4&zʕgJjJkI02 RII2n6(!4%g(E:R;m 3 m<"j-X8G~;x#>o3~ՓՀ=Q˩x9HeW# I)-Y TqquqԃM0'b|k|$jF:8w&7*#l.)Ugti~g_k6wM|᧙^/.W6 6;e'[,4!>LlZ[>rT1yq<#}T Q^XEZqXn9hTӳ={?g9VLWfjA$Z5mqSj4S6ȖcDj ܃^bWJ_TqJUEiN.:ZtjGHfcٵtZ`1V)uk/yٛ kV4mi0/Z[kIrٚbˮtZruX[Յ:qB OXS-xyj X' nEQ,OjW6K T+DZRCX*- % $YEaնT+6p/FMnvݷt][wNx/?c<%s žxk[jn-܊l`WY A:HM<~%]V2> S\OAm߭|4-w:BA:͋[%U-yi$ZdGdگ[t:ẌV29-܈Jv?:UA^>Dǭ~g)^Iz0!b:F,җVK/TSt O@aH0\/^-65N*Z%%:xgN惺DY%Te7en2&A*:([k˾9Bʪ}V bB+SRYk*^!ĂT+ IH'OZX}S{|'G$ [D\KK)Ze0Xq K-Z2KVma7۔Wc>~,2z|= 6odYѧ̘Y[L`ޗ}}-_v)/[ 43|Ɔm֍( 8< {:.ٞEōCnI7zڸP2תۼj=sn^]8nI\B |ۍ-D#1cd3}q1FeP%Nm fC0syϠYdv$]uhP .ks).:yӢ건ϗVYS-&]ҩ󼜱B%΅3X/ ¹]23V-"n+VbY\ 4p֑ :[2 Dt᱄[%!mr*Oj/ٸMߚv7z^px׬_V$~ G"he³0}3koD{;M]ٺ1Ix*^CO{EP)Iw[G9^k}IWgI(ǡr7Vf][.SZ3 g #hniZm١v$Şgjtj @VH-@A*{3Y/˵DoRyj2[<{4Df廓]@ݎ-R\[%xBs MtE"ծ|uxp(A2,%,i:VLucRM':~^V NlUQKE/%c\9+"m^I/_~C;m-tP]z/nu`aM a k߸-[dnVS_dY~&/|vpGM6f3ڹߒKA[!htD>E*")"j tHNJnhPdȻi?csnՙ{_]}~x-*7ۍqwލ p/ކ`2@xR_1$9iYIv1f1U[r}!ݻ.=ry~6}_VJ˦^tBiu4QEЗ!$'om̉nAse-Oϲ3:ʑR(xSHkҋ: Kж&('tDwY ^Ui[Ub:O'Ȃo^63.\<0ݳ*ui2ҽt"2}_Zӕ_/Y\\1f {ō?Ha"E U,%A9wB^;=jW :{oӽ|nkO ƀm"U$4i +9,7`0Rnޭfv6 ROb6!K>ϢRЄۤbE䏺&g.c1 h'҆ e%G;@OB٤O!q& o&\*&2nX_`kPݠt&X5; *-rȪ zmfI[ [:*ԡ-:x% B!w7ۅȯ01 P36a@c75a{…_ y,n$f./Pf3m~&pas;6-6e2GҌqNψN'_#UzE_1u3ͰDȲfDEF8-mi$5QoA<yqxDF@܄m1ؖFc4!/=V[րE*hEK WJSMKʡy](e?G>69*" *@anۡ=vĄ A m p8H Н= Fc%-g?m^8θEVq4{8@+ѕlqͬpE߰ALgOs:D=-Og!|ފ CknxT :BGD!$\]Q^Qd )'Id[M?c# Ta{lvjxUWku!u9 |Sc L9+UbQH JJ!#AI-Ԉ,cKpPlU֕2jx0/ɻmSX9 >%3Ek66_C9'0vʽ&(B Ð{Nnɽ\f(0n ڀ  wr0L{>+g'9DoiAqr=iKkZ dSnpdN`':cܐ >]\I|89ȁo lejl.egXI/YӼ }\kV3[P0^x'3L-#vkT4Ѷmd$DK!yWOK>gUQ0D(ӌp. 屁r9!y)pޥ,2T(=ѦJkb*q Y0Z(H4w'Z}"#Fn򘋭D[oV_ߚ@@nv-^| N~H#%%^dIa7geZ@67Ha ^]<Rk;n݆dH= R#Diǭ=j &* -oS ]A, 6m>)8fԸ<Pyxx1C:$OUDR,%<{h|6ٓiBKcB/'9Zۗ3if 2R$,s WdtP 򆲮,c$U؇͂ aUTeH!cA>][:-YM@.K6Y[9ip<=5m1_Tϼ-YIwYl 9'̦ )W؝ѷTܦ6fEsZnH v;3γŔKY j{En+8!&T+b@)``pLJ/11J2DTjPLj8qHg),i0%y#/U2ٕ8DP TX:V+c;ŻzoXLB %P-好$?U-Vs5 hsx@y{*IL3iﰘt5jwKzh\oN֘gz}wv4u%yNg3G)%1o̫_dRk;T*ZhC~QpQVǔBgvZB &s$Fh-"Sq60 dQOp @IHŐ) ]ImN8U)(,)L%CC!G1Bf߂R cRPK*k(%/nn\[f;{@\腁ܵq*~ b=w \[N,lnf^fxwp}07 6GgOD}>P7~QvĊ^cv#TxiIߪ\a]]x_:M@d߁ H~߷ c|WKX|zPם{mQ!Du rz3ʡUsOsSAj0t>~s@EpHYL5vu#cNNttopo[Hh;OQ;_H+@wOO/O/*3H!U_yS>7`U{TaAhw?q.K#Y$Sl7?4w]]uN@JRG#+o_־fiߣBL!؉u Q~W{~'q >[2|| z\m^kjk$Hz,,͞(\G- G*Bz̧,p6[WjŽmR{0t A5oQ|' +枺À:XMIBA|x* JlfI`lȠF2 K3g! tŠ./~+ Dan;M'xiC<ǰ wɲs&mxa67i-2[~OZ@ 8MS,n#N,{vTG̠5W L/#LԪooP^iXu˸%@P0)KoibK{iBǖKvKwIpno\^^(=Rj\0A`! wGB%iURU'4 PBoS#x련~u˜-M+-Ip>X 2Vi_`xuT%Ἕ?yG cA+H[F:0?c&?}W\>vyBDŘ;d65v&6Nsm":A[Ón.OCjc޷Mwm}6ZL6 m)] )vg~ҘB!-R D,@97D"(8eKB!h0C0!BC"O%ΈK„N=iĄH!BZ'BA'BFҞIҧB='tmI)Dt" ¢Zp<^\gf?:=8?a̵ (^>!.]+#fsΛk qB5"`FlFxD\ExxPF<ZI6 P8 8M mY%ܖEZT4 0OD|Q0o`z53 FgdBhA!$Dpm4|Wx'B0 DD0g{E䓬l6ý#GRyvz[Lb=vQgy_w*_< ꋆRõ㖒pdZqn7ZZ+[J4GkZq->vIӖQND| _x7]J%tzFY+`wOګ;iR,G"K^SRjSMJYv敿N{ldӨf,edd%e!@=/G_/@`ŕƅEfEvTTF]NMMgt&ggpt3nִM&5aժ:T" k*ŕka4en`Lw^?V Kr"R% dkn^ZQ{9'akj=̼*_6}S`n+ۖ0cp ru/ܪXOb0CIa,%'ss }ZQ\Ӓol[~`=) z)@_ۃ2c $0TnYsBdd1Xn5ļOfCD|Q-+ΏM^9J# |rfGnݔuP|A";+^nNDmDd1kfLm#maC=RiDf&7D j9V²G]1e<-ӭK2O\Y/m&t9QYyDOɺp[?%[L%rm)j I\}TV,,1$w+hRwÕnt~4?2m`Usך,3# UIXXJK6N,elז)o|[k';9SIf,|JM ںHIUabW,Hqq~i..0֚RBqtK!qm-"3`kB+dZqt<|J9EW,\9?tpG!dZq>Zɣۻgs0n"Hp'_T@o~#*@ + 4 qJx›.'oʌ1EQ^DgkvՍֵꪘDCV7MݤqmDu]tfAɢL颻E#~>0͓22-iӓ2)!;`_bH8Evw6Z76[wuf~|O~.\Cw;|7 p A[Z۬`oT7#cv|&*wԀ39!VK0z{R2O^>G'2ǹ=:PW=̤fm b>;Z+N: }_ܹ_PrҗZ}V~ ^ F`9$"mN?WD*\c|^^ON_KU ɗ;я*/te-XR=3=\ V3M_KWvNҀ涞3^,X 4;͹7nq?i5ة8G{kg~7Z!ՆjQ3drUN &jԀވe@ㄖp:\0*DKaON, * 06Qx%)%OytaЗ&O$N|:~4X0N&xCj,rg f`c\r ]v< m&d@'[ _O\v!`| l_`v  15E _D-\WH q ʦ)D}A<3&&<\>p)/pe@iѶml><;{y]z&6v? Ҹ@ @ @@ @ @  @S;Mhq8@ !5E _D-\WH qB) r!7&De %.* Eh]^m|~_8N쩇[7\x8@ @ @ @;@ @4 8teH #2#PEAxK\@kiHWj h֠sq:3]٥( ӔOq6' dfVU+!3JU՘ MU ht ,W^:|<sڷ˹98|=~4hGGrYY6*sƽ60:|$٢f·g ?? .fv}3NuP7@-WQT/GGYl@(t|| PyCPPx[,wBFlйOhɏϫsN:WNP%@ Np ip{&蔒{)h`}J(ǴpL+>g1J(uWoo0Z՟ 26"PUzn"3=P(=,;G' Iέ Lр":0im7 MnVn!n-,Y v]megf=*5΍kep U+#'+mdId)pl,"Ra}%NJX NH%& !xXa;DN?6^za[G~av.Kzm}d-hh.kVR;HBJOOttHX4sl0,P32/B^$(/J]EY|E\_7mڐ,ߥ}T3;>6w<ƊϾ=/9=ߠj-NliHTCS΍GuX2"$^E_mSgSَeW9rk$H\=d-8j7#<lhmyCX[p旦YYٵme+ؾGr{LosQ!,ؤpm$U,epV>Q ~ĚE;gP(Zo^ ]HfS{o "4.'^ G$$zUC~\qXa`opfvks*VIUۇ9m$ƿT|r>߿Z.ƝTyt- @|e̟yT̸ȯ0G;YE;,Nn^ert `A|).?dwH @Ba Mlժv5(-d`@00Ė;v5B@Ne}Kt`:a)F,%ɍoI`"4ͮ.t! F%),ه_,_+"XU Y2KaFcҹ[J,&U\:ڜʺr'R*YJ޳noIa"Yb%FP[ 5NQʖn%@!IޒDYURo9@!f~?+-KFKyYe}򌛝׈DO 6V~t{nkK7"\/`nlbǣ#ӡV5, JE% (2J_Y*YF)zӓ!VP2vg)[$7dn O}JA|ū;V24P.]R$aPLt"B' {.Tbj2<-M";!?^, Q.s)0cD ۗ:C7LF!Rwj./))L5wbR#o@|D̲-.";Iswy|WۥT)&ǎ4N&Ge.M_#Is/9*4<,, ǰ qB33PF}owh.p 1pR(.Rs3)*!pd5[mo֭}s{̻/]ܻ7v t E ѽ+( gECn-wgfRq!ъa{@ }fJu-8!HJ),"B(Y6 $f4owxJSs{lKݍM>#A?F$)3V bs1})ga??ղ&NbSs$W|cgoX,IlB)GۅG0eNb}=?>r#R,]7x1P?GUodm)r YZ j_?1('HwHI!>gPݬj?4pvߋwh{gSaܸ6i'8|@t<߮> _7h.1jX+g!L: hAv]Y'|npg܊COՋrRtA˦e ηF/en)]svડ&c2D8cgS#_(2տrterjҟ>AIt2(B 2D顋 ԃ\TG'O W Zx:..Hivp;mÎ9-jf:?I[&lW\TX;4CumC'97|Efmg4VIŭLMG?Ė(9:"(#9dDyܒxӣޞq(׋|nPO>~<'T?8H.,&~xq!]˫׭N>Z_E&MUl=LM 瓏X>cn6 6d{vT^ e#=p2O=_BTċ[Oft|Gh'r$nC^4ڍ#ՠ"`lv1ֵkBVAj=-ѸDb9nMPVrVuDyitǮjyIo%dmVYƥJ*mWWgUNn.0d(]B'dV*Iʭ6]'`-yHE|݊%ބvG_侅oRK.Ύl%^pNQoUq+$~2RVd; oо"Z8e"f3dq-z%s#B˃A񞡼 t,*Yι8VB\9 T ra, iq ҏx DzTe uU^4IQaBXټr}&Hymc|LC,Y}u_/\'6>/?ecN{EGb1ˆg˨YD% }"/:fP{/ ^7~kf3[z݂idK7rˇ9Lk%k!} iHE4k[HJ=WS 2,Rx lD PjHXK3P_2RO1¬+򛆇2Tj]e],T.0k\xfaeQQI P F2*\`YȢ"csGZKjyvxCwYmu1FV&h@Q5C%v#$R1-r/g`8w$L~tB|̳!.Y6j*VrFozEх`>vP>iPyD=5Ho-]0P"E_Z,:X0z,[ I#/ށ2)u@5&SI+y]kac҈q{ΆRӉH"$@d KY/}1#򵒤D_guKa@f;C:U  qB4#P6'؇Τ?@L# (IpBAEDeKzK<}%o$.%ej[#bU%D @'B7xK\c͖%/~Q;#&}"̿72oicݨbܣ| )^PEZfjH(K/LگaKLoMbYw~my3X}=>މ[`$:u+"u9;eM-H]iT M ~e~k^eLD(2fCw:z5NײGMIjr)5bݒ`cXX+,D~sfHy%:!5>- q,2/aXdL=fY+>c!'[NC>]}6WS@e@TKy ~X"5+l]Z&)6PAo! tEW $%eX}n(HJ2 ,ad;{9pZrLHJ@\"È5qA_ Л7NzbCWjׄ3]E &HW>-HW2xkr*-D,^5 VjB )wIrȘ*"f]͵EID¤SMSR*ż+jbt@w[ȟZ԰L"O}E `n EoyyK&ZXp!]p&h{|>djɻ~܈pk%#2&̔1J<\hf[ oz߲+uF԰kB@$X^h2jbwD.+!@D:TD.Geͼ/ކ%ߟ@6#BE_\03$f ɳvw (#$[k^lO`S D ܶZ5V{߾{ﵺd02DE3`}H}oYZHRY%אZt3ʉMidOB(20{yc9Y+Ik@H$Ld cRE34?@f}{sns[,eڗ€0R@dABD" {P1(:'d~?kQZ n)눜g| b p.\<A:Gpz\. Sp`BЉ¸pzI'J A?X…pp.\P[ pK…pXp\$?=JMc$'-\0A{␢RFQg"cA q![1n1Ŧ6;cJ!L߅'.yxYd,QUԑb]kNj!:ᴍ1A]I)7'.&z  &Fi^&gvwsK?D䲓ͯT:.?IP^d¢F;#vsG9]AF9J3zhitzՅfwUǤد e"oySgLA/tKIɜ[єuC&ޒ0WOW,#-X!)=&;ވTa'MhN2OF6x6)NQl!-eJuDQ}.dmnC]%}(9ab'RUYdHrH^X;2kuPAdҸ ccgL~6秈u&^J3t3Z-KF;>50djliIGY[F2757ϴߌRSJ쏝'\w܉IPKV.&.!8Ռ7䪆7ɀJj٣ n˽,,UYzaflk4)N!J[>C j2oE<]T,,*XpK!q s\Tboi 49WEhN׷Ș:;z'ElʰF""IhSQD(>%,?KFDC=QHZMH@>r+ۓF^?gsV2xGԑ$ttγce>2j4Re}Ya!Dꕖ52;K>UX[-XMOTÉ*cJ6G^E [J?-Gvz$2=Bӽ1i3M/>M]qWt\Ŏ^t".[<(5Z4K.3]&'E\\ ŹS'!2,H%'0־PwGZVݕJZӷ\FXkVXщcb8 VX[V%#MF#N\|B^_,浟춷A}p϶=wfҋO Qӓzl~mvv7_O?v/V״7 zz?h%XOrw]G/.f,.8ßgSYHY-Bs}-75T9+jkV02\Z+P&ժ_,F,ٟe=O~6R@lAdZo2dc6_#fyBQ ԫmE~Q)MrzOvۢI{7<{9d^G״6JKwmuAs,4ʳ]Ḭפ5G̮*q=hK8YsR~7#-3J1r.\dr5oѱ]^=kzrmnEc/<iU֙Lc4"*`~Ʊ>K[[Hb֙!Q*DKԚX▊RK) 4rz1kk/^3x=/Wo}).bv?@^9Dm y"_8mnPjK60KN^u Q/+]9kGz&̇4ž*P(d2k-hwХ`FRp\5Z>CuUXw4< A#lMEbhϰP\.ۣyڗ (\2e!,m<{ʳܢV6@mm}v=vJ󫩹-A_[]git]}}b˪1CqH@}]E?)bMq<[XzpᣧF*];Y'\a?<ۏ`Y^mX)x14JѨi[]m+PbcY\5Njn K.l mj7Tn+ǒ>~v#w]S+@\ZxYS+O }ٿ.>9Ԑ3~:NZcڦY`& G䈭)1it٣^EMQBy乺emk>AŴ ;.RBY]?*H[BS8Ukk%ԀѴ~Zʀrzk0Hl7kȻVy7!~ZX i{ĵ]7kdsf@i2"ߴ>]we1 @Pn[ڈ!P"N?Sh .9jQ*aztb*Ù.l]Xs`#Cu2?v Vhk \f֙I4hDif4wV9, ft’Gî,2bT CfX^md,DfMnIeê^wdֽK{~ՃV{U@?>-ܧtYШi[N0ۿ&Gp+,-[ x[wU]cD^q/p(|2FwE]R@5 ( U&~F?ɌkH6+Ϝ9+ƭ DE0('0kVζ\?jRk{P^iZ.͞ym_FF[k_B=O]0cz ^--W&죥C$ѮcN\.[nmXfQ|ۢMq%TkG*S4-k-́~ɌWK/u'8B%7s ᢋEfzx k{a+ݤJr,j15 H]n՘R&^dm&vsU_',߲e` &d?V^Ŏ46ô6viZGlöI4wܿ}`@J/d3k- /ߣ.l4=kհ-/9F 3#4^o~%0cD>/yr>nQϠc+|Ea*I{jݯkTR>ظѩs5G0 z%PRsbܫ #b_҉6Sg w1L/[lwakczjºe5T+uҨ9v&J̟syA_oF@[fX4ngÿ4Le}_=Cй;}ٮ^Y ^ELj_a|FOJk8FӜrźE0^H}A]}/1dHsmM\g˃~AѮjm4\POQR'вZLj-YXB.ЧWO3ءW 3xuR>wֆT}TsJ^KxZ}ՉB/+v蝱ԭoRc"ŋzw"_ldҔZZ-D\]ò]k.`x֭^K .TisF˳WKLې۰sߑ뾆P@F#K| eϙOsuu(}cAnOg¬3na4;{%~̟X{/`bb'hwݘ[ؾzZ9eL}?ɷo lP`/z_d0M-`@#:#qStBi#!nILRn`M({5'MC6Gy3d̏zYdN0ѪfIIwiۺtEDmf,"^7Ȥ'|uty&x` 2 _/d ÚQUjƖ1R'blaSŘR =EԼ*z6ub hccbP+~ %teX c~7_V[nxn;qpލ{u@ d(a޲csúOyZb5n&\b&OT+ݗo~x'MmsOb$U/ CEGfŠ_0!\E PNR a/ !73fVs ~̀gRK=QOd0bH4[g vLb*BK^FFwSjWeu5+:1ú?Tv?rzڹYCbz*WlLꗨ̒M0>%8#y E;S\={ٱyIyyA-r7p wW H@yX^"1=/+3*9y=2fN r,Rw>Z^O1cE˩SF/.=o]sPБGddrƲRN *6%2҉_=lR0}vAEdZ͒VsT5ߡZHaUJw|Ԥ:bE_Qtؙ-?#V#aUr.>bd7X!%'و͋!+?-\(E yBEtb9ɫh0HQ(H ʱ4Y=ΎCrfނ1Y{o\<苼}^]7M9wѺ WF j ,6a-R蠗ǹkg3(N <9']o{O3-u.*Iԍ@#IV(JyGutJM r8(s!0f!]@+A ?0'rՅ~" ^w't2("Ĉ$*2IF Z9+UJ H h^XEM$a'v,-ie?kiP;cj;x7gr<;z{F{Q7ޏ0GB6vkjsOhf {ӕKZǗ T9RuQ`@2gbD4+*> 'g:2c,N,he7aBd!U6[[*TIĂ(a9-U9<NL MLH0xd?yrڔUFEwK9IY0x[J Y&W>ZXvT1^7ced6Ċi8AZf 1!_Q^:"lQX’$$bj,1:-ک̀khx-^/Fn:Cq\r\=Od>q ?3{u2B-QF`'R̙\FY0yQ)ju G71HTgiSN#tEa3\t}cAyITGGCI% Gڏ]Sl|B>l28TVHCB+QCU*Qz# :u&"Uc%%WGXI:lYmY1ð^q dj 9㫳4=[T}ׁu`j7C Oq\&0xcZx69_6@< tSo_z{ϻf1Px2zQa+e5jqBƐH`F¤@-(S4L~*uSfgc*L`L]D`%֩[ù҃tXyAB;x):T9.wtOjU:{{26jr9~:57֎e L )Q&OVQV)'X`q뿻=(DLP$% *Ti1P?P~X:uR^Ie`QCL*sꁠSbaP2NDtY <"LPW_-"V: ixbll;ƞݸz/!}? B㠂p\9y=@sp(V3K'y<6vyǝ֒Ϡ UǙ0cYbju;o_7u {-l\I7kZH S"H>~tՇ8YeHrG5`#<!XQFPH`aD ?XMSXrPVXLaY,iijZ L"2A"jCSgW?f `1E@MBw^gqo nWYp>nN]_@`9-`Y {FCeDHj_>O ޾B0A&߆ӷT}aM>{[6HnX l㰘 o1oll$!vY }Q๕$d=ݫ]( ?r۷;i>OQt > ҸHq u](¾QrȰ/kAm)Wů!.i\x. UST2?YO^. …T*cႸp>\.\ . …p{p q5"FAD/`@0pJƋO2lE&k0EBfaa}T- ')e,sû`!M.\9[vi CJԾ% U@>>wKV-dhuSƱ!4kt~UJ) EuASNWu\R2f]yhcgxFNWu\R2f]y|cXul\W2Rf]s\xn|<{Ry pak› I+6*3s$b^9( ̢ Mg_{5L#d>C5ƥBůV)3?ԅ4{WAPa)%.{kvуR41Y VlyYWsV \,I7EO.UJ!]iRyV$$E +d[cAܙ\0hj_Sd#5Ke}ޯ<, »cTckbZkViuR  Zgh)Ed93s 1x4n*afQL%QYoczbKKcs+ib~JIŴT0MCo+4Q@G翐4NoAzUTMalʊ-aDSVMKV=:dQ)XOUJ|yY3}~j,?T|d]ˋW>n2%FYT?YryU#E8A&.[86:6k5fDt bZ;1.Is:ɨη#3뺽5YJB^F.@Up[HI)j\Fx/Oo31K .e}y\^9ΧY]o _KN{}n6p!;ѭ4ު}Mrd[ȷӶ*h3J_GNJ;}c_bKm_rU龖Zɋa<]MRι} S(6pJ%|Ǎ"doG"4@nuۓ!vGwf21aS[T9cҍ|}8m"ce~oK[ǧZY؄ν) x$LQ4nm}~~ڴl 5/=,<^%o!? 8Y⒭>i=q7%p0?)ƾ[6N~ /p pAs_-/@ m4"`V"s>F6#}YPXeYcvmVֶeMIjHgU;݃iԝr=zouԚj5w_2)e(0/Ga5r@_g}O~FWmEZ+[:K 4hՓ6mY6ŗ|s>n^&īiևˊ=qL}gݫ[[IuTg Ğ/缑ܶݞ I ioIC}ptb}=NISi$| ̉7ֽ05ݭhv:UCSoڶL?mM‚"90,K(46-k tNȴJֻ+Y؏!W&Y0޻VNHrT0Jl$sq灻1m=}cD͟w^|Oj%@GK3s3W);v6ƚ}wEw-z[kT;\{lvg&ž9IDB[ɘejܔ?XLd1{F-vr{|/ۯ.,ݦ׽vhK53*`Nu `3j< }ek?ᝊɆŵT;ws?h:~Ë]"Jti?q Vzȭӷ |;ަ\3r󎯛)7`fUSdкާC4ﶛ3ӁWf~?hFz4Ps̀Hh . g.r@+r`_jH֯Wo?AH?65ʪil vdziŽ`'Y|Լs3pzX^D C]{'jr=^E..W q` &Ekџkl\rQrFx~" >덌{s^1Ӓ?hi5%+<ҧ^f.S>yLHdHq*+ed0v l̕^7"s/Pb~}yq~tc #qm ZW kO}=*ܺso{)ho^@OVTֹn;.?jf؏X"ga@ԤKyL?P*X`UW5}YY畟E qцH͝\Ķ{-cnt!}I*LM*ݷO>#|Yn~n4_=O] sfJ1sx9FūW7GGq|V\@{'. .g@W\5e} ̀\q5l?V*.+BP3 b %NgYNCNg$>0> 2pEhAA?p !pf~Vy3h਌ZVLv]o8 {O4CA{ZFPUv8adcoӝQ4jJ4C8uoQ,,n:P}|GEF|W"owy;g$ts2HFrML)x,HA"!'Qx<7R ~鱪@P`5C[:-KӬOݗխ=j'l^?z&b?]g?%= U؂99<ÁӴ|(0Y}rţ>fj;ڙ(%7*2|_RܪӀZ)`G\ltYDC<]?k@ȕȥ?^J k(O B<9wV-UUOn^z,цRUvTvk|lV~pV4 ԼP+҂W?w&Dzޢ|}o5?"$_ۭ%Pۖx`>Uc`Q]K`01BWk=ȺE@N{lU>p+]⺊PpnW^%HDKd ~ .!5x`Z-GsFc7P)6ߔ 7ĒUdMJZ%}P#*P1G;?յ+5H ӏ5|.D& _ _jdv}RZ|I"\Ev'W%h0[#mXTxlVWξ>*\b8 )w" ]n}){ _ N\Yx)pV=WjbSosκ95E˲)"w>n!:4g%\q؛ iSk~*TW:twR/V:=BOH<:${_9h@n+<ߠ[Zyv^[VpzXw=JN}Zv[%U\ w)UrdaXJו~8 >E >s,Rpͅm V|{R(l>QynayWVk/{']OWupTt.>v`ū={cS8XsザxZk"m@{n )KY^#ГҀY; Өki;!@sQv! @ạt/@p<8],aG~w1Q2b{sQv~/Qx;qeIނ7,4\_*st_QVl"C,_3y.hasLFpuH. 43 *rqv[̤r?q6nj_Œ9g YhJeK ^ ?5>c¿rsT~S,e&_&BhǦ6Fٝ^3fpAiԄ] GOr'Vf`@хZl1/<>[&o m:ۙb A?;ʛS t 3q `@_]鏂yV'\mVbX @0,k>Ԭ5b@0 %)9|z`rKͳ|9_c>w0vѤgD<qj²&$ #o_`f~C4`|1ͽ-Bg$̺uվFM3-/黿Y`W_QOQCZ W)%"br /Gδ3W:cVAM?A=?=ECG%]4чpE?{ҍ5 RmaU?M؁nM[bNp_cjҾ@rhR\ْEŐ{ =sX{C@8Ҧ95?[z𙑽'jҼq_5pli'9 qq/~YaͼY|f+_=AG1}uF֭={u~x m4"`V DA@DzDF @"*1i[k[iw7ݶl"VDw@y7dDe7,g!F6#ovFB˞ ML-e!3"@g5 @oh|j<#k=b"i)ܯez6#p mĽ[^B`׸bIAHtHGpQơ"qq|_p8$OraII҉)y1w/dcdc; bF`w~HSLhy/S`pnԷ.1(5堍R*0v7xbCOPఢ.AU61v a? O{Up{XsH0gk?E]@肙p.4EUE`B]Úpn-gm1YҷXWp@DE-fcߘ)~|Y ΃r48 __wT9=<&H3"̈́rᖻ BdP)(U? SB0Zr)耩_)[MvEmp0e3sFYM`B_+0 ݆J(A/EP]ӭ;" a{6xsN-ő[MP<; %V6W{𶤉m[ &WybeE*Xx/a!f(4>$ 75&++T0NfvmgAFpHXˆM m: t;JgI+&p`W݋Zn->h G @qLV&23Onmݶ `;nwSudtBbXKD*0xRi𾓡UO%'T! 8a5g@޷}|&Dm)­ l4Ć׬.$s5x< ws%LإxHii qOG]: vH#t/`Vo :|ۓ6)qS9zPUڴ߳vR>t蝾g!zaiWVձ- S;<Sͱrڛ7XlD$LZԶA{fIiڝS6@ ᲆ:y⠯/b55= _7; Un0g" pgb|Y׳-G{ {zNO=(qWoo|X|<No~R`V*/_PbQ}w,@iq#N@94Űg  <aViDvx8S@ bOYj|YL>F@{q<u63L_P*5g׾7sy^܄dO ;v. ' d / gJAQ=賉tO1"wȦw0+ME&|o%6nEV#'VH0X%$ǪR8qu8Fan[.f9J&%S6;Zc\F*LһqBg,lH&atiqE}TFoWN`)Ӊ"X7Sy@c&i9Er$Gb:UBgG^Ǜf{g8tߥ,CJ`H2 Y~{MJ_87`'oOcog""ﶡ(Qgx*'@IjPSãJ:擹B6[!%}%@| :e\ߜ2;8v[G\?D_spe X %ܨ38XKOX1 >&d":K( %´0RIo* HOVK@99>F] ~5%?B?uY6,I}/'oPp#F&ǥ}\\W0:ν|}ioHXxl'xJbeET}uKn#}K0[$CPr_l4 8-ѯuSB }20,9h(%:` yY? m4Y33`4of>ffX @`-l'W@KAHY2rq䥶Ovv[ۖlff߯~G=ڟ/s7R7m T=MUr`=UExahH8N8z;>g/#|rpp0;Ff;7ֶprF2 .iYdT(FQ|/B0 q>L'|2LBK{-|iuN~zB9a@q=pCv6?۸n4XKY FIrGt46 KyܯSU:lw,i -仼|i8"Rcߍ SYK2̧( / { jr;Vօdܛd N-`,X&+Ϫ[ZtVKN0H)pw2$>~c*cA^eغș*Kf 5[74y+$[7MhMg3ɻQ Abuu1m,mptE0|]&)W)u>LQ0q Adg8.y*N ^B~ WB H&._{KjӜ b@FN:s0*s=VmS؂"pNMA WoGݵ {ae EMpmA6s:JABm՚" SgIr Zŭ@Pn; cVA&Z`*> };0z!U@ ;U Y} @\@T|.hhJV{ˎ3vL$m FR{4.n/Z Ž;C lA0м7rg6O<0~{IBGOi3|w|a4~`FŽ<|+GILQGĬbZ g46>{F-ϠhƽMa2/s@EB$&۟$g'?G4^hsr1v,3 Ѕ+;6.RVȌ0qP,QDg)Tɚ?c|J̗0)W- G&h 97_䃹YRqa 8}*uf_qjNdv}PhgόD=A t{ aMBҠTq$\P‡ؐ ^sxCa>o~r_ǔx"DTl8LFAR3K1D:;M2dI /o#zEQ ^rWrLt5TыB7^Єz%cW$SRk atg0'/v/(3s1z8pKptJ-"A$n$?1rO?0"N3TQ)R*[ 1ܗIy)aCI0MIR;IVB3f"a53&vLv|98Y t„Jv ;iFMA3Dosҩx8Y 0Tia?f !٬4Bv*x_ 7i$D>"ƀQ^-#3Ͻr$n8YKfܹGZc!I=Sƒ% Ub6?(naHafsd$GcS/]V- aV~B|gO0FN~@i OmKGg q'Ó ,' m!$!!jKbRpv $@s 6,O8*eT2!~  K 950$̊I{䱽FqQwx"+pfB() pD|٨R{e5&#%3;jLuHnuX 8Q~4s#Ԅ}dJ96'=v{ 6A"m!#<|WxBŁRՐ:.kwHcƷ@^4y{!wc5Uc}3o4~rz!0X`đ{Iec {#dZ<% ;;Mts_^0|;Wuz1NhrX΢bbW;KbfHF>;6fO,RȚɰP|31UB a;nuAaa˜o'~0 #T'^#ٽ9z lV5„eI6&t+^jM:A0UrLx^hVk=2 Q@ʄ%I`d7׿?87n]5؃p]h?,F]n%{6Pvli߻AAek+]9^wl,™=VB;ςtg# ٰA6fl`{7A6vY0l1XkZGÕ5a5 CTWj)Cz1MWlߪqw谮N0&{wIq<.lHcs_:DNOeYE[l1L`J4u^MGIYZ4*%J@骵@܀L7P>okMvk&d`ݚK!MgrR[0f$׽ m._>^x,jRԤd9{&c #7l-DbC 5gV_kzo֨v}j_U/-X8!-sK &(@WLfr(Cc:Hd%"Bb?elaCN6RH?E&jVCssK._~5Dw4DW2AOvt&!XMecM`\yWk>1d{qc6> )v9hЏ>PugCSAKxܳ,[rM9~L!K,&~'NmxV%uŹ3_dNX98}]};) +U?*H{qyaF^x|jVΔte8jE:IuF^5 J0\ɕ7k/tӜF9[;`åN 9>꿍g .GOFa%[<cK 0E(d F1>"TXO6ISF3<0&okK_(=Otd#$r`$B;̼nêO VHF =VzV\B]-VB&FqaUlڡ1/o}Z3qEik4Uoa6bdԏ 4$4C8Sw4 Gum +vG0Dq, / fr_;ABBS pz"p{ j8;vu!S" ;[ ՗U/uyʟC@ ٙnʔ&ˤZȢ#R*$<0 "0 b#| !c<Ѐ3O^(vܴmӷ凡5$Sw#|q r&̡6&SN1B#}l2i9lN$/yfx|s0׫xУ^AtxlW'>W} |/MA@H,*dgTi |Mc*b3/a<8Fh@3IBl̀:2gDN;As"AK)i!;O ^6{_V>UQsWcxi~Y!1TutS9?ά?~8rM۵dNq.M\8>{Nnmܼ%hrieôb;ϪQ<̙5#O6D;xf\hhaxM:Y䰝]eZ@`_ڰ"k0xng͐ff 2ޱB[S4ؐ3Uf{Co^F zk׌nzpzF dY|1eOt5-OCƹC!`gM\Jd9eO[:2gNe$b;%(+*#Vc?jjQ+| /!J/r0M/p!)L#t4uil F_6<8'] ֢RU:b @Ft|Js:C(}% m\F<&d4*3rUE<5܌ g΀ػǔWmiMi"v. L~zmxm!Y[y[c ůz>AC zV]D_y|ਨ6KM@%aqL\NWg8E# }b/R'cGm0qSnj]TmNt_4j+Krx[lBjVTᗂ|]`rtgP/8H7EңS]ܤhe - B Y82_ d+MΝª\ݹfsM8~vSb l$8;r^ZqBYC!($ v/Qp]c^eXT<rhSLj41! є"D 0BhP PYDOdsW?~󧍋?DB|6LG Ɓ [AGp@}$Ȫy) ! s\./]A+܆u %jE3mIm'a^#WAY0 ʠ0hA; VQh Zp,VVO0-.*wG9v 5V w8RyG2!f,B:rD0t#r[`(X@Xx!a}8w~@qn1V-omnurV<7ljUMYXuǺU.puu\\Dnk=Uz_ 65;kw^a=_Uϲe|nt[:V|XÅZ\*o_.F=Y=M| NW+[8Y^/{V]ummy:BT>}48\ahzzk.VGGn{UFB6!Y%a3(QKlKΠV_e@˧u k'vBrokN{/q~˨mH <z?*twN\vUG C!mc8`?‚HhI0ipJk4F ![mZ2AGaеC;{PѬAH S_ +D,oy#+[N0Lh@8cUs2U׫u7vamrhB1?%"&"|P g_p?u _y~$L{ezyt;s@ )%] nDx@W]o~ *KvUf?lMC/*|Iu˒UrkM}>$,,$I{Z [̓jI.GDkH\ ԗ^2'r~kw- XMVNn\ëR6G(^kQ .:V}k5ŶᆒBK vWL K."7|!LvB.aXygUM`j>gl`D% XۺvrN\ hpdz -o{ D[^l۵N3YjR30[t яssƒ!:h30H] 0!2 HAu9Z/ gHBy3aZ{xXFx;a~K0hQow!}v{ S9Ī;)HzVKypvwlk`sUr00SqFelg42;߷[E޴@w1OsU, |^ýdn>owhw4u&tNwt@]IpD$'^6 ZNsі-`-nu 8d"`=mf.V)nsEyHKgmo0@ۿTU`pصC^ 5Ǚh"RV`\VROmsK˶vsM]Xpl?^JO ]kff ƄDhcJ wђH%C0G~5ZQ#ph[-bM _mk2h"!>q\7TW _RX_4kQgcsPy]5lZཀfȦ|oF5`6w߷0ۦHQ ={E>NBN|η^^ݻ*ܭ^|_Ց`Zٖry}G;@S I'TY2,bK3;?ocrhMl_'n^6J)ܺa7+44L^Aȶ -;]ΞқYjo4ڢh;T/)|WyYň1%nk3&4$[@RJE`U\,#h%a%#;Pvࣩşt~_ ?baq˦ֹq!b !F/,)`-êLwؗ,̺!<3+&얻-{]ٚkWw]sHzz-JN2Ĺ8X Ts G9긼Η{նVUm{xfk XavZ8&ZaK-ǨȽmk`V6˚d>L̨N;Wo_c1R_67s=k+0b; Vgm "頉]+L+M)& d|6m)lf[\n/'r{ ,nSpk%K/6-]ywwKv rjf³S1ւ /LTOl( (-?h[O d !m0~E+!y 1t~\@!/M{(44AJU# Ë9BS9ދRv}qn_WI.&?^T/=꿶9iMl-̄5OשNղÿ^%80KF%Ͻ]qĴ]7,5ӂ}l0.,ɹNtF:IxȄ8V-x+ -QUh qC(|fvDb?baǵhH㻂.ׯUezGw9Ipe-U8'TlnQy&w3)a.Jm]{ڢ/& `=` n-p¢Ɣe҉[`fShprۮ/ sv]6߻ۧ}6vK.`A_ԉn  7313vTgmVcs;I7op۹A}dWx8L Jf#MQ Ic@)IqFtI^o;`$ְ%q#Qz}[>$6Q:a<LtkJG"b o/,_~FWSgJ=m|%2J;Rc8/S{y[ox;z9羌.XVu{sɠI#9%[8|Y}-}z4@ee84LhC tax@O|b`@/+xUK/#e[֍r\f\ܔ8 G&=v7X0VcE7ehʍk8rˍaccjK dɱ5cBNŘKnS;_4xr,?|FohXe؅)T$Sc۹k_eg8w5|3D?v ;iE0A`V`n!ڷ.<=i{7ԳSښ{&,~]8drB7p$;E)#?y#e}X} z}-ba({8&`ϙYJ,mrY+hGC@ X {L-[&ĜV2T9uȲ=wf..;c 9NTg6|Vrt DT.2^ʲͪr>3:qwN0`TVb'$KaЖN+RbГ bbMy6NRnZ嫋C$Q[t6V9ٟs-Z7&-릑Gk?oP.-%NK+;#.wq|F;@YQ9l<;QsT0CTZL)BU0 `;Eu*p"),+/x% aR(j{o[ kFƼ]aajo1T:] Yt7I@LH^6P)UL!؈0Y"вgEA=Vװy?N"" ,3gM|q@rg̝a3) [ܗ_m-lEX'W-U(G!^RibfEdGyN:0 Z:(jWҗѳPh*GFqOb!$j 3#o[C` qx:15QSWR113:J(=ΌÌw+.E tNLcsh~&Ǵ˜Kw- Tt"XKw!t\` :7Fv_Y^ C,ax䥖 v:d| |C莪i޸Wx{X9@1ЂOSl_U%W)_E"~D5wh!XDxhDF~x'L;ENb<閛\Eʿnq>ߝ&rrP[J ׀з'H%^eQr 7 vqs%(?a5lNR0Ua%SZޔtH1+=b%)s҉@Cք_R8 ]D C06-NiҬ+?IF#}.^Hoc)/4GO5ş̑-TQX0CoΫcC j'4_b=|8=#Z/!⎐w};[jy[9ԈKjs }Zymd_&F x`|z:#v C$o E[\HB"jvt?`SElm3E@~&QuйNSpBp#Qi[R Zn@c{ XAg-VJ>fsvH#~xY'wqzr#a}v(A(YF[EPQ15G31;j5E` /`C^_8I *xXa!MNG;)!vmu vVTyh -N*oq .Ed}lˎ5rZ?[ 3jK jo[dCGG#玣uLC0G/ m7Vbn :țϚ㊁vĻ9{D"E m! mbqE MGpD X̱A/dpm=qiEn}룞mgcp8܃tc8x0a3sC ٫7σaj.m|$+9+k:?'D/9|!dž턉I40AAT X%i0>D):O_n_2>])BZ<+'k_'9Ǿ{w/hqiNlȇ^oiqp%~,p`X"(O`hU(IZO5c~/1( ǃw`׿9IDQJ6eTW $}^Tږ.i1XAQ\mox[p/+^,8аx& zZi3||+P3.@HkPL ?u|ELp,+)e8%쭅#S`j@_ckIN?ellk*e[cTj uǏ!dNd;?/&y0F!sTTu'[ǥxlҺ?cd%}|N5@p@Q! DЧƙfHĂA]M՗9p('"(("F "("L"΢("r(('Wb("0Rulzx=dz)O?L(ZmOdgBp .'埚>H}GqhgյW|"O{'DZQO]:1U_Ļ$);qkfC :*KW |WR% K\"?CzZ%K"UJ%XSSj\2r_dV f|ӏ|| oPݒSO9i?"CZNB;Ha)R%+E۰K)"?Ifr~?D~Ն?\|3p\A$k9h%9.?dvQu0Kl"u{b1Z~㏳WMnUV3$<>&2ID~'RiiK g _6wQ~D~#йO SmXJXjzɸ(j*d'iϟL '0sNr\H2%~$]hyv*&LZe?(.IzO@==?Fwk?i"?ơ@b3|p܍N5Kb ?d]AnVK\а0?~#D&u=h><]NWSc+gʦOO ЇyC6&d(qa@^s'\RЮ>tO4*}և]Tdp0f?؁Vt8w q6"PF3x^>EC~Y[LUme44pWGpln~+~GIFLqgOB Rs ofgHĄ 5<*=$N[nwS#K ƹqLuxRSh^ JcLKKܮ][ZNAq^Nח/<290+tq|7A Y&+$m( ǻIt@SS z*v(~\Do^vUEdn(tTxZ1^ҫ\TLVDynV2lM(be/@Rh xN^ /t ;6>9֡{0БUB5{/_ޜ=@/t@ pOau໓gnd w[̅]VjfsTdMYsP A惝BvGQG~0QuSg dj׸hmf46"g>v߿V?s ly;[&d7fVL׷+6љDZ܎3]A v[Sކky@8kesj'Y*5 m#e2YQm& Resjl:j6)K+)VmEMaaR~Ȝ!+[ (1H)םi3)d$sU-CX2bTY>Kds%"m| :utRʸ?:3xkgQ 8.?_|vh͸8j䮏ePRJEdf3hBk- !2lh36E{3Y%E̹3찦{뿼iZAmK7zS"KүsN_thͷwhVVZfCY2>5~7K^THpw-I?V"Q72ĺ\(a\;sv. ~8'/ n2#SpGm$$ܒ'91d1"{[|rnjз@hHh j?Jn 縛Hd`Vhx&d<`D|`! M=:o2JěĘ7A rArF$pP@[n/{?.$aRnVήP!A~P@^B AGx!xË>,?ŗy3'3#{|o94SKګ)63`Lt5͟icFir_Ql0 &>+r1/W_GxM+]v~m Ulney%:oiAU,W3%]OtU019_p0%ߘߐL'lK_ێ#Z61h9YZ㒑A:{ u" Ue/r6W"oe$V]svBV+£-MgPek^'Y}QT GSyBgs)r9]H/ZDh9$Ner,}Eq!7j,{⠩+;nUwLNr$KMz]rH" pQV*6 Qe]s!NKs,ԥ֒N}W] d* uo\ND,KE$V=5?:]?,$4!A_Gͳ{K-kǚ>wrK^BQ,c+[_U-YTR ЉN\}Ś/?hy\U5- hYY]ql|qEj;A˪x]T9rj: iO{e\k V;!]>aGshq%;`ZxecMi (5%%o8~I/Q)k͑\qLh$05%CKLՋ,6a`Bf±(jh%l ,tU`g\}$Q0oʚB`h?z#8 kur뱶B <_O}/"^N" |XbIں]R0Z 媰.e5x%&4],3%55sʭ)HtY yidv,.F" VSc]D 7Pؿ.ªq7]S?ˮXYY> uJd("!gf,`q q렋`+W|[rU5]di,> +HXܿl`8+WVKd'kYTKU{0" YGEܻA ;XM>V[DZc’׬YwzpҊ<\پZv& H(܎eUK1m肗na]"f ?ٷ8XJ}"aVz8izYWӳzwl7VL\R6ZM'mʯ7yv%E޿A1joըkjyO{^l&m7ZPZ^/“MÎ:p^5,+]SmYڥ*[A0}wQ 2Cɇl^8Yjc{"RxYPv W<AG7r+,+c]WcG 7S(,Uc>rtw8m&*t {EXՅܼ%^X`6Ƹ,,EJJ}iuv#2.+!`$'V`i]T`aa Z.I_. L2bjCXY.AZIJ+J°(,FM(!(",x&`Bo}q"4FaHXr}. Xs.K\ULg,0 m3CPTG 2_ m@   ̶q$ֶ-HXP{3qq室G$Uo E4FР6g#KY4Kt5ώ%&H 8  )$4#fE@}{W.+±֚t:kRP"^p H^rX?G5sc|i^5em/.ci;n2o!5o̪=ܵp*g媧A|y3Ӻ(4u띇ߵ9`.S}7U? +c_ kv]R3Վ'J?wVd$c'c 7De=sܥ%;^y4eN1mݬ{c;ʙ8˧ig$UsPGx !%cͿL31oYBw?!{C8ק=~jC;@5pߓ9ݽ5]9;I1Ne?=?뻼_zLVNaxەg ׼%w4+,]ҚoEl1/:TZc E1VqNTڧۼfpP;p-cn3 ~kzUʬB925RkO1+]R˜Ø{pJlԬM xK ;H wzwg9NRAw|`eBLWVԲ4\uԶ-~Rd.,$Z/ֳe:Ǻ.*^):+Z]( rTJTrv1{3"Z.&$g*|1R: h*]j ,\A~Tg]1xqHre*+AB#GN(3tgU ,=F\[vb'5l<,mxc,O53A.[Ubfl2\;Kܷp $,O{#ws BH[-{FH7w7QUxhc[d-yzbx+HEMXi,bղXo$ }T=먓^!䵌 Dhs 4MVY2ZÈugaKE[5\X60?bx"k_0aTMU;s򨫕/HG|qg'? q࿿ -K8WTm\*+[M҄o@p{]eCw,ʞ`W!R=m8pliS{gywkz k%bb?u6!Knl :oU+;rDcX8[q}Cqcds g(ԭof z;Uv*Pl8mc0qr'@n5IRGb O6m-n/zɾInp26D oWxHbϦ_ I%$mǧ ?ڗ2V3 a?TdoEÜTΗ+#h3IwoݕNϕ_~s )ֲ)aㅋ2r׾ΏkW-Z--̎[{ 7;QVZpSB?lu&oWH]A+Ut$HJRjsqav{8Y(P~\g-a+reag$J,H<,Úz~X}H C)J %R2}'a̙Н"6l?e1U,g2AÔA|ۥb`<a]򾀅,[kK*#Y.4j ` lvwyB|}>@ |0= B#35_^%.siNI@!t"%$Z(R#@‰B 5db?aJ[,ڮkmom﷽ھq!~l{^z /m,*2$ P@ #0h7%Kڕoc(CK50+zwus^W[Sl$ Y 6w$Z( ɀU߽{;bfuP[RZ3 PM R @&!?4A $RXǚ%U6 Dd\$9(Dݡf) Ò"YPp$h821994ɑ48i$AR%=Έ &;=zճKf`2OCj|&c7>:>\Lwȷ'XΒ'#hM=NN'$4Dq.΢4f:DǮϧj"0WG\_qIPmxDY 4 qcMU;??5:?`À tf`K\D2d@{Og:L/ʧb ,Eխ^p>tF .hKz2 3H6fM !Dc҂j$,-چi_[mF.O'ԾQ7+=,sQB.4 7^j)ĦG̥t406J V=&tK@e!kاkCr*>[2eP4WE$!gB%؎(z>uy{!Lf*aZG8chRH+t~iˤÄA'dNم@2rL ,$yGz"0;! 4ʜ' NW#Da/hJ@AmA!%clPt#VDž)a~ƆEOؘ7ECE#"{|1VsSKyQQLMdv[8+|ZF!]v{X.2QtYr5R{0v )W T=D! 2YSW q._|IeVɕ"SLzJ7,PJHx_GN $Iv؃:/51FK1Խg>}X?fndmai>U3qu3E Z#JzQ2]FԊ c&7rh7qxU($@@IFJ*Ĩ(ꄷIb&7pBffDbOdHhZQ9EVE~R}H`]P4{, }(_*U-B6c0Ȋvuz0.\]% WV&jM>08ֶu2Uą'_d89*hTbӑz)/M+}PAd5Gf\Z zWb*˘dr1P9QA ZmbAq/x(9y[GӦAѺPbkxxVOu}#oGW/]I_xB*iHV5M 9 ,ט`ǎZD*Sb1(2yU+$jqR$(z5Gu= TuZ#DdV1:*\Pml,LTȍTj::XВS>0*ϙND3uI!TK><20%Xt};a$÷o4d5E& dFdm,M";VOA-k,@f^BZ "W~S*Vcet|Oh%'FȌM"RL+գ:DtF* BU}Xd<õ-\A"J_tTBa{%3 ^drZfT4Nπ=htC*WT5kbH~Bt͗.:|`@TAVnjja֤]!V?sՑrqb^Z K:vP.rGQ!HNWs "*7zK|U0ᡰePf:SZ0h5*qw2ڞXC+BznW4k)LfVQ*z,ۅr]-몸-JU!A~CJ]j7њAkB\D)=jX?^,9"t)W B^їVET"͊J*CEiM[*Urw@؎}ÞUsiÿcbgc{ٰm7eݛxq} $3ް< ,BGЖF4OaZLz>iǃBjgnwumxMYE8ƜE)5TxS7^ݶ#KǦ?~ueu9ڡ@]Zʧ[hϖ'%1;ctW+3>/^ nZAѤ9Xt i-Qp C׬ W^S^IODwvBe_^ h?a0sDd*avUO4S%U1J3IiiXJf8hWګ]0aٱ/^M"bjfx@w:,w2CI-17n-Qt߫WGC.(MZuWh~ sBHc0%ְ̎#Xӽsaenp>gjuYLڧhv[Wun%Lo .`,<I׭Ny%Şu[,7B!N.ΡNlt\oE/U)̺E?_Xyl~Ӻ\x5 ׍[ti^iXд b~X>p2 J"*QvfuӪ" 7cY5F_@9? 6SSyqH"#auo.O9[=xgmZ }۷{sWM\?.31XYexEs t(FӚ YSS ae4Ak#׋9^sE`mص8k.ov[_OZ\xsGc.@-T ն+ ֪*M\Z9Lb%oԪTJlKN D$U#*J*;y[v*,h\!j]w{奄 ރȿooxo8?s)c.t]rA_TtUfa !_O_J|(?yZW%NE M pf F9 ֪u* #6_G孅C؛6:Rשe(1TQ*%dnRYI1K|W lby[VXR9@d7KAX,NȚ$Uc+42ZťQcXfs_jG5t}-(66b%Ӄо:A^=gB,; *P]eIG\Z֮"*J6 Vg\#idC`:M,0 OIek}_.Wn;/e[7ۈ> # 0g--k F7[y:պk4OgT~U#fnYBE{ūZmXauWX١8 +T­qs.O?KFn^=n/ m!Ou(]51*0̫? XSLiq+Qe3y(cK8-pD,B\QJʙ.CWnwv >>;6_mfiX@8Y Lb3tVXno`( lA/"۽h%PkkV+<%a w]@9ΑrZw[P(+,y>eܲJ1oZyLF|3z*f/}zWYZ:ddRW4$0HA+ɩ 0JT*%]ΐ!٢(CD'ZqzKdVuZ<ٿr6~m @ڋj?_ff6]fqw,  @ remn0`tg h_Q;ѥhF aZDy 0toU x6+ t˕]pwGŒv\4D<~VɚW5Uk~.z\_ & V0,WZKPzu_)sJ}cFT2+dC:4֦>Qa#"*tIxNzwuFՠJVb~:^ۘp8@o+0uy(#<"KX^;~0BqPG0!4IpҌ´^D3DWX^%Ý0+ґMu.Fv浏+d]ӛA/$_5t/hF , v'_RY%%ZDMMf*QW/.!.Q`SJJ)sT*IUjYi}ZWd^w^B[7Mnr nh {x#>j; oŃMOK/b' K˸@xn#ejNgߠpQ\աVlZ871^}m[+eԑ._enk΄Rpȅx=Ln{:L%~Oj2JW.!v^KTDOCRA2BJ̅4 0窔.W]U^ ~4UV%;op// Ɣ B-I$4\sV 1i+XjA8sTv^HE*:}).$H6bw9&HR *XEFC4|)d>TәZ&0U|,8]p@BGCĭBng9qf=j% 1-EMrʀ\ꬷ]f"!VuW ڕ:ovcGȮ(z-0!C p"fxm(Ttkc:jރg^qdV(]rv(4P 顱V?cf$ׯrRZy!dbBXYbpOjksԞ@`8.#y!K!08=.<3|Δ nh%2.8֗WCű/cb[X._ʦ_;flNV ,9kiw\k[&~l\]'e|8If.?Jc:ٴUWQTOo^&;]6 oEQWJܲ1UK5dv:u4ŢLKDWfC\w#S!EVUmg-9tK pn0!!1͟ EY8 V([-0Irǟ, yF.&3褯u6X]X҅{ƟbMɗEL+"AfQnsuK@a;+j`U\KfCSu)t%sy1eLyT*h^DĹr%T`(OB^ v&4z+W cQDJa&.A-q!(G΂D(ay* PǻAҗ-獙VB?>!ղXPטlal~nDEpiY?$ߗ/D3+q!c( E֞<\N׭yS4f$A3NN=߮t-j1\#c|-x'#B =MP9`s-+w;/@/k= Ε ߲3 mdT;<B>|;l-4|B\:GhhD JB}6yw6ZMxŕ83pKxKtloGQч\}/>? 끣ذ>0ݰJ 8y@dV!nvOLE,[?w̉&~ë]w3kfH{tccDwYۼH >0gj? XXWsOꡳ)ÕKL~𳍊L6!p_2>v^ S*91?IgWwR1HǢ騯1ŵGW6(7zwRz7AF+_#?l6_~ԟ)>tE?&rmLU)wBTޥoW'>F=_KoQU1>V^q7 W[洷W8S.REwU_hP,z=t v ?-ncfH؟ O'V>|OOM;H2sś RŇ'>s♧XS7ONߏ>V!?hހI6<`$xGD0uXE >tM\n֤LrmanJIk|ߪy0VVm)q،~WZN% -6csM_֤ C> pt<+I@t}f{1?ʇ4rKY&dMt8ޏ,%A7 ZNA[b?͙Tn˂n6LsmiM(;yF!n~WOքɭS,.ͲG:'`'rސ 6& tP;14J~^ Ζ&ىQ\bWaBƳ12nvRel^G Ɂ\716r/Njw _*D|8/㫣a.hE89TE+aRe3e0 Ϥb:;oi0oW0z F~/?|v;>Ꞹѣx}nMGo`}sz]Gmm{|C=CV~;u0 z<{w]o` @tGr'eeM[l>m@@0>@n]]Xpb&>, >uǀK 1 @aW=L0I{YVԊN5up꿊u}gů/q lR[zbȷdY|Z37_muO2%c 5Y YHqmU(K¯CBS6fhcOa~K+RfU8_;N*t#|;|PjB[,ejÓ'Io_zԼ[ e!,'U?lgd{T=Nz(o_|Tcūf7 sq^PMtNzXVZ:x=Q>Ǿ2xr_[Xض@{Yt6(] diC԰5&.q_whؤcn%jMpVm16Zo ;'Mdb)3 eAO |_s2tq4e_]q^.4ĘiH4~[ xvɫv\$~в^[7 Տrgk({&'7wsuZv 5vM~f,=ܩ./BA C7g7v+s&Z=^ހe=/KY|z&6glzTw _2,A,t0׊XdGѻJ0bjoݣ޹z'0!;]r]5j ?tN*W6#JgKMUĬfC a?ɓ\-&-+:+|G4[z0/DnW(gW|KӫwPuq*l|q5 Wԍx?[{k>Kz-8j)Щh|ÆS0czSYV>N]|yt޳iQX@|xu٥W n3S6"`MY%š: 5[-%-/B'(93m繜vwwm@"hd ۺ쾃~{32aRj#f: 10 O< / o{!,7gvZd)BR  iDs>z~8t;pŮ[ _dn)@C_أyLiCGzt<Y|D[[1 ~ʼ^~,&>l&*=z ]ژl'IyVj4!7 _ƟGwЃě/25uekʆ[𩁦&_DgTY-u siCWPw|P޾0_^;RxD9yzzx7VA͕Ibt+tQ)?/E$ִ҂JKor?_)D~Wz="0ǹ~[?;ҏ~(!-Y=괋EJi1yڽWWʩ_V͵tjN=ݨ#ԧ~*'=μZ:(!-ǖ{zO.m -O'J y:US7T8t_Lv,džz]Emhe}~}3;u xĿF둨U/Ea ؟qXb<ŸS܋WK^P Ov`Myk"iju@Kv/G_;ßo/)-)/¿:Kն`@P?e1D #7Fw-ٽfǓ֫߯>djVzK";Rw#8nY~Q49qE>fćIi9m输̶/a?QݗlX01%zOk@SWf[cK6  z =eMPbz]Ӹ/Q3e>NHq#_.܋fuw(ҷJ"G}]M澶F=P͘(LLG^U~]0ҌE&KəSe'"5'73"^Y ):+"ȞzBafhE\BƨDi™2'- '~3"[Jo2;gc&93|TNH٪""+Pfh=opM[-L{Zx%O>ȱ¥f$e!#ft)*J ƌWnlY`؃cy %F I%~ J=egÿ+KU{]n'dT_uόS "83--#v0{>MMD}=޿ZhuS;Jb<^\g¡ W~E̴s[t,,kIbrM@Ǔҩ"ʽT턯E ,_>3&?Ń=\;b7oWebOA۬n9ln` NJF"{*2B8331cm-ܽ+&}d}9n"*& -P*}ZV++w~ao}x*6#s/~V4ȋf0ڧ~!:~?[ߓro<3mrnfR2fB>/vel޲nzYwT^+Uss5xMz*`"C6W` 3̳;v2M{swd  "8'(q*Ƒ $" _o[~{@m݄ ==k-ncJ\ƪٵٔ]N"K+ n2{ 1Is+kdLV#LP#(L ?&@F hr'{N2.,Yȍbb(c- h 蓈DHD@&@p~ ,Q&&?cgY_wxg5\ˢQ-#QǾOh)ǒƞ(q>+d]w0!.9KiU ק謇ڹA\V*xҺ7+|cvW=^WroVn.IlPO%JU> ?iG?NT-ÁLEDyA!)>\%rɁiate7~G*׵;qWmm۟Ix-\ݻ niE{'0λרέg5__xy_‡:˼&3=[H|'C AC $sbJ~ٵDU.}+{ 9²nגaǹivQvUni=Fbvz6vqKk^7F-axE؟%, o:[ Vlz#]R>A}_П `?AOz玈G|(y,y#<{,9;뗂]{O"oInXoZƾ=ۊ5ot҄ɑ.Y)m]HO2/Y2Cˊҏd42?hY*\:SYkq?~$ls4'+bV/{!ѮM✖k¬\ ¼[#v/cn_[ MÚ gWu_ ;'^u2_FT* ](k3ϧ |t;)2 Ld#ʠ|OXw}ClZH68@oꟌvn't)7HH7b`:U׮:磹gr5GqӮs=3Qv Ii%hqꇵ%]Νdz?=ƒr <<seh >Kd2DF>U9 CH2d6U>@Ȑ?dʫ9b C ~D Jޯr C%C!$!Cʐ!d2QvY:] )49 Cv8X8yAzbi\<+ =dqJ3,C!D:lC!!C!ȐA}O >:ՆoyC!,o19yA9bhؾ8CEɍ}WkDREGE?ӱޟyeygddp̪fQ *)23%)J vb`ki_~|h\oEBȈ-UCw2LUe\ "#\JMG *>{Y"#3@v> O6qO`vYz7ٲwxjw9%*ɸ6vEtί͢Dή$o2k_NzSoݕv1xׄX9Z{7=a=g6ܖ3˛fZ lxjs++:yyh M6FO)|o7c[?1'$q$geA,[Ot;dVWlLyvjPv'(6= 2{E|n;.vҙKn0D熓&N:Pu#Ux4 12I;pϳ;)6D;ة49m6D`7;0J+9w'&p0lB7#\T=^(!  )*]I}__:ZZcWǜy =|P9x6Y1<4qޡ}6l0DcPѸ II\K͡P00 eC +78ne{?s$CƲ/WozgP?Ŭ4gY!䚃0-ItJ?niSwVGg`ޡVU0nSQ\,CԆV.{뜞r_=_y pRtQfPHȻơ?"Mx$F9]49hak ӢMɤNS cT!i篔Y˟ZyجNo긄E0uө^zJX·wxQ =>WY$qjdWiCaCė9GF/y2<0eJS$MP]bFߴ~je=i''#{hor^(ɦK7vL8I ^,ϯqd2 --2~p.2^ﯙAy-nM7*C|,NCM_bF~Lg"BJW: 爲^pEWv q;ӥv a|1y{ CL*L,v*ɓJ?ӄòO}_ŷ)̓ZE#> $wHjZH0 NFej'?ʒ8bYo"@rT 8eF]QG=cu*uχeH2tG*^d4e9̒?U7&Mj?6j7}ME<-bU<;v#~}ǖم:n_W s{yB?:)m~уwi65\ Z0@c1򣐙Cp )}Ių|@>ƥ<ťKT>]%v(1 C0ndM#h9HpJi47v8:D PBtC}}ٓg뽻_Kg-yHBC!0çS&p, ~8)@֭/8wd𢡊T4™%|Ow3AXGL&v(v5jHV=1i7WiZoؠw6]܄DtJo]oP>peFE(5A?-ɿ蕳Pc*"TzIz JIGB_#݇ŰC65$l]Q; }^Sو}ޑޑqM|iZV<-Mڦih[8'2TUb1,,vwAzC@;EwNg{̯Kd*ٻmR_7.aǻo>f jlbN*@nηK=Cv#{gͦ6Ƭ6 +n q)]z–|C(#O*c'@֡fG5:5qPb:Tb؞pG4PѩY%E!R23z>>ݍDk{&׼ QZZ[b;OX9F^`VL7J_wS =$SCq**"^^7>{Ye,;a]f`lPAb݊ mN@1pjNNw B@nMX xXY1_+v6z` vw]є<`u^׳f\b[ѦbW4!Ou_.[.͟7TN72AG:.VAc Ef};Y'"-et^zWAlIQ KE0o*cc_ģV. ht-LNx)Э*Y)˝ߡܠ*ec2FsQNܸ`1@jhz|r~v@T䢭2tց53hTj= ܴ/{R\9o1~c]ȋ5^tOTn'Ȧb;Qucq46_pڏz㲨yP)5\준"h&||ӕJ ƚ$pocY~N]F?n X,uɮCZ4JBFv#OǷrFcoVfe]NTxM+ۍ 4l@~^Rqqݑ,.*&jNqnv6 ܵN\ՌJ[k[ՙU^fwį8xh*w|T= nfq!Gm}\eBgj`Q?wϻ)G3֗ CɲGg?OSmMtC[@-OCMZ>pCfSpӟ %OVyc;j/ d# KF~frDq57]ؽ]KqRx.hn93'ldx2~khZo #%_Q<, C(bq}Ƒ99yWuɠf4?%ԡ9;|^{~WaPKZ-ki?_Kx-!}H?ԟr\d4Cbuweǀ_)G|9iZ]˄Q "Mw욖owF`ck\@k]VJYI^ BL*8_1 N8l̝(mV1_8 ̈]KĦՀ,T i]ZX%K_%˻(ԡ{:KZe~f!|̬S5)6Y/^W?ew2bAѨs}\1ERGܲ`evdbcxw$ v ^ؠ1O)71rzW[F5~2۹vn.hA n۶ ]H]t~' mg}z;.\r8_ #.O8QE']7@Ż:](䋻lH^w$nhOu?j<]$TO$g;ìzr(N? #sJ=כk,JݣwaJNzL;b$^9}`ٱN&R;F[]si>$z]P[& CHwV5ouZB`A @> 0˫SKŇ!ShOqU7 >Â͟h8+:&%`Nx#ַzZcVy ʰ ~*çZ]2Pk|ق5!J7 ob;4,fTFHwdj#mz+D5{2fֽ$ 5(KS9߲+Z%%zCc,igmq{h(+b=Ffћ*)+|3=tFX?]zmo,ßC ܙˆ(HV2F*;bPqz  Awd!] 1nd\>'Cp)xAP1|hgцV?fUڒo6eWC0&؃M?ev#$h: eYʧw~<;ʹ\ETos:D̉ll$~? r"b43Pn++dB]"e/BjB+E2(lkլ.Ajmetkm۶w֮@fF qڽvO v('{í-؃XIv hʀ +-H ƭ'Er@D(@'E%@P",@.M۶in-5Myum g k-3~dPdXdAPY%o/:UkQ|vTd)ڮ&FBnk%fT4nH:"9!fvZ|v ?nG%/kKl%i9z9[*qu;sɘH٧tCMLYm(&~0R~!Ž*[>8F!UT$. :ݷ j 5XY'0Xrr|ܪ3}3.Q0xzK;4]W:I@F팺*\փhBc7 5k8vMFjOgiLP\:P[cpKyy[1c 6ǹD9-_#Nּ'NKnr<|$wr~!x &{cij?RT KEҩ C+]p7 _⍼xrą}5iO{΋>s?E(6Wa?U ᰴb.+`?t,. jTdRB7b@Μ C0_)6guWAxݯ] h*pǂVX+.\-4ֳ䶵<r \h;?`XyZ%v;<!SpBB+7`K>0PFW89t88! J NM͗Վ*hz`#y[1[Az~g0J ` @"SU\{(wz';i=LL!@18}#9]C 99 Y}h/ߧ¥&Zj.WapIヾ)zzhaTuSD>&y:U8Gč;rC}䨬zaP|WcI,%ъAK̹2 <,/S2&Qi#_!~!bTO’7cOCt8q2GpokȏddウQr0 4%xKdo$$71?X6Hon)Ht(! "FSi*bTOԏ݄uF47HRqB\.ջ(T! ]ųMg0 dСq*n,]q L N3*uT3d"::vU޶FHʫk*c]d&0uQ (ʄ>)٢Tl|z'(~ ;`:ȲP/3>s %B@ܷFC ) O^ܘ_W/<[H):GFk?C8SDmd[btk~nn*g[̭L#E;vTQkzPRap72/݈ZMIdm/>,EECjXkRgW/Ds, 6 )FS]ݭiziaPU <1m=;Gg0\`wj0T”7cSkr-/-\ j*LZ[lf¼Ybnq(`97Lj0Fz'g>=cT)zi둍RaȋxQOrTH*_$8@dq(H#LD+ re[VԊHh0- ` @+{WnjB)9=1,6zb:du !1" B@p8 l1@4 ‘/* 8@)#KR%p PqKȿ() B%OkLoVA&1vEP4}Ůzs<R.7=6  Gݴ;|Ĺ^nh'`@ 0`Ym>4b{~΄@|}(  ( (  ( :f(9L l!2PU]nb^kK'0i&NDbu!'VcfP}dh{[8',Aߕ XbWZa0@0@ @` 0 `0@ v<`0@ @`0c|_K:0ؿ 0k6w]g_^lN@{8R9D "$2U i1?zV3Wk{ZPq3cC2 )LJ"!% l@HDjƹAG~H|?mM_zP %s?O~|ܝ?FgN#,:C'Ϥc߿? Yn)h(4of_5Mk5_CQR}K|7 3Ba.@px:4qr~ 6]W7J=hc٨6yͿ%| #W)`E@-9`'[`M0~"l{0L ~/h+(XDekB(( @6E>!K k2 W5Ya Z*MX}`O oT)`¼'JQ0v* +Wpĩ/ϣաsn֋b-/ʾ@[+ "k^s٨KkSjI _ lw`;k Bt/ CwL>'}ӇUèo<Ҙ V m42pg_P-Z }dD TF%)2,S\)@*B"\v0_evΞカ; 33PDpvn~3aU0!(n $46TZ*- ^"".s{ 9,@ЇA 33E`IT5Bt2XbY@%ɶ-Fx y_Z9h>ob{][_m-ٟߋvEh(]PY2#&r_?m ˠ-&duDxDۯ@Q=*H;e?:Xk020_TXVF)Nbϑ{2װJ`vM!|$$q&d}j8JSXjR~U]By Y#VɐpPP+M"1%a 30%ʊ)|]j"iY$! ׻uʘ:k:j͎t&aL Ka/Df*7*WeC#Shb_&1qd7|yYɦ阀TY$#z CC؄L&)(L%h6IJ~-#~$pTgXĞąs49y ^/yz2 KsAuU RyHY4B)=Jluƽ+P?vNwd*?TY+@tEm3sISLMN*5!ŠqTn W9媔. W)t}=5i%;0Nmԛm*=C'Pe8vMSyOU`*vⱢE DNe*+`u+}gb\DLd5Ut_{[#Jik"Eaj6 4o/uVdN{ pHJq)O^)d.+5ugC}fJSXjamx3#xrTu0u%؈aJ";)S,.{z?1*YpcZzZ\)dU{IBxRM, rpgU$jc2*Gč"oUU!zy.Rfqdb0V ;5 ƴ6* /Yzb۽vV`5_e/n|@1-n8޾v߹zF0u|/mS^Jm9ѷd7:Pܿ1 ք>40湸Чy%*Mae}?̋:n&dA@ {({zWS^JkX.p@Bp'o{w= e^Ts.BqH4uQ<]KEo[3)ſeo3rn%1E\oBF#RqSSon\OVM|sU!ㆨ3}7*)fkTXx\&r" Twts{lNܰtRpoO%LD+"3[h^q$yHCvwfɐ"Ґk[]{UNN溗0iJSumq$BR>Hzߌmy!]wK/>f>\Jg©u'̃w|x?2 *Ȱ0YiMSVߨ]+ NAJ5] U˟*7nm.i{ފ-?g!4gU^hڮg{:nWsU?vЂ5[*"|Vzw(5S4c_f~'fm{͆_Ըo9/t.c4[~ZrE RBZn*'NyvLY]atS#4I/CHŽ mvoss7~V}G'tPi<)2~9ζa[;ސ+K}"ũO{3k#!tbPV%Rpk6½=!bt|kLz#ў^~eINw g*u Y4Û@u+mjܗj=!eéN \56XX-rd\ϩb՚Fx;h.A8k_h흙!zWs-/, {WBݥCi3<;4}_Ik;zVr: S7a_ۅ1Ԯ70}#?uiq{^ϗ[pP>azsݏү"fl&'K vX5ca>}o5|5&"7fl'+kRfa9FyTvNȚiLW9Fo-wȃ0$biK&eswVASqnsB޴DheƖI_RTuzI25ZNoְ܏oBW!@X+n"Iҵ˒ǿA&h [_䚍i0Ve*M甝s=|Z_:,K% qoz;U*w|ž$䊦8tBq N*"$ ]oxM ,L$TLVT-3*+;yebΣYgC|% H6NlHYڲبCXw_l yшp-+*-_.{hTE#wgi^k= %#0`NmF{/ CQZh=H%1aYOx`9 شp^{#wu]~|xOX;%X"-\I`R~z\$IesF xL3Tǫ^.e_[/'Rt& Se,mjN '2S>>s"(,rc. 3@X3J=TFBV1,>(U1v;!t l6JtKTW\Z-\ۛb~#ކMZ!0,a]eVO{Kxh,\kqwZ%h^6ph3-q!Ҿv0]}uiʼr[)kz@ +=ɘUƥ0K]Sٚe)3۵Mĥ;vY!m~W6tL.[ s~U>Rr051`W9b~?6wzaWP?ӎ5gWTly}C{aК9B˦'K\&$A#^oF ٘yCAO!R9 a^J@hPGx/ O e& Ѕtʠ~0$ۃ=챽5诅^.F>F?fCrh ;AbXT+B'_GoπeT*K[9jD*,q/h[ep JyE_H'RED#XHvЃ$w&{mo', \QEg$:BΠu'«E<əQ *Y6e0$mxR^g{ujKZ OUCN8y4'1RB>::q< ϙ[^_plsC.+bC0 3#8UJԎ,*J-GR*.5?ey 7HmgpN{4(X_s:!X9Q_|Iv~0$ᕤ}\SгOԕQu9EЅk d^:TT+b^L F㿃KRnއ&[5h̯x{`rHxw5 (4􊌣 ց<(o;EB:Eup<4`Rd NdQO?0H){ 8lSmv=j~i YF?D_.?hЊs 35`w潍`>`ff4Ϛ 8fg.B)rދ*~ =@,d%'RD:UrLFMTyqDdgjdvW+Ň"r(ѷGPFzwC1vʡjj'!KJJNa3؅b?\x},tX A5oO?&ށ7~O=<|'q׃q5ّsv(]jGa(LBތRkNd\I[DU BH2.<.yg-D*BR_" wupzXbc?V}D@ zxN3BW/>x#A!4:&ʘuk&zլr)i Lz9va?x/~~4ު,GeR\x:7Lx*}J-WnU\d>bKY?uw_j$} _QgSFq~U8 #IGn^j?;$>^Kl}wq~K SN_/ LݨM{kLlTW {Wѹ-QZX.ϊ޹+.#?G!<F^<.抟jĦC~+`3Iߘf -icݞKKdtyχ'&#@vQ+$K?2/""WeDDq>LБE:ڿ~!X_i ,tdypyKaD^y©T Ź$\~/W&2D"Ԟ8lؾ"SLd;2uHX| foJ*)6 R ~Џkg2:@tV#A> @6TwwؑQti=-8obM8ny[x@1-3y2y2qac S/7o/uWh)bHtaaҊ pYB"To ;u>/xt N'D8t'dG{ƞ=>rN=l"iI$WO#3.u=12.. J/o#;?*'<JgjNc[ &Nz[a~dDi(0 2wf3! .^, VxӚ!r3VVe0uİoQ}+ Rsu'pDp{L6oautNi墛osM/ަHWG1>zх Os rvu]A`8]6•&¾B582m1`GO$ȊƲXӄqul. n7l~\o[ : lcN, aq AWv IxNwiqd10Ŧ#Эt%%$H>} R)_b&HO8IwI=v'`_?N_>ǹI:Οp#*bMXpqs&2$-I$T0=*K 1x'^K~\LnRL/4—mW>_eΎc98hNsVx^3̬2=JϼchI+dϳp?b7T> {ws~5츲=V؇%j\S69 YэKTW, ]qD:V-+1_O]oJ}LB)',//s礊WX7C3;R-POܴ,+{ X~p T  v*!ͦp9;"(I"A0$9*\ScC*sXJh|1!,=Pzܷ·˂ʣݮ ey9t{ {߂[^ϔǣ-v01E_Taʈ\eJY7?ONOax>( /W 8+Me^?|}yU@ 9ا"PIA,`ܠqTEsɌB8 9QJLO@$  읗P}pqZݒ+Uf,Nt2Z5,]4O6l-YCnXbb8^o\O|HWB$l_?Ko 39+;2*vbXiv/REέ`Cx$v/oÝNaaPAH<^(n\#9}D8*SO x7bU&[Kҷ-xqh}\ˇ{{"=^]ƊCR*eO7H|h7Cape7D.b%Ch3$eXmZ^eY/?=?y@cr̷٭eQZt{ZAxAdW jn zLșGq>^<@DJtDTOyHbA ֤ihH11hFwqJpeϰWj{N)qpOw!WC8CN 3 c#+X^]O< ~%]>TM`iVsBvl^Ez1]ʡCOfu4;O8eފEkZwtp:U[7ɶ[%d5^FidOQSK"ަ~BCu'W.^Cɖ|7L| S1/ ò  @J2\1v^\ GS; //`B fR|?7-],Ehvgޗ]jCE&P ЗX`(h#L4@Hn[ eWq plV+8.'ty2oxUxҾ2O 8*]XX|(pQiQSM}l漶eֱX]𢚽\a2j.+(ά';.O|ZWiGDx\ΈB"O"s5<ðea%iڋiEێ=ًP| ʴTR.%'Ғ%Ǿ&"#RMG$AB_sC%!D%$@UT)Ugoceb|2[%&`%#2.EEI?)W++ :j"{9eQ'(-[ȶktٯn#z88@:("b"Dw/D~wx__=VϏ,G]xP;55 h\TLjˁv_25)Qf0@SD^%>Rnʩ>oQ<(uN^c鉆 납-}Q\+#͡)FϺ(_?-qXt%W/R iѵ,^9PED!8w0/Ӿ]YsR9 SÖ4 )h@Lݓ0*9<˯6Z{zd?q\U'5iԇ==|#m V.xpBk\}xF ߟ2D4`7Y_qʦՇJ5`w{e`uuHH(DQEJ$;˾оo\o6>b=õ+xY9|>H x}\s\pjU(( ލhs* L%v#}Bmg\0o]ĭ,ث:bT;4w03 RGQW j%] `x? 'baaYFqgYصGȋH_6 [ސVodJl{krK=E(Don!mmoQUj܍6hAs=p6h6}g׻̎` [vtϴ>q ƬU8.}l:Jb:PQzkV:8~TÕz 5o2h9E/w7*+4W ˩ ^6Jc حAJ{5R[Ñ `{Y~jL ?n շ̓ZrRM-!.w~p92nub;neb`ߦe[G,~1/WŸ)Q ×ܿ3l$F!~(jw[JX ^wcornxn.xk {h"3 5xSmrj۵oSvok G/ɀhKե=a8[6? =lo9k;_| çl,LavS0ϴ&6Foد}k&WFJ|v꺽Wwksij:Ay4BNjy> լVա$>ra e+RSY U%2m^4ܧ.X [zٮф];Ԕ>}Rlt3#b;[\(9|_#8YiY9#%:)g<LĝI]h_u&ˈ]F oAKE ܅K1,jm$EHpYfXedOo7,$M;vc얷0V nvehq{fNdR!~b|:ݗ$$:y8`v@ 8AZk-tlmSJf7vgtcvDw#q?DiWtx.6 M߰&j՛Bi#<~2-ۅZ{uW=5kyګCCfd FV^ B3oÖIҳ{6g56#&MQ,Hae]"[k:DWðuw l y )R43xֻD0' Y3e!3"ArDZ0Lh` qaT8 o1} g_ •A !o>R/*z%%~/n^F=&f)'ڼ8vUqpWq] [1mC6[ۙ|*NmL'*LZ9=қm5RY*5}p`qz} zFԧqONq#J 9V6VZp`.iFnmN>ޏƸCG(D-1]+4p4%=߶#ߌJ%[.pU+*I{PoeY> KcnoYyH{Y=xg'38Ώw6qͨ y"f%9[56wbN,k՞=cWT%'Nv$nnbdu@tYaŽp z.n.kf:륑NsMcabk3no&9vw`-ʹnFUǯ_G낯_ohOloV7Yqb}oڷ07u9ppOA47Wb>,"DӂN!2:LK9pxTG";NΏg+4,ApECB!fJP0 x At`IG,!l#BedegUi1BoZ+NY3y]hʿ!(),̐U_!lB,6p,$ 5rۮڵ1,\k8:m\ȁ)⯧)n'ilWZ,VzeIP'AHmGȕP8XcHtہqf[l9&f[M}i: >[[k݇!AcIlѩKֳVD%*nqMQ";E=)L,'꯰`.?)4c_}2JyJX)"IJexP(hXy.WDF\M`8ïAI"_|3­+ 8d WФm,K V۲*]if˗%Lk{*~, _a,R̻|e)s/Z[xy`E Wɧףv:2=?W_ ,NVk4fۧ}B77t@F`¯!R-V|U: jLlhSuo} '7# # B_OĨq,!;l>R\Nl(\YC1 "%ိU鿒U`P&Fp+~SPNK cmT-7. 8Х],DJ VY] o1`".A1_P 4IʶKAf!%H4bIj*9ZH`r/im7;ַ3˭j,NڞSߍ F,';6eȫ0<8~\p+$ZfdL/͵SziY6Vk5@:uc)i{]q1 ŞMmQfYY8c_px~V*.DDxM>ڽdkJ@INaJ,DqAd:}RF"jqtR𡼱 q"C7?0` e% ˜r+>r_<7kHBp +,rδ3% cKBCm~[LzX8ԈwΦbnR`.߅H-Ja5?]E%/*l [ j<Gڭcy-襠Ks}܂ s1"c5H]Ph?V&|y']٦uVy*`}= AXQ {žQAu6d/0ϴ:Emm˜@ch^T[t{][ql{5rwh: gy' uyI×7;c-2#9bEyh_)h萌5L~п_*C *s3$b qn*T;_X&P)b]O}wɅIU#.| n%g 3Аsva./-!b*Vf =|h˿~C\R6R !݌5, êe9!!~`|xxO]d:h#*Fp ˑ&u>&?>Tf!nNs[-lVJeYw{V@TA `8-lR,6:]2ƅeEͫWssh@>>I7|`S#$|Kr"_O@,+e a3 \>[|U&Dqg3׃О/-FgC B_ͳ0NX x8Wɥ`Fv;.>Q&TF 1WF};<<=@,uؕgA -~rK@-=;]pa(׏_\3`퍈;&M+"C7W##%/de/0p29B/ K̴9 /x|Z2y9P5먫m9ƺ*=W7!* (>yWob*q*a泎ࢦ`_zz\.*B 4dˤ ) %!-'uP7y.%#3)ݙƁl9~( @N\Cq,Ln+>0-<;YIQ|;Ls)JHcՁÅRU8A f.0RUIkyyl0j͊;ŒyᜅeM>D4"-J D2' Bႚv!` b'HvC/ATJ'ox77ސ=7A 4ϕxPE̶zԉ8?] sM Ԩ[o5n4Qx}7\A̳ƅߔY8LfEyN]›F ESB $#(Ib pSmVtwoYpl_ȭчќc1BSI2啱Ku+u CϬ bp w33:,oB 33Q˗2q[:E¥W s0-Mmy,%d<-/T :MZasE[=> 'FR#/KY|#琗ev_-"5*dX_B"ZX,,b,tQP2$I*y7ߍuEFfue|!nhV< ϴb:6: `t_KLGE6B'@"Z Xl?hOBr!-wˠYpn>k ʃ"G~c<$yJ,tz3D7^$0r,N$bMRXζA }T"kBZ#aFpG) >}_nI}vXKIf ơLPͲe|_]~?b~ŽWӗ[fMvޮW[hmTۯuAM&2D#{km^ۼ7ٿ\V;읯8@M55z-6Jr[UZFꫧ&12D& wLk=Uݳ m XsN#\BO=t>_ȫE#^ :Md.`#ޔ#}PNNNiwzh՚Ճ{=?\jQ"\7уTxtE]ۂOrI.ݤ^i`!oÔ۹űf˙]x`.p׮/G6}֞ 7\l-TwR[U>v }_:^~ވ(M']CNNj^lݣ5^M]{i}~JH" gEnKt*[m_cZf8>5=`?pg>wTo^*1!@V_o %M ?w<2\\t+{~N-ۏE%v#P/=ĥϰ$-Xg CW&7zWFyi xF 1DA}Xn H).!+gמt[`H 徤9"ʼng';dQ!7]? !^8}vFxC"wNWc/#8@5=?Qz&D(2D&d"LEo Q4"ff$\kE4]>lUa,yK,YUabLf.I0me)-2d6.v6WkQr6e hlnEMPx6rKfED8> _yz+7EF%(ͲH͢L/ :fK>$4iGU1Md+%xEP) r]v)N:ȵ ot Xi^:NIdQiIV9sͫ9IVt*j 4(#oQn=os:>ˉ}t1 @TzsZyRo+'8o5DCI]fLQRA /+W6dSaΏKaFQ$Z-BØ5'Khgavp[ҶV[/P-Sդ̰O91ɿ&g&$t$/s=6vsIFQ$T}-_3=UyQ(Wuvsj$3wl$;+^bYk|zTTR '{};3sr>km>آ` ^Kjּ,5Ɉ/j886së,Uշ!t2^[w|8T0Oۅ9H|*}֟ѫ3y'x]Yw)~2 9S<^5LbǯkDzT {%qz~-|(%_+;&\I(kVo}$͚E:Rc?ɶ<) WRnYKMqKTiI{|jP%B)ٮ:Q~7|^3g2K̥5VOh^3 IOk}vYysyswT3J3 Z3=pRZ3s;8[9Z̓%}z{q s*L7iYV7`.2w·s]͵ws/ә&r(˿ +6&1"J4+a-ڮ9xّrNԫtr͉$3eJ3tHY(^v\w+9FN44in)#:NF8Yy^1hag 1:{lI 1:ڶ$)Ũ؇"@@X, r;M}S;E<@pkV\uuVX7τi- }P8IWWPNlD# 9Klލ`.E=,g# Qq!iRI]B:PrP)hVl`BM[gv h HCy G%mc t@$G8,KogWn% Dwӱ BNGx/vTU>Sa]Z}:@4rW7Dtqh&/}.e@ 'C]o*qjIO/dՋ" R.:R3 iQOB5c` t,2r?y5&TЁTN sgENMJz\%˥U`qz$ϖ'Bz IhP^h1C78$Pn*gid!!(CJۄHEu[A|UZ5 BDUi,kίoE' IZ<+7T;J> cF 7 ={޶!!ڞW8Ӟ%U$anOg%UL "Ix}3EѮb=_KR҅8EBQ_C+o o+H{y_4"yc\k:'fzYW+8-ȭ L8l[ aDLEM,t$X$ e}߱V*-_bNF [`a|ōAV'-0jt?]H1@[E$eWfnw/0osLH/&x[#W -81u٢F>8!3`GPp{o{zb ˛vHY$gt!FFRlŘ!/ ABiⴓh_fپJHL7xN.;wT0|> #|`LN:#mQA"%7 Xei(?gLHZBJbd۝`H^gU {?GMHTgi_#Ypgha: ; i<7t%42H;_wⱸ^w؉?&TP%wM*7Oo$O m]:dG5SzƲu? R]w>넎@"F"GRp xj;VjfD"SZZ)HSdy7U i) YRns sʟ+y$ZasW@ɀi:G Ru%B\+@ (H!/S^l!@UHiNnn.w:$xX<׺2WH)IЉ?ߺ6|j#m OK (26$mRm= Q{s(ĩ(j.hZ3 j墻|?~41F8hؗ5$|D@ e{ rE"qAoA"ZUI1mVu]s0),@TԻ!SAo)0i+4 ;`Ր U7TNG(72d;DP[a>xCxH=x57phQ !J`j+ɂ]aٽ5} ]jZYJY%^ɒ H©@.d/^1YR $=kډkYip DIP8JǏX&jv:[: !Jr"]Na)-gV]'-H2+NfiSUΙݕumuU]GMo+g$B+C%ScęɸH~UO'n졢 ݵULy޵ n2r34Xm>!<}@)a ) @H Ntmo{[׮[ֶ #F3f]g}tDuj VpVtK+)H(с#!YyͰ $!0A߃! S@4``@&wa2߲m_0YL%FTkēR!k /E(pR%aId[Gli:+B|#<9pfZf4ǶYUբ:}"[5x|(t_/ccaPY_.;= 6zЮGD | ZFdaX:o(a[ӣCƾxd, kSLlxgnLx&a\ _޷^Y M.lȴM+^c#Wm}X )'U(ЍU#!X_0 mԕꦝ:aq{EH:5ACATUIxRTpOSuo";ђD*lrbz(9Tbo7:}[GňuĮIեET*a,J\lZ50cH`M܁pm5UUdKE * oUZ"Iq9U t?zo;y2tbhV 9)r&3(x@0& I)VW$FVV%1eX1,+Lvh )eSV4(6# 0*$GY̆En`y 2;2kH6@pd h1YZ"@bƵ8)i$hFgoY7\jԃD"FKbiRΠq$dTw/" +Qͬ-#5EF*@'0 ' )kt'8MgYgD֯6OiZN~ibFlNZ8lڌNl9gsЉxKm ^lY \Oȷ\dvEvv:6ʪ~íGdFpfv:[ UŹY#݃,Xs,/X^b!*5҅BMєJCgwWUij /֛M\АJBmGY#2֭ B(N8&ɍ:LÍP*S69 $K$F2-55T TA_(x 3y|DJʐ(ucEZK3؉ dmKhj:H яM DdH[M]-gKCJHWֹHjD$#c9 D7ёZfnik5lk * ~|w%עF[I)("kob|||}&*3CF4JKF7ZGYWG}ز;K'jZ @_ڂ{{||m1ж$T17 4ri~ICGC]tZbR#t )i}41CmayF&?hJQn,EkEewcۨ|kq’zKQ3 *IH hEƢSnRtńs7:(ƜA*+[M]p0]d蟕Npfthl- 4QNzNPL cta[T t%?Izp46)biPd,m;4WSTXj9jB si8t0m鸋M7Pإ=ihw@LO9q&DtQ퐕V[@ C2 ˲SJ0?T5TjSר'M@(HьvV/:mcM̕#9Sh(Q40(a"%/ ӆftcaR[zWr_KB?;reɻD@2cn\2,zDz |%Zr%))7iJ?q ǰ)I 9r3 fcDƕ&7]C78Nݙ'_#toMj p|O&$6&q@Qf<<"I˻&/Pȭaej>B:3NIɁ)c3%[Ś͹}]1DokHs,l?Ix~7Ѷ28/TzE7+,+1s.UT4)fsԹ$;8–N(ys\ m&SHrJUSIa^P9U黻1m$GL/s>"3oq}lqХQ8鸞DH*8݇;:vZ0E7a2"$Q7?gbcƷv]Ltm^1{+HPG0#"7\6 vxBn v">5[EYnv/%3c4ݟq6Ji_kd 肎As`떼fӎNݛ= Ľ1 0~5柳H~DHvv4L a ᮈ3^;^("y{joqX=gwnߚ&#0{$3M@;_TF Bs#<=Xj\fӽM '3}oU*wC*X~@h-I4n0/Of*!C*٥S(9;m5 _+,gvu=ﻣg g;]`E'+̙пw*CS7Nɞ/ntr8Ksnij5O~ÕQGU. a2 W#H5-,zgYӾyؗn.0!DvOo*qᒟ% !qȎ0$:R7H''KX]`E'+PNQ.&OCt0F8F܄Jo z}7'LwuODIWIѼy5]z.4=_HsÕR]!; n.gwފ% w⧌q|=I*ĵe(DS4OӅ.-lC$Oс}mggQ1+P0XP,'B!bX],C蜼5\Rq,t7 #C4J Xf$RnI$}0F=o @k` 6[4l4O FO 0 $d ϒ߶%w[[z 033E3`_{ֻ@$[L:e:lRcnN'Jq.) \eD&j۷zTYYbecpFJֲ,Ah2! _ =sJs1Ra%*fx D(" (xœd<❰'UOAᆅqT*jzx}=RnGq|hyaᜮV mR &EJ} {)A|Q'~υY;WA-$h{I˅YT"T[XF(vZ Vڼy65I)?9t?̾+^a"YDZ;d{Q= @rSj%cAyjLEO3&DW*#hyχV%#x퟿r2g]-PJbz6HygŶYqILt?p 鲆H+l>,59bMz6@XXupXXwXXpXXw.[!Mp J9p%+|wcIc%4e[\]<1)-A%4)G}9FBa(y*RLiB.",(5^g) ë|5?dt|&U8Fۦ4#,8U(/IaU,̥Za 8OÔeGQXu$I+.-u<R"_m6u=NWw1+#184nQuc& 687\†V`:N ϹqbaLI8U cH!i|*TT>%:tCwӾþ'^^Cc^ $;XPQ=&E*)2Dz~Ź>~/bL[+M" z.mSK: S&R聯n}UxXőB|!^)1,^βr__(JPA2A%jx7FH/$AHqCeEݳD:}*)Udɬr_0`Z&|t\}D**]x_oc!rúUVIFY{p*+#:4a*J1cjD[pjf QRp׏BNj8V㘉aG)׳XLzT&_>4=vЈjޖ,wJG%%Y=# }C5R$ǤUNs8y|F @(bb+fGZ@#bHIƢy0ȸ>Bœ%r|ޚNR.\M,\8z+2NPa=4!;J*#Y"BIӓHG#5=thRn&0q4t a9$iaB *0"@O@Ji|H1u񈤋IUçdl* }".?"M:N<zΖm\v)5rMUyZҤ%91v*)rXi!T/;Dc v i*|#"N4NeDQj2maXv:La Q,4Bȣ@_n9z`^uyAd3tjRLdS5%SH!l2Xp甚XqGƘ}HC#76d Pz*4#cњȎ(YD1EI;RQOJ3F«H|}Uq iDoӊNƄ)4DEQeg z8\CI41_V*"j;D&OB;3)ScӳiUOHM"(V{J70"c ñD,s;/DP ɉD"D!XM!2½n:5B WԱGC͝wڗ_vm[T unWfmLR |ԍ 좔Gȩ.T5tZQh+K͔$_sd%rcK%):;iL7EO;c3ПƮBnߪ!鲉NH7Q1 Iҷ\#Yމ[(kN(9RlcˤVD>\W-M'[#{@$o^ax{mؑoUQG7x!}ͯrΠ$&X)*amBA+bo ,hhRbbJ'?ǃI mEN!dccKxVi[-.BPo)x?լSdTwR;hFooQʡRꝏTe˘: bSS:e:E<nô:%Z^R$"jԽ䒁J!0?\4ze\JVW@x+7RI\wP{/ɵ%9]a\rߍge  *|B7?ΕaY%CY9c@GE5=R-;FXp %( rPka>g(PD9Eɖc!GEl`1ݍsY_іn{?ܼtzQ/w[wn@>qk{+:zjɅC)Ὼ"]-}0G{v=e/!pub)bmX!M/J 8$mٰ_C&1'5yODrPƕߤRʉhiRDUw<?)Y:#r!$BX+)vh榒9z9ftĪy:k.D#7J/S㇭>-gm{G˹~莠]Kyi0BUfKDMH[)*K]]Je2?ӣD&믰,?~U(f|E\b;E˹yy&6*}%)KPȔ2&۶v2k8͞nCrY +q}J盷79\DcfR5DEWH캛 RŧBn"+iP/*:3XBqX3#9(MhsS\ (cwuh3*Qfە/k/||{۹?.caq7-{-okԅ`5^Bmn`' d@}< .&J{+[M>"vGSvQ@ݶMv=/d+x"goBd\)F䶎dgfjQݺڭr'uY zbxb"žP Nego(U,7o83*F#;.KW{TĚ&sisY LI@F\#bKGd0 jBcY4DnD#LîE0-G8iDlT~hs x9]u9 Pm$vm($ P.yS\{G~./?NKVSQzN5Ϛ#- u\ G[ޯ"i3yҕM?l?t)w7j"6PhYgW`'#kudVRi#wOs+~tAةNhtj$:dWF956hJPD:AD{r)A FӠ4(LHA1qDh> z8fHhslzy=حvyZ-묾ܯ5՚Wonؾzu*  ћj_;wh@E \TҸgtiUtae)'s܅bHX4(I) 'dhS;?Yr@; u*ܐvbXd3|ze;;H-ZX]Ҷ+"΁V&g=,VJW}H&$;Eޱ6ZiPdD)◞ &E M8 RX!BХB~9w(%ڱз}ූ9rcsYi{k1לlޜ5]֝kO|`A   ȴpL}z](hQr+H"9HZR avyi/x#\,$v)"^שw2A"Ncn8 C%iVmf$JH-NF״Y2|Pgx8vk} `CȌF8&TgQ bݙb]# y&6U^i3J{e 3wj{މww}|@|FG/k|FKoNK"2Vr[`|b91"=e/AIH/|0)iM~&؍<#"Y_@ rGfhI/u6G~D}a]~N\$Δ!ӃKJ"" ZƨKGDb%}A3xePC0J$9(%D%D`h1*Ht29"ѨJ|ʭ~~lc-/ ߛVƿ=:c(Mmttлi!T"X(C*}ɘ)Ib=W;E{fZ=o%jL@j}8hg(K;&- :V83ՎJ t&~.4'-+r2"M?(Yh6 BTԔ4gyY"rDj[2$/} 5 F"&l~/^0k}ȅjϾ? # a[|@"~k"oG""1›B-,avT]<!H{T5L1=J~\%ky*dP)SiS;i vG,>mڒTUH'r$RC7vڟoRaSUn6aUK**äbMևVGv9`Uԑ^0&@)ýlMĎVz汞k፝}xx#PF 4NH @-G8z[Ä;R\/`bE vs(Wcڒ)@e_$83cC)!F9MQt|ƣtj!]XN.Z<&2 #MrlU1-,.S~a[͢>^"׃UM&WzH፾!d%0YP ez2!!`C d:@G'^o qKʵ֪'EpbK`qÀHg-m9?؟9~8L@"HTMOdL.|6(š2,x3[t^d9D+ وt(vh4ТbWkC(]|=>G {hKcĪ\qXv!$!p"C|\tgnQ 7_h+=βpMA@,e`b 7 8 ELASv]kJr_Q[oo"_%ΫI)% ~I_#M~((vGH4H {(g`X_pnM,,79Ms>x q%?<ެ{n5B~q?{tt<$-y;g-4 G  [`޺[~w-_zf[;nڏOIKpUˡA2o SWy@&&I~`C_wI*4k,+̻k_ljf;m~-w#HT( 6{pR=ʯDjF]B◽T#\mЄ%W灤Ȏ@FtD s'Ҕ'qző3MqWl m6˸H+d.}6gFt PF:YI#(v~({x5qK&j+&P  qx {L%LNoDKj Lp?Gz:+_j rʶۮþmơ^qEU<4@ۨw̏gnc!>``Ƙ.*247pn4afA""|iUnxv}wNzh9x&m,אz1]HVi8ښ^LMLm䈜KlNRΪtE͒]GN_wI]3Xi3c:5kzӸKYX}չӚbbnku %B[3ةk6ugSBډ;Mv\wGS:d>LZVJ{pa믐]tK o#gՉI{}{ ew}쬚[5[ƏN5P)[rࡳ+]K쿟RwX [ go$LLMM6 7C Q7 G@/qGx|ќfҺ f8UꎒwIj]Km eCE]kԝ{bbo 6"?N.w/7^˳Ep+g;vө+Nx_/&k+T8vpUzfwVL)өٕȭY$uNF [ۍ az8c3IiYpy;? ?[2΅O Z:;lLLmM{UB v@cw9S׆b %GLVBLϣ Zmi`ϾbMĂǁʸ2ET7^#&k+)Ta]$f޷_rn27 R24h8Ok24h8 <ʆb&oDF'cĶy* /1yb{2qllVugyI4+9 "AX&8*TP *b]>3dәh=O_ #@.f?P} LREDtQh}- D VY3L h|=:*;2(/ICkpxk%!c n\h[Mfu)\Nhgt` 0|cqa?5 ` _@@PAP@9wAP@A@Pu@P({`A@Pk@\AP@] "ULlg<=U*%>U Й3]]8pַV))Rt~=I%T} H4 ʨ 怨 A@2{8H= Lg OwW4WkhecOqyS uѴg>8~~0!٠ ` (  ( (  ( ( 7VzlO<QvL $T}y: M`, hM@go 1~x[n`.k@$ 'yzp2@,&Qgg ij,|GujO֥8c8;پs n"#3PE @8) H^"!I@zijĶdmmVۻ]@  s(^B:)aI @ W@G=3_pG)l#]ud jj 4BA'@ <ƪLL|^1A}?_߿{oov.aD]lm,1~~Pm>9tͥϠ Mj$< @H%[J<?V4;2p6^2[qX`YnO96WddL@e  %m0~.yV3 @`jj\T0YRKkdp tڨy@0TLz  >@=o 6*TfW=AU*^sNٿ =6["&q LJlj5@ծ[ڢvbi@] ?7SڿvtC;\"rdp ^7uZ\)7]_B`~d<ڟOX."qYtG0[KL0^)adX$TL'wbS[ # .  ,U803==gSQ'phs/z4< Cm3/U{=:8P}>7cC`{P N1гlc53ٸSI)X2t`aή0o[x5d' 9nj,:2/̒5Ua0n ūu7ug!{1`q LFYy%k/n^wVp޺w;^KV~UF}lt1ȯ&M.~_wʻjow;B%fs{F_ m$3`f>ol@$z؅$mBސ`7%`ܒ\g{sX$h P˶+L{vb3Āo vsK-*B w|KtҼ߳c8,( @Y<J>VҨ`Ram#eQ)y ⾶Yӕh#<0ʨ@ebZ&Sm gcl<{*~GD~OHJX<]SҶRu~XҷpFG Ź-󞛛R&S,&ei4gӸ%vR#JN^76`hnRY=<6C<0=4BjF4w0iK%9F"pՊ<)J_n4ZtuyW!qW٣U[? vjFKwe|‚'g{]!YwI'.Iʬg2ϐdv&ϙ>AԊ2Mr\VY,-f:`MJkڨ[7&0} O[摚%ѢB_<?+ޤ^W+w:w;gIy}Hev,ZN~㸑Vot,X`P!RKfqʬ~VYC<@pKT;RYr "T5eVka*; wCiJϣԾ\YTbB!%Ԧ k V7Hvl 7z\-H]V_Gn;&6ij¦勾BG)L~{0gS<LY2#n&9}sb`"8{^EkE\D \A_R嗒pO2}p+.~Wۑ5{p@=xY ._+/8 U`Ku7oj3'|ZD;` j>ꅏ,oӬ-V⛬~U>p>Wun5iI.|wu'ik,竨$;Xb|}FbZ:3lٴ}e7dj_|$d` Se|^ӛCDֲ=^8܇*藠բ{ͨϳAkm-Яb(dY3Z;{rt@U?3^j&0 Ϳ{H1pe Dժ-g _]bQ~<2#'fR[7FX! 6l`Jn\ vtyj ʨEjΣqfb.l\p6N'5=ƖL ?tO?!?znl0L[ 0#G{U =Hdg-?ss |ַiQiJ >*#CC:](1wH3g#3^=d$vi*T g D'1$2yKٝhʥg72)=#"=),VB?k@ "J!O-nmib`]aFB5ȻsA{0T>*u&~ۭ'ϓ(~9*5ƦmN~Q?X՛%fۚގTOyڙrSm7ucO+VS;56K瓝TlrǺXy.FڭU!PM<4B=Rx{VivmeXjl3m:o/4ÜP= =vM2š*b'd.MVf)K.e=Մltb\]Ә{ޓ7m*|"\EF5QU1 YGO\7KqLl K&]&eyHgu.Li:xm&܅I|,0 |}Wj3iqU]y BǼ&ӏ$eTd ? 2񃮴bl+.pvH@54) ~j v韊`uk0=_T!7 FPO6 hXz)Fm#O(A:u/p=u@.LmNsG"! f m5CvECpO߶j A&$P݂A+t!a4xWImumkۻR00u)ruTjd>D87:PmbX uTY8Tʃe4<Xy!2_C< @7E4VwsNWtML-3!I*DZ!S&yiTC/\t2J ;_\k]c]^oբ}K!shYv]O1'1v&śsݴV8R<, ()7.nY/ dOHlN$Ivb3B7ZIr:8ZCFcSY8M]-r8FSv5s.FqyKiឡyS ~Nx={ʵ6/F[" 8i naɀ$} "iuf<-E%dLUo^٫?9fSҧHRM"S֔~cysl yyɩZVZZU]^ǥ6% L,Hwe+R\z`- a߻ڜƭG{`riG)-|͍ف0c42%1{ai¶zU5Oф5X,ej~JO^yk s@m{O?bxt:W|2!e0:աvxfL `{)J]v90aOscn]Np8j⏵.n% ^:F0:CmU}NѲsĶm.ƫ񞞵59agul!6a6թL }U^7Ŗ8ZM+![²@ccɁ{YHl2}HD0.P7Uh :xs,pٹTꦭ dg v ҈ mVQU5oQKhUX{!0J{XP:4oǟ)rTP-ގwYկĩU)zo"nߙ_2` }jwf. +l}Vo~@n/Y쥎D x^4ZmiP5L }#!R::6Z5(1#{qb>jKZj_H1~*v{F>q&'ʥpkFqWu15!ּN`|$%?tnM>jW/ D,.[g3P|W8mרOu9۠[Q\~d q^67qt#,-)I%8(hؐx ^Cift7ɣYVdΫѽip=(Y-"Y$*]t?6z%H- \ .E*+ |N1?7I^JAy54!Gg@w:8r_d/߾csMJ[f%n+z`}<`k3M/z,GzxO\nECt)ٰoL=Rq?~Υ_`z'.e=T'415|9q'hl^ء\nGq\x"O۪ y?>›iP&o7EO2ATC\2GLzTHC]DCj(]\\֣\…u"g=>+))x`U :rAV:F!՟4ptb 4+B_5~Y%M4~\>kh-!&dW1 *)g>ő#W"pe tmD*5}<3$}!W1Tiʁ-y3($&ݟH t1{Nz'O%eJߋa-2c7)o±B*{ %T&?'./EqT-1]S1z%=P#V)<խz^/POǁ~'{̎4O5;Ϸ!t#3M`нo'}Z#GGTSiN9i3ՏMZUϞ9K/<2p>LJB&6}6J'y$TE]ZsOD@o/zXˮg{^}\' mT}'ls v`v͍7UUoyaf\j)uⱩ<śo&- \:+t95TD CH1W,p]_St5O} \s񢷬=7l|0jݕV8Q%2J&d^]Gcjv,HQҜKQ{YwL?=:3o1=7H:{N'T7x9b#~Zj-c&X}6X-RKJyRS?h[+БXP+&/.2FB$EtkJP (? ŰľBڨ!(RXP>&s_Ff:1u`fe[qAZ"dF,ehĻ?2")dqah,mN6;c\'C@뽼vb"#9Ln^`eD0g'C?|v XڃvhC#!{%=R2Rw2XLG! '>#5A=%{ B $!l$3Y˄J()}c@H_@z&byCL*#BdO6ʬG=cy<R&" d-#un`Θ3(0bҕ7_fΩ9Nru07="7f.޼RM 6sPQROJ1~%E]K".2Ex/^8f/a0ýf81P&|=AO; }rh%6C1`Gp]eVW" B1l |.A7v8 L0'|QTT!]~S9=N f4vG e"WHxLbnjf;{ h~drCy?\8v Ͳ}(m&ò5yl0c$1%7s5V\?:EaM-e%SŠ_30AǞ/gvaEeҜ\vo$ $0% 7a$oa5F9Bd'cƲgy0S'LG tw¶#q(dEq έ6} vV   / =_9&>d82—"YJ*,|d$k{G G )/s*sAdE[ې-c/ˏEvA o^XgބTd?³Y|{jRzZy|蒺N8Av =Z"=;1,>SI/~k*e8T%Q!gIЇS෸=n|Ycţ_dg]_rYI&X7+=3T͝|a9ۯytѳnV ]4 |oTBLf7WY3 <˱P'tv5ukn7:hi-<.:)|HI/d(&J! Dfz{]졘A2QD 8c.5d-Bw| vP3xD \BH.>DP{B =IGJV73PgQj{L4C6SDg Rs2J L v}_w)2V7?plx,UŢ5n-Ew\\Y"81RYiI k:R}?ŔF}SW+ Ս׆)VkaTX? l%F=K( %epgܩ|s_W#8J\htw{N |-Flq\vsZC+|WRBWYd{(/csqzLl52h^x"BK-I"Ģa V񄄈yBo~9Z 2+#T eB*P`8ylX Bo\#}P^H‚5#Iѡ]*zTy.'T'/e:a/6<:SOC:5:/7^*sTT=_5]6=ulG\M8*CRJ5܌*loSN:vN6閪Oz0 z:_;(EՆq͖m{y@Y 44$:HE9ͤzF7+ú_Lb{_΂O5j#+CF:D:hHKxwO۴הNNq!׌[)0}*VzN`;~d~lG!gWA>aRt㙫|¡,|!C@4 "^`dĨ#N'bcRȂײ,г`A/UE-j_M>3r^PHgsHYIeT{Ft<q4 NЀ` ~~sX2\ji~`[Sr3eKc>}C⒀z|Kܗ zŦߒ  čgSKMܻX܎g -Q10%sxvaȷf9Y H_%h^oxI ~v7)#Jveku{S ;DWn3Wr7NzRD;4V"&F#b?/{%K͆jȶ] | buaa؆qeQG^ VX3KIHk :hrlY!KX/<&]yɯ_5^_5wem\xe2]V΍5r{u{9]]Xu|7Xã}UZ*VkV*܀n o{.~voIo}>_G6iιsZH(Wx{X5M!* xFEs%\{;*U(ȏD%yޜIh~6@:MiŴ)a߷܏L0Of|ܻô)y9OݵD:jSdܝa|WsGX/xPdP%I.##;҄30^+}.gIB{yD;aXqft-ڝ ~ $Jq*cYƷ7X] ,2),Us૷ݹt4k;.n鬢˰79cOoέ u;4c.1H@΀RrvZVm| wvٗMk@fэtnφ9lρ:g݇+L\K'>6ZNsu!jKn[ y IJƺ{l UT{crAJ= UOF|G̀8ҫ-|󪕵15wM0}jDCw};3Jbt;#W'fHOҔ&U螑/ //#)ՔFJyA3XzR5O7ĺbm9`UzeH*MS`_PH我7 ^R1N7.aXڂ{qtprutR\Vū7ռkmܛWf*mE3Y|Ui=J]b=7&Ż8~d{فOSxJ]vyAg*_yryv [oyںXh=ֳeXm6lmƾ>sd8Wrpt 2k W9o$:+Y>ï_]HukKv}lpuۊo/npROvږ s R{PBߜGm9 TpGx4޽D4]5.hV-EF=a𑁜nRimG `BA_,;D d—KVVE {"` H%Wôf<`沓8vWBz,&JOaE v{%sYhDRS>79:>ȵrؑnλߨzM6Ѡ{ΖMKƲk]LcyKi+gt>{ eZW׶'=l Mf8 ^-Yzj=Mk:u}UU8́a#ذp|59|tݖ#dtYHd$h]ev[Ys[W%rq+9w Da!x+\G[yD,R9jNZB.r) ݌'stCU ނ/.R+ QIGL)OZ=W-*# Xdڿ1B!iaJS)gYYRwTb,^Z_o'vU B6:s:Ve7QA{9G"<wweCs.$:>[;4*O;ѳns!q\ 9db.{گSZD[U~x)W2v,gWxSۮNӼ5ק>w qOv[B}*&-6|-K .v9I:2Z][/:V5m{[Xd J‘Ni1)_e-Jk•Q<T %`҂/%/>lE\: {]jqi">N#u cCMBMl[A)cMQwlWKD VI>N;33i--7%MyOƬ[ <jSN C51|13ռ'q['_2OrӴuwԋxc{/Noa~ b0gmPG4J%]I'9!ieu]u\e>^ 6p}.->q.+>@8^GAlc; S綁嬡abypIJXӞWMR:Lĕ4şD<) ^$ C8*_l^1,|eq?Ž,w)iTa,Pe:n "Ґ\҅4NN=(Qh;uۓ I*O 2q]1_T?]T}x~@{wXO]d_%:€)=Uʠ3[9߷hv,!Dκ[5n s]ֵ*hi]@2Q"Fmߗ&ܖ1,mIRpwtȬw#U7 Ԁ]|#&hxjs\%~0aZPE PdLd䏌 RӉxVzG8ѡp|; Bx[m!svqyla0L鐉+r?hɗCӻzE/,.JvS?z G;LpD&m#-oܔ**f' ^pzʆ"Xۙi{-El7'z|pE@IfS= ߠc ^}&`!y) \聾NLŌZk[3lX@X:E>vy"%$!,.1^̒, r> #:-_S#ab52 |cUow8_8kPh;9Q;$K'^a\NN9\魐 O%c$:4(-U C8W^d#1Yw24♲G%rN0&͐kLa+oz"/npNasMpK(XM v|ߓk3RrGdޝťM7ɘ/ö |M%B5, a)E·{oD.4%(32)lpUyy;n8G@_ A 4ߕx(tc"F[qu"qvMJ țZT;M ]7ný#Hp R?[#rF.#\D{r# XoصCO mT1 9#hsƐ9?'[]`*zȗV]Z-#I#qb`/ )'x%E#l.Es&/F7 Mu4o<:+R+/|]M4gl 3eHBLc _HnĽ×| xњTL42qp=K.` F@HvܪƙXLP=i qA?bKU׿N.jG8Ôd11D<+{ .+˿Dі)Ua OR!ĄC))$:qBb@Fp $QR1c9d?){J5gp){ag2Jbp]e'ޥc ^؎ *4 Q.ߌ$%GXF:sF/daw9ݑg|pxYߌ-)AEBE_!b"< TΧ>5rzW2Mj4]IK6Y&n:y^hnG~?@G a04 Gx. <8\rȢ*q" @ljFRp&o:Ԟx#!|G%qZ)Ge51!(XY3 CŇ0G$.-t,F4Wff1]\LyL!K~$I&.`f#YN"C}~}DiFD$hpgT6Ќ+鰼lJ)]p3MVK *ZoKk\o,/lGp~y̕_t#g* oN) CK^>e!D Uo/XAUߒg1ڱ󽲣21+YXM",!c@2=ztѲSA ҜAAomf1тy,wvܱP/K#䔏:Y쿚.iBKۤxYCz[oDUd8u*Yk.N!aJ +ǿo劐 :%.pXٖ)-j0XQI%.am85-! @h!E75jc j ^ dgy)_ʣa݉ uiCPaLtu;Rf`,X1 vopXu#K-_תZOGFxX &ISڲ,6/~]/{{9S ?D$PFtpg}7nK\xfm$|[+@>dD9)Ԑ-fغ"f.|li#/񎻤n1OJ=Tjiu%,ٻS$bbnkv! %Bk.3Ik6ugWBډ;Mv\wGS:d>LZV9Jrp.)0CW`!+0.1tSxG$z4UKǛcٙ5k8ék&+-c0f`!0؃?Jӻ5nF37M1145, #6U7 G@/q/Gp|ќfҺ fX8UꎢyYn}[m iGE]oե{$bbo 6"N-/w/7b׿ӳEp+';vӫK?>w_ۯ&k+ ԰+5*Z_Ӵ(!]N^uxV/&I&&t6B ߝvTn= ۈKQח&fxujWIKˁˬlᆇuA^mi֐uz␰^5 .迊Vgls_C 24(eP@T{-PKX5C]fo?L42>* *  L5T + j6YAM \\pI%ױE߂011yI]c{`_YEb".C<˟g4 |l]xnY4OWu} @ MlvSvp 1rx @ @ UDUGO)x'*J'x=]Wt茌 n pѪVEpEZf/Es8Eu0Ś0;/u)5.&\ˏ2~T( _;cgвuf:7;6~ jh~_K}g?T@@@@v`}՗@j4@Vq:f`S /uSb$.?@i@/id +:~qd WF QNgo*? {Lo^;iZՏoár8_t\2ղ|;syEl8|0R[ @^~ڬ՚Θjoڦl1a֐Mge3]w?rx_LxV_ǎ}7 $2W> !Y~Jo@& e\c0(cSy*rZ]4ݳꖹr_A@V'X`X4Z,0 <1@2_ ;l "NqH  ?]nm-e"'08dؖ0. ғЁk²>7\\~~߀7|Ӡ_wxl0ik=? v}_̜hfm:ؚ:QoĤ{rhI 5b3(Sk?1ڍt婻UV/P=%&p ~NwH*N R"t=vg S0`>f+}R?jΕuY;λYuRH^2x2`=`jVO>@^WU7cdb d},cjH$yB#[IQ>;7x%N)?&K4?)sdݔ4~[(wXѤYQ, n:J=[?/tK5I}1z??aW#Gb\[ʤr D=7놣U[]7uPN`|8eb.x -[xUJ;MMC3]  vӧ鰸Uڜi?Lsz&kuHl+9~7`gUP}˜%2WW 6Yw^}@p@bi]o 7bDElP Ow{8`Z?A8UqSMO2 |`D 'S_T\ဥ *7ú/깮ra]4%!J<Tk>ouFt,k}ܯGBѯ^!E+ni?r-8i7ۆaP 3V/mLL-$fA8:mմ9~eo\N'0YەeXd`L1`q }1aP_0'k}o`N8FΊ~OPuw~"lU27/,'x/&O,sJ -QE=kF&.xlے+79js93 K4r`5 s>X#龥Dg˄7 P@CXS8G+eumQx^xX2cPx"`ͻo+E=N02oLپUVP瘭nx7}f/3 05nss W%y[ }1i Nӛpy56;~ eb]_UiW8KT~I<٢R|^ ~gn0 vwƹ&U$*l›\^i mE3xo;,4ȕkPȃ(mDiQ$!ˁ̦j]n{m{ww|޻ #E3w˚_o([wT;@6nܣn (*h( 4$ַzĔZH# |Dp*Ո]w{wYPדߓeKGO7mSg[{D-;pc|r[/#_Pj_=°M=ib HwX~[q)`i!YZKGxRHB0y|ا=A3}MS 6Xj%>֦nC|2#l"0-H95u'Vc< _"4M09;#~bsZ|[m` {J,wKՔҐWNvY5 %Zm$##wWn\;p'S,<}oo,Op_ܬaC: x;+SM s9&ϣ `/-:(~FhF-BdxZ/o1W&3Ĕh`?q (TDVVF) k[DYz0VHǿoDž)1^7 7:,t_@4_{% H&,:jʿ~8$\j`H&:,իVwK#\5 ! +pkUF2۱spA.V\kQS# C\}措9.IW+P9`Ugǒ@OSzZJr6ƅXYu=j 񃁱h{R j#4BnӮV; `\#oA'o~?uL q[}@~hKC|AwWTM40@~9o~; : :&9yG Qצ^y`"nvfPr⧤}@2i,z?OE%>3Ciw#2G&_ԄsFz~e!H({-O6+^<%U&cD> ,sONƍds̿6Jac˸f Ў+OHޭw>Z.h†vZ(2jO` /`g׍>`ݵ9CG l/stj/@8nƟ/4`n Wd;,@L  ]almE׍I͙%K{s|SX 9DbAe&3$5 hn!gVނp "! ŝ@L@N$em޵m{dm 3E3gmdt{uTVNI'Rnnv]aibwmW:5VX0'2#f[#)5# "NtD /(1 f̪w~>l.qٶLmw4I6VZm !`!SI±]M _'=O|jdDUW Ld(m,[!؟w>fUW?~_`mZA`Lȣp}QLLKLk%f@xL&g)՝X5㨍d!B\Hv'X)i6րJ!0N!ԯjoΈ$ @/cN @#\g.Bpx@ eshQ;Oo< {@ 5_, @5 m7H)Hy{R2d KQW)@F>Z @ۓ]0y0|͋@v:q9(upQ[XL+4SuO+wuL*jЉ2apu'uM`{?߅{d\W S 4:ՙ|ЯIЉYEp A&_H4 Vad\WLI*OToP!&5Xp4t.tdΤw9r%N_wqI$$dҼSgAgX D-JJO.y:w[ą"IaCQd0[\>\3Žic@v>1XWxx{JVBZ8~y7>!B~"bSa 0`Y?v xʒ!̜و3]E^Jf\>JFDnfů VTqgGmlp] -'oo]BF@JQ5'hnO}6ٯp 7;e ovwC@kFSO}E)]Z{ Cf$VU2bճ[x_#10ծWPiXc^p !?mxqĿ 8B64 W~ELKqӴ S,V9#|i޽gcYdÓs; F Oݞ,<:WF?Gr欱}r]^VM[2m )A|흆/rINa-jm?zu' l~cY2Q&PLW}/kZ`2s2be.i_x :V+r8$a[>Hp88uKR--0)̻F<'-ȩ^玨!Õw;҄*orxF$lvvOL' T`tQ+;FQmkvߢ]x#8 իjPR9e̴%C-he[}=2@Ȃ2hVݴY `S %IL78ݙQևipz&bpo[%#?!KZK`߂)te>cS\A Wʈy&8gcY) k}앁x-!r 5o6X΃xSb 0a1 u2Ct9s`ZIyMD\%2X421 0G}tcMbAy`*@>~1d;tWśl}vd"c0`P`,I>F{%eፂ[>hFB'tpE*rokCgA fy"9 Ap&N)_P m:a釵RX0 p^0cv=+ OylciBXi\-&6XƳч|hu4a<.NbT]v#U!VE[bxT W")^଼MSw*uLpIDLJRK4: !0KGٲ5~ꢙTF#OTӎN֐-%8/J~#@C[TG4 0ayYA}{JcpO9e_HM%=7]vQM9)#N̑S ~w~w/%Yχ#j , `W]v6|L>ukGkV*&kOiAX3zo^Mq;HV'6˶q{uÝnX;%ZbJ謆K5aN* o{ئjskVuBSFuEv+=_qw=HS|C #9b/.]gw\cu}Y hbzxV,Gq(:jKS{4A$wxqLqr$[9yiA'XcѹO4?aƤ=u_S){HXYBeJucOP={ Sӡi”QZPc+%gt';|bKػr'߼ǻNr9SîۤsMG5-Tm}*Ϳӗj8\lNv/Z9TyXn@v/yh:ӂNZ\?bOǿ\lF)K!Z/."Wd|_t=ڛID e=篱2AJ.s#In< F_{׸Rz$z%!F.)/Q*=?wP%c4kqKoV z=U#ϣ(cScE0y6ؐ'_K(yL!+rbcI'AۂyDVq}]?;Ww"C R^r6479C{!՞vTwSFt.eE-kVryN2HR7:&IOsuZ穡Mc6Wћ)lAw-JiS91UN8^_4bKi'y[Z¶pKbjY˿?Y>sQ6G~)!oŏڨO18ۃRVY*5_dͦ0WWÏؑjq1rt/%m)qoWAR?E`w-“ܶx-y-h{_u?f+JO'l4~ޝB^OR阽]i G% "!Yꂎpׯ*nm/WsE>>h5I}Sf 6t޶VaNyPZnU})}s`O[bU; 7JR3=9^4w1x*.q$UmЪg%LD3i&VusD SJ߄*Fw2z 1X9>Ÿm Խ0 SRsCq)weG(C8o4Q#sþ ,{-2dm;6.50'Hu6tiܞ=4ftgg8y)2O>(Dў~ r )b8 aᷔenmz0l)aXAK[ihu/Ҋ3!AG&6@~aٛwN=i 7#lFE̼DVRʣ4u{>$?;C}>-՗6j[`6αJQe-Gwz:[d^1rW,U£<`dTRRD|/21&cBxv'vOmrP{fsrx5w=]J ]f W \H} `Ev --R^|m5ok;7C^\Ew0C1Jp Oe[^V^op?^27m8P`` O@|D B"p?:{x9ox%Lmg VXJE]voi/sSmo3M` VBf.9lVMwu^q2:o)l^\s&m :0ihc] 9AG Eb6Bf Orcbp7Q| S(9EFX] qCeb.%􄠂1]ʞ0FƂHm< 733w$㱅nntEu0gA%-EŃb f7.O~:ae3âý״m,mG6`as#|[-6n +4G~a9k#wU+EpCl۝Z{xvq` Et7Tt2tP_&qTYH}nuոiWY~av{0K_N7hoρ^:e n L_mK7Sn0R.7ep je13;(>K ,p  (ҕ(xʰ)Ђ x{z+L켴 qm"~L^Ig0KD _(DQ JC}~G0i$Q/zo"śV$_CkoZX1!G`η33apu ,ۡ"̵<u>۾@nwp{a膡zTvt`o~.2@# i˽l&7\ U;Q!kTm&3wc o^67ԟjFGbM,ێk[+m} е0w[ASgcڵ9i>cX@%~!=x=Yqh9L} I4xPʸޅ0}ҁTۢ@0hH%@B ]bW ≈6'? 4l ДC9*q!!J߈#I$zGF,~Em_CO$0]s: -SkKo{JFbcz> 2|^חx#Bz|kskYGf3Ӱc񍍻^5.} /U FƿBVY [Egw;Nmh r3VžB&V!χY&>.~V[)5~{xw%^Xl~>qѮv7V+_Ǯ۷+g=~=m8cAܟ9-}> Q\>(0#, vWA6p峵eQGWoe,d`hNso/VJ 8+0l*u ĠT@@ZsFT kݸupjau=ö3MS?M!X%<8u=ܐ?9\9:RT W\[U(ߗOjJEjJWWťY4NmG䒰Mip[~%;!O8nxek5q3Xt+JpM H(BjqZ| A=qJ.,D좕¦ƍɈvW~'Ŵ]KxYYW!1&| ]A:`oK/D( gJ2Gfd'l0"jf||I[6r(vKp*}z^&.W }bDl*tb&-{7S{ l7[ˮ!wͿl1}fn6ٝoj{/dOu%gN'VLYIke$=/Nqid\+وސ{yKۺw3o\&m=;Yl}R. K>s !P7)͢b:&jh,ʼQfWD8OFACQ,ĤrtB~ q2!DelfIX#y!'Rp_\̕];Pֳb8CR/o+`F'KRWCCY`RE  aYB+hȤ8=E:7 "Q=tl{A Xqx^r\l;lE<6׳|ܷ~qO]xAٷި:ǻ4` fA)[%LJ-}ˈ190hHSR5ä1`wޏ̅T * QIO͜肵dwO;y!gfY+u*g`A++y.KXw΄ƃ:*H^>^2|0XZ\͌41 .Ĕ`Otvً195"tj~SDKoH>sg+Ұ4Um)a@MU:S| qwj<re`ಊL}]zՊS\A_  ogkwٝПr%;+6dd^my_U}XUݓ8muoa6%+/DؚƾsC1 $l&4o/]3ڲ?MW,`GTƦX LsnɅ!Q.yiz /F) 3C Jʀyzn0T;E | $ҏxiQ')oh8C5 "x.v) ,f,D&.i޽%|~D1]KCJ4oɬ0.'[| E$~.Km *B/j7b-M|Y]mEWktxnsCm#Drvukp vq]xpR+}d>OYT)Mς^fb_)Fbgbmqn,u`8`x@/ޖ{7N\d]d0ϴ;jx3ݵF !^w9d^u%lDZuZx!< ^~2B1@G%`Ȣ\sGՒ57P#JBGmI«{ :Ĉ=?!M'=y\#nYrF  }U; :[\G!4~?7dk1j/ s'wΓ _ B0)=ՔLTJIm"FKHZuTU0J]ǂ<8 r(-Pyt$7,}dK` n.{ +I vL|ON6MŘZ+<;ܤ't2,wYNJr*MAѯmlLW_Y':`̍m;=_`F}t3%]٫!fWV{QiElD_V˺drE 8B= d #%'^P7v)Aej.rG6)`KX@ l[`NS+pXy[و(Zg,<\+3J8LS-7L}<;Hsb$qGHܴDq7JAe"p)Xp)|O[H`r&6.Hr(lL"0]rsȄ(! G̻eϫٳ,YPU"5ϒ1Amqs&g|p8G= r!Eud~Dcl\x3&{Xp~'n+qbr!_8t"ͅ<2-A E^/  #C9nNz2 ./q+;O.43]MX⚾4A?eE<0 Q"TZxDD<ȤGdtrӃȸ_Z ejwo1qmB+s=BUiO-o<[NYyȩ[gyi2!& |ٗQ<\l)ĩP*܈2ٳl/?kN2Wkhs)-91<~nq3s+'P/z @^!Fpހ|[!ֲTDv$fk`1 o,zƻtKd_mQ)W|(e9Cqz,fQt<>AMNDŀ!'8 DǕP成N'Vnezq-\0\/H:IN)8 q%\JJ*̻C*smJ-!; m+ck)rH;W_/QqWA^iʅD"@pHv)!f]!efE (cy0lhUI,nH S&ZB[y|xo%8J㷠<9տkGր *zAyWnZ8OO/!]1СMh }m-#>?D⇪%q2Mj6dYI`hn~̂xN4$`)9P,'X*kh'O$[؆{4X)a`wjT3aJVrUw-wSN5^IHɘ&A Wa[ynbk7!viUn`3qEq|1“m7jswWŸTX&tlRC|őKr;ߕhni`G&$9t|h鳚_QGqA|Oُ)E).y g1x iO azsEabkiL*=C|]!ըx9?æSGXٳlWdM'ȜTiۨs/|ᜊӂ*Ua}SF:JE Ң!&P <@B{?Ϡ@{ t<d!1 t8z,H\#F $ A=P @{toYZ>c'W>Dl+e#nv>%hme`h@iqcXZ/cH=v]ŚH\=mv&6Cawە 2=O$sbNɶJ[P1>[q1bEہ98a*6aa@r: Z }  { 2cƌ;l!^YU'l<7`.M DhDp'Hg@i"nUպ̒Ȼ!iNmxR/߯6lv#w_E foV0{hr5l^BU}e71+lLp.Q4яx L m"U*3IM&ktcA|U~\zsǴ L0  T1PoTQz'ƚZ<ZAv Ne$ o  PO _A-, UeY>NNhL&ĸȑmDkihn %m{oJO+E9&Jt.8nh~&4ODshZ[ŏ\mO p: H[ƣ󓍆] y۞2)wRԕ: oox?*y6ʌ9*F\RI/Ҥh[XUyZ ǑK,ssLz͞{Mu1E)|]U +rgxK\m*,-2 &f8{KDp{h U KrOLM\|9Y|fJgML %B[ժr O6 RmЄ+ O9lw_yf\g^{fws>dyt~sX*\ָ/eO(Mr܃@_!ʊeU\dms69>yg~s[rҏjnιsĄ~$ԥ4X^EFh=m Knilw0;\}~531R?M =ͣg:J|)8ushEiS5'*Uf%?%q<4͡vYE9ρ-e}E//>$sك%'}!*GIHǢiHK6Ydy*fV 7zyEk?=YA> Z|%L~7;r2S׾ ƀx늤zRq(#0)ylH6"ٗ.8^4@ѥ|3ws1œ_FmXϿm8WW %Ѷ|7D~)vϯ$2yesn0-j$k շ_*u$*S 2 o{JPBj$j" M͜V9lŘeHx6ajֹ% 9mmS`A.tC JWk L]׈YgұQьH/]׈`6jEP%濶oXY9[G˰5-'$?NT> PDamD rkh䣓-?An#Bk)Hi;SH LOa@B1ѝ >}B?!=łu#Nsh{HܜL-P! yw uOldOU0=-hmD^X2҅zXSh\q=3Z05΅g""rV7#ҥ5R^uRԲ9ru CI,|̂aJgcmCQmJ'q԰ōr9o{DB(\B\)dA!2&\{ƉВW}ďYSe7Hg&uj\ {*7jyP;O9pPЄ26xnWԎvh++}ns!Ls>a˶XK79셲^V6|Bl.[sFci{*!^4c{P seA8zʭ&anݶdHTX R}bf#Jsε9ZO6D?@{FӼ5ШS \g]u>j j&h^R^ځJ-7( hƭ4 M`.l}ijyONj`tMDd*Ln@M RZJK2tU9O?DJ4fNHNjofr.%9c]!Ta hD[62m#=pGoWՌdFiZ 璞>`l|@"C4^}M7{$s̞wd3>!HlbC h 7)  0$T,DkZ߿_w^Y~`fff I۽M/нf݈Em5Wj YNfJA. LB&@&EK_眦icbDQdmT ЈiA p  H3$vEG~wzҗMZreddŊ 9A "@Ex2^P{<Vd6* ]>pscT3|rl:nƄsd\Pك1:xQTh5YG{Pt;%_dFUd!31d+kJQi9sSuueNwmE1}RO\4zl@ D,#Tkn\{($w ;Jq@^Â"fͧ».Ir{`3DBB`l9E̓رEJզ="G1:ұp}27Uϵ;lsTzcvF2Χ4$$M59e-rҘBq3X$wq0.ĝ>(a"i@IJ["S^p4@w7N=df4[KRiePncTZ[ ţ u^^ݸh?z7o^)VZQ"%6`^*P+kΖYN˜}MVtsf\9`0R`|t=l?B=]gX''>,|t|Y)XA'hAD,[/GM{ͨA8޺caž}MЫw* _ln6ղWF.})B?Z)mT}/u⨆I/T5nSP5EyL5CUrNE]M2┛8iҦln=mo;ff&cnrua׼8WqGԠsI 7X b((>> A7(6P54u ʱ&mIPpy9nrl@)_N fmkaA AC.#48l4w J<9B60RKN9tr5h>< 4m%S+7ryrJT3,{Nt3ВT^N2  3?5urP.)V7Pmy9wzNX.\f$SmV||w'VD-Hz8C)da1061U*MT :B1*id<⩔O_!+J(Zg=V(~YxфfH)' b&dj !b #=gi~H~ ?鳸 pهz2_6YШ$AK6t4z2P4R,ٍ)fq7DNn֌ոaveFsʗ&D)(r9(R85mzYCUDk0'WkPs) p ES@rsv*҇>4Q⸩$g-/fvflLDɢe2MGdr"X@G 4`v"JfOhO '"S"I$l8D$,fE# &=iA>lBQ3J.HJMnF ȜS[PQǗdl9lĄ'C! rqbfҬBBB(D,JIa4g<`g*qEy~|gLl{O$&ɿ`eϴŚK{\zn'|k:女z.ڸkyKuEe:+^?ls27ٮ4rJjFǤ*LfZE=&E{. ymWWGMB XїZofBQhll94'0H21lR&:&.VlSOnꭊun,8]Н};N$?&(p Oԕ/LP]Jv(SJ҉ @aߑ;o95 [vjYaOk0j}:$~m KopoyN|<'A!0lӄ] XgJ" Nj{8ʼnsWK7ܽfUdͺtӿNKYMS- }O[>ywAn;ŵ0 I.af\EtVC_f)MYG;^6k@53<'N8?Xֽg{%4>I:<*dCWRlstLS3\F9zdfFHls37g}s:W, w`i>#m7^%}l/2AWCn _sпT~&/q;/0=F#}77֛4G#4o*{*f:faz/j n nN7%krh %>֜>N;8\hu"l7lO& Y{'\*٪(֖>~eW)?B"_bY% GYDm)>HpHOi"*kPr .ADkYww.t֥_Tρ`^, ӛٽOpв[9o0AA8Z7Gw߭]37jUI xJI*<lX AF&-#-,/lفF!n#h,26GW =lX\ 6T^_%pf):` `.d5_3;')@L j-u(+M5JjX*eY, l ƒA:8'lH `qC$"۫v"?ybv黍٧`k gy(}`We 8M',Aj_-+ҙ?;K1z`rW `, ۽9W<ۛ,M_H1EI -ʹ$q4/Z[KΈ:IQU`Z{<Ԯ>I9OmU2m(5S1[Y4nq\l= llI5+b_gپ`l^bv[e6[~quvwZ?̭vϣtI˅/= å^om}w6?OtltU%msӰ2Ժ @z?yc#4핓/}bZr=3Sv+' p]E#[睍ݜJ4mܚ5*)tN$g2,&ˬ6uV+3OFrx-޸[mϝ`0 vnz1؂ٴ DϚ3PAL}F)`y\w>7K+ kژN/^^X`\jmMS軆Xozi 1=e&X#[)9 ?]@Rx4jjaMS$oLV9n7ypgMp⇌KqGXW.UtYE~S ȊTv2D(.~%@pe1``^=ћ껿yIb>뷓s6Mɹĺc] Q"ځE3hB2!֑N]`ƍtBЮr#,nd)I`r(^k_~%~ygU4RO( (C VB}ftJۊ"q~Tͧ"?|H0#uh 0S ={ךS5S8I|\8ؑ9ݜWfc^.7NBHDp7.x.N$?:ⵐjw#>X\ctpB.ktgc[6ԱStIYRU^m+-JԐ:%kJ*V^sSGcX5=s0cc CYiHsvnu.Z"." וN3/G'z9T%` 8\@pQV etݢlɇ;*ޚ wfDʽCh$>nÆȿ`I|3 bgq9&,dak(5uG2m7e;fxWWถ!Is@e @YozmӪ/eV \_L\BqqA"lxpie}0Ik{_alJo,5Ѩgb9T8!5IݫfCۑZ\.Y bQxƭMSP 9hڪh/lm4-Ě3Ei9ކx^F9gO,@7d,ZV 3>)H0) A\QA ;n#[l /l'瞫91Q]!|hTfiid$hw+s}:CEw?)}f.HZNYhpk0#fЈfB$b !ƻ#?chvH@_|=Y{X@?S !^#b^fw7.{^Ϗ}\\}暗V;&웓N_oc:O2\Bb>"296,kYac7^rnoXe缏OI~ R`YJIYICW+)igT"v#Tfw橏}1.2.]w|]΋a2_?:|Q7O2S4͘GKJ)*CAoiJ9(Yd~;+~ m?7܎W ʇr^m}:|G[WWo p 3Ko?| nWuT`zG.`(*6 @uϐ+]-gpēx{xKPPPP6~aCw]~}N%U;۫.͏=IP?I`LL?hAVcf?xY~0 EIvec f#ȉJ77;no_W~kB4 bBwg0A 8Pl~V!jĄz >" 3mᰰfV ~Qo@eẋ!ecF5,KbxxWyw:!4BG(HB}^ M2O`jA)*bFعXҽgX3gkY:9{'q,‡!C00>(3q3x0 l|,Mfu-MzfsMQ8~W";L!ۡYߓy33FyˆC,0%}ZfRTS2p%FD07 &pɻ˄1@8I0̸bekr,37U+ʔ Ϊ +y?fs0%h֜7GQ2pޛͭ֠wcPG0MZЫԧmB:w FQë#_k´᪵*@ cvQ+g}Mv^`dm5P͎f,)~bgQf9Az03ɢQa|( !YdkFm{AZ0|gⴍCa~xw~<(Sԭ ҫ |Rلkԯ AR{#fg-(@jAؼbEEWͤV'pEfyq&8(L:f|#M/HVA)&5NtUSR}|+|8T͔r OZ(S>F[ A*}ߔ|E QO+?._K~ɟD$F?Nd}bWYg-hGj~Rj}sNxeGmwĻ[| l'g/{N1U|EG'J7[KThR$DAX)+dX'Yi3{ޚҮZ-SC] ;O!l5 s0M'4u_Nrd4EK4jgU$Ǩv;|hՑ,>I_LQNu$2cg]#ƅ)oP6c_rhD;t:'ܳL6HϏ;(/Qי%E 藯=ML*nqjqBIJʗٻVv9mQtDgUA >ub %&f;eO<jzzd VnjcT5kp^;oRRΠK_oV\8ORBv$RW '6q/! ;NEyZ a|( ?gd1HQh>5 |0Ctq#垗ivCa;'0N@P1dcܧ``/]T( l5T + j6YAM A?1|DKtK,K8,k5voq,Ym/-ya14]iDv܅n~#,1}@Fz` @i(O >&<@~p @ ;nP;M*8 ? p"PTFR]CW"3ljh SSʑD;!)&rS J ١K,W`}oK^'>dcP剋s՞?||.|`<|{oR z@ @ @<L{ ? ӛFsѳxwv9/+TwϪU6w\=;Jbm-S=6al OUoc` m4"`V 0ԁ‡0E%)Dd+(Lhjf@Қvw]Y0aU#gP?9~+vFAޚ[a]0c輢Zs}Kk5wscs x,fnwKv[U[%8ikĶ(9m՗lOBeUX[f{|3WWۆa'X(V(,SZ^h˧JG˪x9qͩz-Mr2 + glYw#=g1Ԋ)_kě5 9o3 #ըEiXC,s`vUw?`rjKn0릾@lIƠ[ oTrTȁܕ!lC@Œ3v59C+cX/TLJ n|KrW1 q96|%O{:}҉伉[.GMw%HiH;Pzm5hY BK,ف*RqɲDV1V0KVڻkwXxݬ:dY"+oHT<9Od0vѾfS=kiځr4?_EF@WՖ~U^W0EN ,og?H<_f`0W|_}%wki6/ _.86)܀ \w9E⦭ xnn0 ۻ5\{ wɵD`'V24w=b;谷/.'5/_LC4PѠܼ[CB3SHG:K _y7 |% Em6O_{#w~%%3@]5~9(a^M65X_{ef # @.|WgrZ5pV^"0\y\K.ԱMdqѷqb~j̴v~Ե*#i^nn}/kjp~ԁk% M7w|_qMb6lq3~|o5șV1vO@@$󓒰ǒP\mtS9.ٛIƑ\ᗬ- ߤ| `.6^_c2C3g\rYiEi'L3Yr( ܣ~M>;XED7xςꄷ/]t>w(d=Ӧmx/ށ_-e׸4c`ܞb1 %p`ruwظW}ᛪ m43Po_8DPS۴DcP%$F |A# )Ecd`I0 $,5[ֺkvwwn\?{_-`}XVMBApQLP'% @JphZ1 p" $$~ 5"pWwݼᰟb6V֎H S$}x U8: 2H!@s7G@@IyT^j<[lDER܇_\~V٫&) }yڼ5_KmJJ CK9vre[Cἂ;Ѧ^*8Cͫ=jYyU>//3evt_iY,3l֋k(rpL-ϳbN3Eu\=54Fz;\ !cFIWK658R&P4T~g)} a-3-ۈtcѲ.-;SM–zaPcYCOĠH-mvJ@MĐmC[L{\Rv ²np4fXZU9 X<2s{9N0,AM( *0/q'L#~ΖZ}Z7^6VZ">J!Gi!N>"{l!y^{Qv".4Cg(=j3L QLc%cّ1Qܭ[=[,XYԞi-5eWoϜk6\Kъo9 ր)2gp[vÞ|7K2ߺNr`0xkK;Dh z pO0)˽;~1S- HZ6MQpW0 K[Vִ;p$ - f~E0')_ ``.lN 7G\養󾚶NFkǍLG-EU'=P\ӁV|_X_%Wp|g qZ۷ ]ݩߙolwrl Yj C ~ݭSzUOT4 _>mo|oAM( |>8t  ~ɗF VЄipqSnJcrJnPqn lܼСeAL?%R%ƸcR|wl5(]U-Z*0ƍWl1Fn"]t]u_%؆[*+Us,gtVa>WUھ7'[w'D5)/rR?O'ّ/}I{+6M8BKg_0jjp(,+_ӷ/5`]OPȢ>&gJN[\yudFCr^bc>%mmd4I~sD=k$wa{x<ѹm{mX5R4I; nyB>J6k;]S8UiMIk&.4S:~K?tSUsY榬 +|9GBu I;u? yH reBťCjdIn;NDW;0weLVgٍje3U2H)*tRFr)t<{"r2}CijW7Oo+0w=`7 V  &P |:zۮ>]*eiΔ6rIX&#|u+^S&ap;jKNůWz-W4R/(jkj6 s@``ȏ<'ʳȵUScI\_vm&`` m6CgoNrq';PxHѨZ! A!'V$]m]̀cOz_s*Դ/ Pl`eEN7LRp1'C7j&  .qfdw}wܱĆ~L"\+m`n BII" $,&.@o?mdakѮZ'~_&o>wX_7~WXmimޭmj,n,[74%]bW 5vJ$S4'V:|Uv4ōf~:)j5K |X%༻͐&) nFRiԦBS^e?Aջh[RmШ ݰ)״5z;[Sdz6ۄx:Olm7s nrt|Ռ`V\Sf<^D˾91:JLiϒ$³kx}!&~y&*mm;3 |'PL0B=}6=H\r}p_'wט+sevqs {IIY-I`íߢ'ܻ4c/-^DRaiT.@`oJ%mx-kg340L> [X]ݪk.i|Y ng,v*=}p6S{}ɅuQ[-|?v| GP3W@OT?`GMn)k莹4s^6%lڳP"`ZEǍ͕4q<{$-- Kڿ=%Rl`&U30FٛTmi-=v}U6 9=J`ڊcs\X 1U',TK6YDHOz=!`ltl*Z%k`#UmNyVyۉvt?@XȺ"9фpv';ot]W7JI5?JE>2w3%f/J}`c*{7nD`3BU!kI47? :LDsAbnqFS3:^YBV/>ɻ%Hl4q='Mά `"B@][ o읕vYE\f-0ni /ǹ:\OfD^}iLIBN:(ݧ-`c*6r Y])z^qâ lld Je ѨH>zAg/ŐbNc-{@82.}J,g0P!x'qg%(w֔˶5;b*F,`! `:B+D}OA}3c&RA4w^y{6B=G%̈́VhGaJ歡\ڢ._m@܆@z{.^kQB[& SX555 s9uLRǻ(PGx&V$LG܎`:*GYU7 tfILp/;,tjx$ q1! U"#%1hLO"‰ZGGAj(=y3~.Hy`b k"!%T^Hs iE^Y7Mń4;RMj{LPĩA3tnmPKBU_i2%YժꮼL0c p8\ vڡ#hVEJ$qu{4k~NkW"IDݝoPcG}Ca $:/t]osx g0bꫜɮcr[\zRH_A1bBNƳmy~g?::XW^57>2gMn>WEu7PR4ҫA!oqC@&~ŀQ9'kZ4k@C1i 8V'n;*jXl]KYt)nD,o8$ U>IN hEV70r<+N `"bQ%|zJU(,ՠK{2|Z%*skFVMڎ[stk401ъ.QbOFk7`&": wh`j0PM[TQ`m?SsuqM \#B5Ofp{nCw@LwDĢX# ꠨"PT]`,2@Qb쑏$[I,lζoy*ozNzƗIc֝rߒu`6H0Is#Hrz0HAYİh$`zwYn9)nR'K E$`E ,‚#E4gHn˞vݲ-)[nIBlYa1FD"(<"!^@xGsg NW_gJQ'E{0!s8+e/6A@N~_/3,Ć;R&P&|颉k$38O}E1c<1{.+ͨͮ{4 vX "?9} >rDcq|B6g=ORr}:B}2ĕV Q|KtܼTyxSoo;AqB[] -ⴝ7[VΌVO#"P$iæ 9qdc]-b 2mݏh$ta 2G_H@ U ]LҊ({>_z]&2PaOt̰%hc<_%~biWGA"˄F  XiL+ nprN?o$Ix JX{Edf_Υ1v`K|W~bOl&9ϔD9'=]=yqw!1sv8?Ʀ?!)\$C1懼ɡRI|(8ha&s/ؒ9Ru[^؂#7+Iu= U;uu옲nYa&~., E|AK̤X2tPYDzAw%̯%aWHW*uVH![2yee/ x=c6$V/xLbfV {hOtbyLd@9 "ƙ˶%3'ЖV9DD"%R0~p+$1fi>6y _D`hO`$>XR'(pv=}_eɁ9 k {'g*p[FsZ aGcI" x$l;e"hd̷x!WN[S&3Xxo/M/F~qI,u܎ʼe91ؓe(t8Pظf?U Ol dVFdV+#ȅ9vȮia;,vX2,SF!.a gyj?=)(bDxe3 _e^kA/<,hK"^WsD~ϗKz09)T07/H\TY mt^;ʅ_X%|ku[ֺZm*w%L濼1_º@ E]w)cDEQ~]o\yFQ@ym=ʬvzw' XCy@G G%sʀgQq9Y`'3baj񉾫6pe"k V/Z-/<7-e/cw;/εcf91kDFRx}rDHvN!vTOQ$JFꗕKP{ ]R8 h$S}WdPtC#ekpr .b"b8.Bv̠ٙ+ͥ5W f+0 ;k{"׻e{J'>j#hON2~ `hU#alq҆_a.p;Yo^=W*Zٜ׬ϒE2[V;4IP'۱iKFo6ŦLaŽcҰBWJ*X rLЦ|٠ݤWo^KLLC3}?SDG ؎z0ze-$Rl#zi7KTP+fK`#tOӜ5ctKӳO6~G#m[v+ c]vf-V4:"T)':_{Fg|'DLbZ)QGj4ZAZHUEo ~5Lˤ 4o8 h$14R ٿ3x Q,͂z;m3=ʈEaxƢ=%i_k??ƻ@êoѢQ kp+2EDZ[yN ?MoӛO:__N.<@%{h|K(C瞓Po*l l~ ^T-zMyr9%GP@J#! .biX WgJ~%WR+xTg⻏=)RPK9ϡ}cȿVu92{J !3>Z0AV =8[L<E{ME<;qwUyLWह5lj=1֋ MNo&.̓hv"@L+> [i(TXe`#xⳢXr\X9wZ1_b.K+z_֢-k:+3r6Xa'UG*ߦrXǻGr[[{db[o%r X=8kPp\}-Xxy|6עwoۃ.x;p9ݶ޻ۻo=wsa#^]-9*>6xoT5\e:Nãޔ"_ t4S;K+4k}FNDd!Ȱ'BC}Rּuh5ՊH#k,Vq) Y`k=GLu# #qiF553Բxgbw#_ f5Zn_J2s0(3(R0s)y#~/wggzG- ^r^}+g^J@!fP6mnڠ-n~n.;=suG7mxu|)W89TNm~索1o߭ݪ՟&WfnMkS Uobҋ'nda!kR 4۫ 3uom#ϓ%9 R벖q'(W{*%tk^Jnfݭ LT-EjT~miFwOZ@I+?O#b.KRAJw)E\B W•ك|C9X+x CeD bQ|v ɷ"Ezoa >TRWXqebw~stYR=me6.Ŗ]&Xk8X6l+Ui)l&_4n]{ۛ~9iɓ|e˔ieVk{-U Rva9S^9~N~M³0nVK7>T͞8O3e7[!_)ꪯzRn.w cJXԕgy1㳕}]Wvrܪ!̳2˲51Kr̭oq{ȬS̓A6M m%xEk/tYd_ |٭-F"Vr>C[@gxɅtPM5,ECʿ.Fo*_]iP.Ҙ+ۨ'ʸcXMIIOw3M`ٷE-hƜ|nR7ڳҞ"YKXGW[y 6KƂ( ,hWۦjhsr'9 Ё 7c 3B:NOpZۚӫ-6QcuNV}k153+Fw~c7 ȁrm5 j dS1Xk)K5:S&[ 5hLqkQiFEN%0e RaӓjM_m-^zXK:0\?kRV`@uQ]vKzrzl1ƢUjT?M0lvmUU $D~ UCom?gL'ћFk/g㞍$E6c}RtP.Rw2= ,\9#4=~a,irw,Yb?L5.˳tanLQo=Vt)A"XQzY.NAb)'Vࣥ:K;[[Ik2_JT[r+,T kh=WtĽ<*c;l x~*_{ǺG?:OX=C?#>jT@YC ZMܲts.q@nӽ;=u?~@8DZ]jm/37>@KBr꜌K遹ƀc@&WMǢ]ko'gjGxseǟ~=sB圹_[~.(gllnvab[%?_ՑcR9 NT"{nALZ5ndҙ|'-1\󷮶ToqnΨvT'M}4p _f 59 }3"$\X"PAt[G ⥟I¿3 NLz 2 φUز$7svecR 2*A#fN4sО/-&gdmx#3gץpaPl© 6g%S",&>.M2 5 1`bq}涔Ϧ`WhM[#=ڳ%(+ޙ=_`&~ƗK#ioAApE/r2*=.~)/S}l:90!LU!5ϙPB'JWL\FV ]_77jԀv6-ys Q#)ʶͰ!.0^Βͯr@.<ٺ0mzפE : 1$IHʁbe-_\pptm1h^Os"qw+J`x_JPk[0(%a9n_+b^|LičfG%eaWD&Fq d/qBܮr$A{"{+Bgq!Tb&" hAҹR٢do Lu~*RUޒ-4G:]ɴ0[B<) jQRtgۙ; weXG].D-p^ӰIb39: 9+[*= DD:kRk8c(tУb]1LB(!: :0*8:2K{Q1 p4Y`[)悋< `"GI@ Puܟa# Xť_FylO[ o`mۑ4/6k-Pش Õ|D1_W<{~tIc K2J[?}X!D5PIDu8C.CT=Ń|Og5C;F9iaNJħ,Xa'͞e\5.a2gbp9w˂$La͙`H,Uk)T.EfjO5,Yu/hr=\Xk_;|39/ ,>w.vPB!Bhc>L%y"TLǥ},vb4Eܶ^"ۯJŠ W("%0 G9ť\WbL U c8H@oCjp S/SهK~81D}qFƕlq\FZĩ`j䍣!)/.+[ DŲy͎.`"UUmN637|jvp1$@ZV"cv(ɂ;R~A^v-ъ(qP HHb3 B/0"C"2ue%̒+zk$\oD//v_̙eN_8S^H|b!R,Î(92>ߌɰLQq4߿"g̻U|#q_=;⥰ɗ.z_K!b m"ybȐ!q@K7իci,rloWݚi_<^J sH#!ʔ՝I))P;_Еy1 hz\F =,Euan}yhę̳mB͹Xs8.hM1Qa*l|\BpJQT5X?5~/]XM Ih 搌T%XQes?#e<~ֳm :N#Z2پ~ԩj'[5݇y{/m6NƟ<. G]ZQW_S暥!V,Rӻޛ E֚׭QSԚEi.< `m@@o 4֏QᯍӃa1p/#rhqx/V+"cW:z㱳v0;>W^0@H{ĩ@gMH~zOM (N;4 pܸ6w7A:caOv [t (h{C_ɍ&>Jyr9|x7D:c 'ǀ=П^>W։[@QLxH!",K%/(*IJ/Э4Pv/@0JaɑCN-[>ܲD]$X_|W/2~OnI^$ E{ 0j)|~5ic̏[/M[4QE*$"P$cDUˏ&N&TO#yn6&y|H~>UP0N tH^@`ꕧob~'e2ݔqw5 Oi-6C'^Gyn͇ue0aaz',*^?kp>V/45zi%z *RIŒƠ p\.zp!\. ;\h. [d‰p| ¸p.\ $N ÒI+p? P Q5"pFAD/A&=<#VT 7P6=xr;%j v#S"0fm~ȕ;3 <b$4PdsěR2JN)o&K3"9emO_"g08,@~M:]Zb1Vkr/),^ҲɓJԒMƷA|)c xSI۟ O| ->wM=?O>>d%;:4ְ!É<X ƈG4!։T(JW{FVY "<ּ F*MϞpZkߛ>6/}Ugb!q/$Vxle^UjW 8ZpkG <.깊0t#8<.+mmokXU]م:5:iaAY8R:` RX(.k zg?y%'|+@aB^`NHn!$'0+ < hg߄f5x =5keZOԶn8Pj|' )?%BW ?-v5`X Q-G5;zR#J= KN qM3gb*mA]H.tOV)Л.iЩl֥Wdc#eN+z5ou8m-:9-U 8A}tR.wfMR/ݔVajV$)24}^goZ;+hրD9FncɫKۊ #ZK6<־/9is #Sf lwu}ӳvi%[8hs3Y̸%͙׽Z o[r5J܊7\{H2^ŝƍIdrfùC͎[NtW:*%jpFN~w>CyKdyΒQ'UZJ[ɈYtIUL 0&tl`l;G8լYPK?qnl&gEG5(֖Oer%yMŗkkj+^SXEO~ q25"`@ o #55 .QzM@ :LT)!.?~mkV-_-rmK+D`Y='O}+x"H3pe H|$<Mgpk' $K)PRsP(2]wq:c|8shXji(b_2o;kD%Z^0&6x'nϟU0s_ZTkWپy&&ޮzǍp"TkmNtбwl«+^x9Ųg«+^}{kse$oϼ w. m@t z@y@ +k43RכV^P 7nP6{-Jʙc∋z3mʲ r&5wG9)vyS% AWUlD"799^zrT+0C"퇰4yG :bj1!dn=; 2u߱4ɹ+ ,ΨbT1]jI?"?],z2e; U,:l7vIh_ ݞ8IMLU`*-J^%{/Ӓ> dVe$@+O†%8u)j4U sM6MM: ۄCE$EM/NŴIc"DZ{䎬I$8tRR;bGAxIYik_NUS5rgu; yh,ÚʛL}S4l?&er(9WKsft~ 9 X>\vKiYΘ*UfsCⶇq-9#JD|=E rF q+; S E\̏j<!q0gl e/ kxxH@a!tH@a!x4 z%ARܫ \ ߾boep퓞]=og>ՖlտpMƣg\ V.K erNg[XѨe|'m̵XQe(<}"wow-m,?dhˀ)6:rG5mqKVp2Ô:o,^-/=L#ڡwAxT-M3[K};,Tm oAjlpZф`⊚x{|FD`([l5#hj[-m"f{l}VM,ضۣwUbf"4p)H8)[̆HKuO"/a4gPo|qOLܶa|״ikJgV8]F༆K)38fS""O^{[Gz{^#!'gy>7kqu+@2)~D]"@5{-l҃ /s'ՂA M0RS-"jEh 6΅@ص0kbsnV agcN s{hu~oDH  غ1"?fVX) #+dNrgcHOi Xx7NvjU#kiʩudoӟ2_,W`o'/Smj|10kAx.[wϗK؟?تUU#Fe?\tnPnOj~`!;MXm}5Zx;kC#KvrxY-={}]ka*ǘ7$$s%IfcԨG]Evecr.߶HV>PWP:D};kDŽ٘$@\N4?:$ i,ǕҮ:ģ>CQ;i;", :^Y!F̭ht.cND_d-x<%ŋhW3ɛ kQ>"rB9YF;VR,q]\adl_EۋyG[etfڳq2P!\ `Ҏ-Ph6: In\8PB]k 7v؉G_lsσ:O?Bҳ ꀶ6c?~YlY<Pw8 is5d.ۨ=sc@WV`\PN%l=!'`[[Θ?fBۦNs+C\gք7$ {tyRM8 [;+,]HYa*)ph [BM [w뀅0KG/ Z:AkVjSVBjVVISHzYkJ՜,]lH -cEGnb2>솼4x $} UсA=s=r)$\/{D-B1h42A0f(h4!ٟ&X2 Kdp_!\SlݼKS7oK_#ov{wρTN0@ >$Zkyg`n&jےgzF,!Z`$HP,*j`45{ZZh"qB")ASs"^X= nsSplRȄi1s$!;$"s֖`|J0`ñ;' aD):>͓|uރZ~& +`ʬKh~'j_sĦYlpoTS ;P=mV_\VT@O6 p 3 =XˆThZzwљcTEZt3wIC;nCd 9" 9w=C fۂ6KT󠃭!W]4+lGu[˧45}l_DoZ~KeFB!Zڙ[̟-U8g5l+Ӈ vEiKGC4E0X^`ul5UCGvhg3J[\ͱNIFHOPFJ~HɔJxQחsWV~vw5ʺ|9hc2IE$"($ut-ѩ .ǼutG;oIg4F[JW/v Fgy1f=Zuֹ>K';m^aiDxax8M~-]'RAlܳWiQcNm|rSOvzo?X/7 Ez~zz V.dAdxdd-;5n-Xr6dS>pڦ5pT6l8N:EqVwHd(5?&\hr{w1X>̇vF+,3iUYYz 9Lo 'χ͆x@yC]Ot/}vGw|eeqI:d|r nΝr,ŏIG:ҭ vTZѻ/u)vŋiMQ 叨-9fPYP}x}Qlm}ܷ%?Tke*cuPy\ L̓:hJ7@^H /bSp>/᜝ml̃:M I짰JQ02-{@Nw߻ P:V6i%7iOSuTq,a1bf]}~P%:1Bఉ>Ex*zz`=;_-|WR#g>arD4 Cb?U 3pD'f\r>GFX`( !F>`3?O/hWPeHlz XE޹Dlp4\lp-qRsŸ~I@i,"=3%m$$ *0;8` 3?-bbђ+f  L,hT9 ,̓U: ?w$1tTs`oh2"()Sl@.99r<鼇K|߀A{}beQ*+o 0 {孑՝Kn` }cJ;ƚ?ߚ"%K;-Vl+}\ ,  t$%rD->1( !]²`U*wn.݈KjWe!.XA=T.-Uap_|##Eo`Ih Ia B M>Ta hj9^WT%@J  unʹvvsn~r(}}n`vѺ/\ĭ9eNs]ɬ[ImiXjTIU!(  >HPD |J?( c>+"a^$ %/ 3DxjZ7k&D} #Zֽg]mVcj\ WmX՚{WM;[Z~$9T2ӥacG5xu-:=C[`#_6ol4Ξk eRa\')digfeK70 BޮjvEhQt;: > {Q{L PpwPIM4L˱.%Wϓ5"<N0<,'c7<7^³hCGU۽՞{1x%*su8"Ah}R_sfzqXNsH6{|`7hzITQn( o~&goWj>#m QmMƄ @~Yӑ$Y@.AbR23ZP?sDKMcuA|pXOjk^4J׫a˶E? H^8Р?o -(E9]- kgCUpx`a $1[ ni"va0Eh5Аs>e/m{L鲯C!s+X-ͨL `I֣3"b7aO)AnK #-9.p4e?3T[24e|n4Vc[! - ;B9yzij]&T^ xm07o;qQz?1>Av@tֻX-~;_JBV,@#Pa{L^ΒfIH.RA/ Z-N50X&%qR@@@v(ExZ@Oe%BPt lrE:0&"eJE}H7QRA=ەʁc {Z|d^;8%3㩗_J(35%Ux>g|cTY? 3gԺ(:kӬTEK5 5BnjJf,yJ a 6$]jeʙ8Y '%JL*"|BI @L"&*iK"nq-C~+3Alr7IYAuZbV cAИ _b%)*,*_|%2,Od!"zB;< ;Jy 1]E.33+- M"vTX TN|eQLĕd$93\85rV9Osh\yH#>/f)g*rS 1?œD pqa-b%H#mzY&̍j}Ճr:6⬂0)!Ou%A5VDP=U,!S+?P?\TitȸZEyg"4] |MoJPUw [E' ^Rq3GSVn1]E}oX"olLY!Kc%UĆc{+pк\O8D2HĎ"/.|!4if4)9sKDai aId$/H/}y^;nr1aëu-:"h#V$u1bnD-D"KLm[-TS:KkU@mbS4(!їy ~HĠI74kD7Pl!v#WH&W0 -/kehꀙ2U#V\^Ǫ<*0+*,LbBd!*[ryp-d&قpp;G"efZDl4ꉐ$qx6ř%fAS`XeMDiz4ޠ^rXC9 2f, %;/Fp HY\k p`{ \CS ]%BS!bGF!c :Z`a-ta&/DR,dp_,)h/d0ӍF fGqPQ$"~A?H<9-a-S^-%2_D άK,)##%&e!tR_;-V]#`iCB!?r~qKF]T[0 ~ y=|s>MRjBf81̎93!MVV_yG&Tw\n2L4_Fr8%W̴%7G$H&=22X %ު"g#_-璍-j9N2A6Ō _`,lHJ i-0-DD *Ql>Ë,LB*9PBbZnV-tSzu?JD;̎[drzrB A> 0 2Yϙ3Sap-O{ 2RU$zFh^>1? 2eF J~dEۋJ6 ‘U$D^Άt68E-_K޸oW[x .y<};7ׯ˒=Y7͒pV>в^bE HZ^9)&"\wjl}bE/8^,|l.ힽƘ`^@ vNŜ0kt:|3k8C/ކ*ԕa0ޒF킚2ƞ<6D]WjN)uH"M{] aKǣpLdo/`Sx{)l)ɏ뜑N%z&IM i 70ۓ/AL@!A[ƙcĄG vB+Ty?̩#-?dWNYyHfYim ^{Xn8+YGrhܸ~DMf^P'艦[tWnf:^˶>1_j/B_+*ez:Th-XmMK.Μgdr-[^ÂVM0LSuɯ/;-cPi!P ޷B\EpjT" n!LG~297#Dz颉"q3HYz"y'ٷ(\]"+י#[ &XS{m9] f4_Yʼnzݐss|  G_N_䝾73|ClБAG~$7-R-t7ۘ=9G QB5Ez_N28v0YR%)8:-F<,W>҃U^_#%wc$`1p!)Ic0_KēS;7d+}L`PaXQZ5Y2Vu-u[[92"{[:/?aNEJ)C/cM#t5d/ug$RIoKLխi?0h0Ԛ#aB/eE""FxC̽VҒx,ܙ$ԋ.ˌŢ 1<9G-O;PCDhfˋrpy2t7ӷO^`-zi\$XߋOO^p3/ ,Xgd 7:Wg.4صw;:Vε|]-MkN [dn&rE: ?j/j8:2G0N5& nn£n\2v\<Tգl C6Ugeo+ԃ[$b@b{ sd$ mg=?nDOS04qK0'Ƅ-dbH#e\yy:;]`#`SwQGU[Ok޶1B= R0De\CŖE-R=HtQw[M'G=zMzcSsgNc[Dʎ ?7`e867{iCsEi'4lrϹo'"\r9!.|Rv}ѽc:-Sn-l&hb5suݣ7U[Ghoo-g091)-܅^]P3BE"}6CfFrEH[g:2-(E1C 5w߼L2YB/λ2w :RB$D?!lk6"%D*"e`$?*A@<ך)T۽*HL rFQ8ut>$-x 9λ8tIGם L\:s.k.gzYSWt%DV:Oa: 654uCl6 ekuц*>NTuJPxH nJ n`\"*ɜE|UcoQ3cGy]tE0LlE3f ƄjqMF<=rq\^ p H̬#j.grJHOJJ%t/# deö-%%ppn"(.U2y|mf"l59$}E-Rr {7s"Pc_Ŵyy'ezpKK[hgk"*. U]G~ŘE8H T_!b!Daye[nLE2r CR3?"-YDq3eK⦗Wo Ygl'(q\hV]xX2] * %<6b|c!h G9΃)HZet`ה%ҙI-<XAFDLg04rb?_(a, i+{GF! ei8ǗK/{cx*/`[0@ 'f#\{}NG@Q-DLƹRGybDĽV'Fj,yl\l$-5?2`~h.BW`0Ă5 ւ ΂MQn T R{2&BW] mI͢ /LA}?s 6% 9ސUNiES ~7.CQm$etilD"ileu >?`*0[:}j`Ha'*q$pQDh;G!ehfZY.xЂkZJ=C43ej˖9! \nϙ3DnעXeWN6U%mpˡ "gvf®W`Ɋco{%'8H実5Ūg̎} !oke9 5W$!dL0;S0ʳ;sp(5iP?obb.ÒBH$|6;[.H2KZf1 Ppv :X,~bg^^{9m˅?{)jKsv&d3k 4sI?fWWL[_l'x(FKi5=ޖ/ $/PbX4BYP9 Xx~-G\F\h 0/I~;&Z䲜l -XM( 7'tW] P@:6Ҵ1QӚ 57$727.M!)g?'0r9FEȻE,44CXJ~4oM,+m[͘SQ5'䨺&ssY2lbӌe0B>*X0w&c$~K? :p;?o}[5 h֐RŴTZJ~ZD 'm,RPXૂ * ^SkirBz;J0.NϺjmx. { $\0-sɥ]\&x?\kmtFeH/ܼtV:w/Ҏ@ ~7==3D zzV>}fӐg=G *%ʙJ@alLQآܙ=\xS &/ AytM3A_$n/d sU,?وA" DrɬDap;_fe|ǁA$T9Oǘ-[s=>hˡ,jXS.r,DAv\p,Ni  B9@◙ZOn"ݬ/Qj-FF胤8e >7oޛ=P 9ygfx=Iϣ"VDihŎ=ڸ%[6aYAQGmy|![lN8X"-20ɓgl.dg,Z!ۆ^)?ˁ Fa2-אwC~?Ӑ]6W{J HV[^ar]sr} P\C=`RPrQ 4n٫C`aKP`=3?=~E EI1 o #096^X}tS^_f7; \/;fg!e-aQv[y=a "GpS^N0GEחy6>0iPaB 0,,|ba2b~H >yklW[rT`׆9fe< c^N,hڟ}Gn3hT`x}+}> y ա;X/g/o"3Cbp8_.62AƯr~ ]s2=5.]/EcE.kjz,A+䂖˦KW Mc>=t=q$.j jYW`iUT89GBP%^R@:90z 0[m? :ippnͽxJ)s]xC?pShBJQVTPx*%PT*.O rH&8 o 4c]dcXq\E>85$Q0KݜF&s>;=:dOx ?>=7LCcF2VYrU.gv١'{:oú]vn }e?KӼ0"sY9GsH{c2Nm L ;n|y&CfjSA6-eងdOQpdGLٓ(bql~wu{rJTcSae| oid'K[7ڳ[zqBI(`rWwݿ_P>7ZD5MxKݫᲑsY#G>}=y8 m?HW8*u *V5BM֕%=Q'+M&*ȜuUB#{<aVW.&уh 6jy(މ5TS:z MUѸriJ׭oa䙹LM7v4&_E"5iR赖H_ <ކ]mK'Ϸbo>ɉ60u<.LS숔Uޝ)%\oM+z ~cno9I`X"ƭ!˫NNH$$.'aP3S'du6Mf^Q2;&a6ֱ"CAý %jqfKÙOȌz(p(mDUt{<-F$>Wro/xE.rf0#㤣RM5FF'-ziP4 Pj"{#s[,ǣ:oH`L ߿<ꯃ@z$qK8x9շmuLN>Mҧ(j:E u!R>KXL36Sݽ]YdؘWݰhȓ\\a5cީ7yO˱ş|/vS]Iw!-t%6%{܈8oNm6&ٍsw!' TQF)|@kz8ܮ<⭴ dN\d%p3͙ӣ.@N~ЭՊh(YD9mzpR컏C L@rI)tfI4l#{kza1S~A:)=JSRfq_a_L{]/ˆ0L:D2L5obK2Œ>[_<{Lc{&X̒W L̅8;ig\GkD{Zna_{}ܥmBDiXVٯwnj !xQSwntK~^syv-4T"AXz&*o?˵͵TC%{vǝ[[<-R+% rԪ|:_7WvzEfH rF.w8b_%P~}k(xp /dbƄ Ȍ> rx-/a|]=ov*O}PQng}0Cf駼op $m^ouO;Ѳ=wퟯܴ «{o[ퟁo+?%{Ѷ}mɶ>8Hɯ]kr!XZ_ -c7W_Z [;Ic^_)%ʗKS-o`ni(w 6&ؼ]FSkoO٪9u88.8 ,DrF7 ' 4Bk"9 c71مD`GNB."9 c jgaٚCG0lƁoDG00 DZ. gA00h CDD݀GċCiS*'Z恩Ꮳ5>\u 2O&? -Al[ۂ|Tp Bbp}VF ;2Pvq8ڑ@}#-q '욤ūGR.bXʹܨՋAՋaSCxbh@Pbp4`è֊Ĥ[+$^19XbJ0x1Ehb+U+X*mTCbT̩Ԑȟ 2">/L|x\lDLm!&#Fa 0ĄQ F1"a0AbD( #aF0 ĈQF  \Ae\8agH\GZ\jcq v-[i}[`íǁ7oL+ |? dō"ʧ𹀾\;s * |׭(ț{(+JC &sQ:w=tS8-?w0mÖ7{ t^B߾r_tyH|~EG;馚iN &ZzGTu_]V˙kCUvGp` 9tbLbٰ`S;6"-[wֿG\`i; Ͽj;-0}/4$)3{{^;쟞!\؋/a؟g*EO ذo0ìÌ'NV@.bAqAq]A]Zcn0I5 rdJZZx䶁p>u$/*|]m& ш1. ,ek';GjMN٤ Gk ۶`^<)6yݍSO}ܺpB@qG@8d$' \ H .\ hTndׯ{:ǀ=Ue\C>݀Au _޽ڙ@~@}(z.F+|R|vqpP喅un76f2Tzkܑ{ou;Ѧ_>݊+`j%B P %PB%B P %PBƅhtE|a@0H2<,-CPpB@A9q rAu?ڭ74!e&2тS kA, pA u) t4oa 郔d.1.xB#BMܐ6"p?th3鸨 w*d T\qY xZ sd‚ePkPVD`P%ԉjmj-Ma<][*V=QvxGtB6aw?mi9k)s׊XUu~Mz9'M 4~-W`{8Uw|3`t ^7P|KׄJ[NT~k %u`XFݣ11|y`2S1.n^7L^ 5݋Gx UHдWJZ[1Ʌ*֤h8WxZ7=(E!{T@צJZ>5:S[/&pm:F5!jpqrŤ幯B*y#k *J ?F.>&juCT5Fy2 xT>Yk ]5//ˣ|o RU*]MJ>Tj.k@ 櫦}s^&SZ;ULQ94?nU8QgT%dVZUr,"Vx/|}:O?ɏ[HKn *U{'ӠHX򷅪O~:t_P2Yتn[Tmղa;Pr~V?XWUS 1D^񖬝ק*/*LJתhJ5 5_'QjjV(<tP%B P %PB%B P %PBtqsl-2.0/apps/help/tqslapp/stnloc5.bmp0000664000076400007640000277407612231073120020032 0ustar rmurphyrmurphyBM> 6( (r h' S1#L>8/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)%%%111777<<<@'xZNb][/,)1/-𢟝1/-/,)OOOooo}}}ghhͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻᢟPPPrrrqqq-*'ͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼̽̽̽̽;οοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾ͿͿͿ;̽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻ˼բ-*'WWW```0.,ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾ͿͿͿ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼.,*III222ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼Ǡ222-*'ͿͿͿͿ˼˼˼˼-*'-*'ͿͿͿͿޢohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb˼˼˼˼-*'-*'ͿͿͿͿohbohb˼˼˼˼-*'-*'ͿͿͿͿohbohb˼˼˼˼-*'-*'ͿͿͿͿohbohb˼˼˼˼-*'-*'ͿͿͿͿohbohb˼˼˼˼-*'-*'ͿͿͿͿohbohb˼˼˼˽-*'-*'ͿͿͿͿohbohb˼˼˼˽-*'-*'ͿͿͿͿohbohb˼˼˼˽-*'-*'ͿͿͿͿohbohb˼˼˽˽-*'-*'ͿͿͿ̾ohbohb˼˽˽˽-*'-*'ͿͿͿ̾ohb뺺ohb˼˽˽˽-*'-*'ͿͿͿ̾ohb랞ohb˼˽˽˽-*'-*'ͿͿ̾̾ohb뎎ohb˽˽˽˽-*'-*'Ϳ̾̾̾ohb|||vvvvvvxxxohb˽˽˽˽-*'-*'Ϳ̾̾̾ohbohb˽˽˽˽-*'-*'Ϳ̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾̾ohbohb˽˽˽˽-*'-*'̾̾̾˽ohbohb˽˽˽̾-*'-*'̾̾̾˽ohbohb˽˽˽̾-*'-*'̾̾̾˽ohbohb˽˽˽̾-*'-*'̾̾˽˽ohbohb˽˽̾̾-*'-*'̾˽˽˽ohbohb˽̾̾̾-*'-*'̾˽˽˽ohbohb˽̾̾̾-*'-*'̾˽˽˽ohbohb˽̾̾̾-*'-*'˽˽˽˽ohbohb̾̾̾̾-*'-*'˽˽˽˽ohbohb̾̾̾̾-*'-*'˽˽˽˽ohb돏Ŀohb̾̾̾̾-*'-*'˽˽˽˽ohbuuuohb̾̾̾̾-*'-*'˽˽˽˽ohbsssohb̾̾̾̾-*'-*'˽˽˽˼ohb{{{ohb̾̾̾̾-*'-*'˽˽˼˼ohbohb̾̾̾̾-*'-*'˽˽˼˼ohbohb̾̾̾̾-*'-*'˽˽˼˼ohbohb̾̾̾̾-*'-*'˽˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohb½½ohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼˼ohbohb̾̾̾̾-*'-*'˼˼˼̽ohb``ohb̾̾̾̾-*'-*'˼˼̽̽ohb``ohb̾̾̾̾-*'-*'˼˼̽̽ohb66·`·6```666`·66``666`·66`6``6ohb̾̾̾̾-*'-*'˼˼̽̽ohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb̾̾̾̾-*'-*'˼̽̽;ohb``66·66·66·66·6666``6666`6`666ohb̾̾̾̾-*'-*'̽̽;;ohb``6666·66·6666``6666`6Ϋ6666ohb̾̾̾̾-*'-*'̽̽;;ohb``66``66·6666`6``66``6Ϋ```66ohb̾̾̾̾-*'-*'̽̽;οohb``6·666·6``6666666666`66ohb̾̾̾̾-*'-*'̽;;οohb6`·``666666ohb̾̾̾̾-*'-*';;οohb6·6666666ohb̾̾̾̾-*'-*';οοohbohb̾̾̾̾-*'-*'οοohbohb̾̾̾̾-*'-*'οοohbohb̾̾̾̾-*'-*'οohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb̾ͿͿͿ-*'-*'ohb𕌉䏏ohb̾ͿͿͿ-*'-*'ohb𕌉uuuuuuohb̾ͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppps:q8s9s:t:t:t:s:q8r:pppohbͿͿͿͿ-*'-*'ohb𕌉pppr8u;~@FOV\^^\VOF@u;r9pppohbͿͿͿͿ-*'-*'ohb𕌉pppp7t9DSdlqsuvwvtqleSDu9q7pppohbͿͿͿͿ-*'-*'ohb𕌉pppp6v:GYmppqsuwyyxvtrqqnZGv:p6pppohbͿͿͿͿ-*'-*'ohb𕌉pppp6~?Rfklmpruwyz{zxvsqnmlfR~?p6pppohbͿͿͿͿ-*'-*'ohb𕌉ppps8C^hghkmpruw{|}|yvsqnlihi_Cs8pppohbͿͿͿͿ-*'-*'ohb𕌉pppr8G]ecehjjjmoqsuvtqpmkjkifdf^Hr8pppohbͿͿͿο-*'-*'ohb𕌉ppps8F`a`behicԨxժ{֫{׫{ج{٬{ج{ج{׫{֪{ժ{ԩ{djifcabbGs8pppohbͿͿοο-*'-*'ohb𕌉pppp6AY^]`beghbdihfca^_ZBp6pppohbͿοοο-*'-*'ohb𕌉pppp5{=W[Z\_adfg_bhheb`][\X|=p5pppohbͿοοο-*'-*'ohb𕌉pppt9JZWY[^`cef_̟p͡rѭѭ̡r̠r_gfda_\ZX[Kt9pppohbͿοοο-*'-*'ohb𕌉pppo6ATTUXZ]_bdfeder%Ȼt)eeegec`^\ZWUVBo6pppohbοοοο-*'-*'ohb𕌉ppps8LTRTWY\^`befiis%ȼu)iihfdb_]ZXUSUMs8pppohbοοοο-*'-*'ohb𕌉pppp6|>RPQSVXZ\_acefgq%ȹs)ggedb`^\YWURPS}?p6pppohbοοοο-*'-*'ohb𕌉ppps8FOMPRTVY[]_acdep%ȸr)eedb`^\ZXVSQOPGs8pppohbοοοο-*'-*'ohb𕌉pppw;MLLOQSUWY[]_`bbo%ȷq)bca`^\ZYVTRPMMNx;pppohbοοοο-*'-*'ohb𕌉pppo4{=MLLMOQSVWY\_abao%ȵq)`a_^\ZYWTRPNLLN}>o4pppohbοοοο-*'-*'ohb𕌉pppo6@QS UY]di"m&p(t,w.z2~6ŀ8ŀ8Nӻ~@omf`ZXVUSQNMLLL@o6pppohbοοοο-*'-*'ohb𕌉pppp6J h(m/o1q4s5t6u6w6w6y6z6{6{6}6|5MXŃ?Ń?ĄAŇG>t-cUQOMLLLLBp6pppohbοοοο-*'-*'ohb𕌉pppp6Or6u:u:u:u:u:w:x:y:z:{:|:}:~:}:QT}9~:}:}:~=CMT~Et6c!UMLKBp6pppohbοοοο-*'-*'ohb𕌉pppp6Ru;w>w>w>w>w>x>y>z>{>|>}>}>~>~=TX~=>~>}>|>|>z>z>|C~GJIx>d!MBp7pppohbοοο-*'-*'ohb𕌉pppp7Uy@{B{B{B{B{B{B{B|B}B~B~B|@}A|?X\ABBB~B}B|B{B{B{B{B{B{COV_(q7pppohbοοο-*'-*'ohb𕌉pppq7U{C}F}F}F}F}F}F}F}F~FF~EyAܿۿƯ_FFFFF~F~F}F}F}F}F}F}F}FMf2r8pppohbοοο-*'-*'ohb𕌉PUXPUXSXYpppfffff۶ې:fې::ې::ffff::::ې::ې::::ې:::::ې::ې:ff::ې:::fې::ohb-*'-*'ohb𕌉 霟::::ې::::ې::::ff:ې:ېf::ې::f:ff:::ې::f::::pppy;FÒdÐ`Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_[jk[Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Đ`ˠxI {=pppf:f:f:f:::۶ffff::ې::ې::::ې:::::ې:::۶:fې::۶:fېfff:::::ffohb-*'-*'ohb𕌉ꑙ::::ې::::ې::::ې::ffffff::ff۶::::ې::ې::::::ppp}?r<ǕgƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƒdfgƒcƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdənP@ppp:ې:fې:fffffffff::ff:ff:ff::::ېf:::ېf:۶fff:::f::ffohb-*'-*'ohb𕌉mmmmmmmmmmmmmmmmmmS:N7}x덈M7P7::ې::ې::::ې:::::fffffff:::::f::ې::::::ppp}>TdǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhƔgˣˤƓfǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhƛr[@ppp:fېfffې:fې:::ې:f:f::::ې::ff:::ې:fې::ې:fې::fې::f::fې::ohb-*'-*'ohb𕌉V;y\Z@jlmrtvS:wYS9:::ې:ې:::ff::ff:ff::fffff:ff::ېff::ff:f:ff:pppEp;͟vʘlʘlʘlʘlʘlʘlʘlʘlʘlʘlɗkЫѬȖjʘlʘlʘlʘlʘlʘlʘlʘlʘlʘlϤ}{HHpppff::::f::::::f::::fېf::::fېfffffې::ې:fې:ohb-*'-*'ohb𕌉mmmT:|^Z?UVWUVW붵XByZQ8::ff۶::ې::ff::ff::ې:f:fې::::ff::ې::ېff::ffpppH R×mΡy˛p˛p˛p˛p˛p˛p˛p˛p˛p˛oΤΥ˚o˛p˛p˛p˛p˛p˛p˛p˛p˛pϢzȠyWJ ppp::::ېff::::::::fې:f:::ې:ې:ohb-*'-*'ohb𕌉T:{^Y>۹ݶXBwYR8::f:::::::pppRf-ɟyϡyΞtΞtΞtΞtΞtΞtΞtΞtΞt͝sٵٶ͝sΞtΞtΞtΞtΞtΞtΞtΞtΞtТzͧl3Uppp::::ohb-*'-*'ohb𕌉mmmT:~aV<񸷷T>z[R8:f:::f::ppp\ yEհҥϡxϡxϡxϡxϡxϡxϡxϡxϡxϡyز¨éسϡyϡxϡxϡxϡxϡxϡxϡxϡxϡxҦ״}J_#pppohb-*'-*'ohb𕌉Q8z^U=YErUO6::pppf,SҰխѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}ѥ}֭ճZi/pppohb-*'-*'ohb𕌉mmmQ8~aV?T@vWO6pppp8RִڶӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧڵظXs;ppp::ff::f:ېohb-*'-*'ohb𕌉Q8~bx\O6ppp}JS̩۷֬ժժժժժժժժժժժժժժܷ֬ϬWLppp::f:::::ohb-*'-*'ohb𕌉mmmW۹ݶXBwYR8::f::::fې::ې::f::::fې::fffffې::::::ې:fpppjj_pppohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې:::ې:::fې:f::::f:ې:pppjj_pppohb-*'-*'ohb𕌉Q8z^U=YErUO6::pppv{lla++pppohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6pppnnc//pppohb-*'-*'ohb𕌉Q8~bx\O6ppp nnc33 pppohb-*'-*'ohb𕌉mmmmmmW>$$ºpppohb-*'-*'ohb𕌉pppZZrAA.-ºûpppohb-*'-*'ohb𕌉2^^Rjjppp""""""""""""""""""""""""""""""%%ED""""""""""""""""""""""""""""22úĻŽpppohb-*'-*'ohb𕌉㑑2T::f:::ې:::f:ې:ppp''''''''''''''''''''''''''''''''''..DD''''''''''''''''''''''''''''''''77¹ûļŽƾpppohb-*'-*'ohb𕌉㑑2T::f:fې:f:::::f::ې:::ppp,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,<<ºûļŽƾǿpppohb-*'-*'ohb𕌉푑2T:::ېf::ff::ې::::ff:fې::ppp000000000000000000000000000000000000000000000000000000000000000000000000UUºûżƾǿpppohb-*'-*'ohb𕌉cKcKcKcKcK푑mmmmmmmmm2T::ې::ې::fff:::::::ې::::ppp55555555555555555555555555555555555555555555555555555555555555555555YX¹úļŽƾǿºpppohb-*'-*'ohb𕌉2T::ff::fff:::f::ې::ppp::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::]\ºûļŽƾǿûpppohb-*'-*'ohb𕌉2T::f۶f:::fې::f:::ff:fېppp?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>?>`_ºûļŽƾļpppohb-*'-*'ohb𕌉2Tf::::fې::fffffې::::::ې:fpppCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCccúĻżƾǿŽpppohb-*'-*'ohb𕌉2T:ې:::fې:f::::f:ې:pppHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHggúļŽƾǿǿpppohb-*'-*'ohb𕌉Jff""""""""TpppMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLMLkjûļŽƾǿpppohb-*'-*'ohb𕌉mmmVVzpppRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQRQomûļƽǿpppohb-*'-*'ohb𕌉pppVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVmmĻŽƾǿpppohb-*'-*'ohb𕌉mmmppp[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]Žƾǿpppohb-*'-*'ohb𕌉PUXPUXSXY۹ݶXBwYR8::f::::fې::ې::::ې::ې:fffff:::ې:ff:ppp揎揎揎揎揎揎揎揎揎揎揎揎揎挋ĿǿΏ収揎揎揎揎揎揎揎揎揎揎揎揎欪֞ppp::f:::ohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::fffffې::f:ې:::ېppp锓锓锓锓锓锓锓锓锓锓锓锓酄·є蔓锓锓锓锓锓锓锓锓锓锓鯭١ppp::ې::ې::ې::fې:::::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f:::::::f:::fې::ې:::f::ې:ې::ffff:::::ې::fff:::ې::::fff::::::f:::fې::ې:::fohb-*'-*'ohb𕌉Q8z^U=YErUO6::ppp환환환환환환환환환환|ĺԙ왘환환환환환환환환ۥppp::ffff::fff:fff:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f:::::ff::ff:fې:f::::ې:ff::ې:f:::ېf:::ې::::ې::ې:::ې:::ې:ې:::::fې:ې::ff::ff:fې:f::::ې:ffohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6ppp|Ǿםީppp::::ې::::ې::::ې::ff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶:::::ې::ې:ff::ې:::fې::fffff۶ې:fې::ې::ffff::::ې::ې::::ې:::::ې::ې:ff::ې:::fې::ohb-*'-*'ohb𕌉Q8~bx\O6ppp~ڢ᭩ppp::ff۶:f۶:::f::ې:fff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::::۶:fې::۶:fېfff:::::fff:f:f:f:::۶ffff::ې::ې::::ې:::::ې:::۶:fې::۶:fېfff:::::ffohb-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8f33Z33Z333333333333Z3333333333333333Z333333333333333333ZZ3333ppp؇}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}pppohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R83Z3333333333333333Z3333333333333333Z333333Z3333Z33333Z333Z333fpppyzrnnnnnnnnnnnzxnnnn{nnnnnnnnnnnrzypppohb-*'-*'ohb𕌉Q8z^U=YErUO6f33333333333333333333333Z3333333333333333Z333333333333333333333333333333333333333pppkic^^^^^^^^^^^^^^^^^^^^^^^^^^bikpppohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO63333333333333333333333333333333333333333333333333333333333333333333333333333333333fppp[WRNNNNNNNNNNMNNNNONNNNNNNNNNRW[pppohb-*'-*'ohb𕌉Q8~bx\O6f3333333333333333333333333333333333333333333333333333333333333333333333333333333333pppKFB???????????????A??????????BFKpppohb-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::f::::fې::ې::f::::fېf::::fېfffffې::ې:fې:ppp#bj'pppohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::::fې:f:::ې:ې:ppp4y9pppohb-*'-*'ohb𕌉Q8z^U=YErUO6::pppKRpppohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6ppp %bd' pppohb-*'-*'ohb𕌉Q8~bx\O6ppp  pppohb-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::f::::fې::ې::::::::ې::f::::fېf::::fېfffffې::ې:fې:pppbnnnnnnnnlppp::::::ې::ې::ff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::::۶:fې::۶:fېfff:::::fff:f:f:f:::۶ffff::ې::ې::::ې:::::ې:::۶:fې::۶:fېfff:::::ffohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::::ې::ې::ې::::::fې:f:::ې:ې:pppppp::ff::ې::ې::ff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:::ېf:::ېf:۶fff:::f::ff::ې:ې:fې:fffffffff::ff:ff:ff::::ېf:::ېf:۶fff:::f::ffohb-*'-*'ohb𕌉Q8z^U=YErUO6::::ې::pppppp::::ې:::ې:ff:ې:::ې:ff:::ې:f::ff:::fff::ې:ff:::ې:f::ff:ې:fې::ې:fې::fې::f::fې::ې::ې:fېfffې:fې:::ې:f:f::::ې::ff:::ې:fې::ې:fې::fې::f::fې::ohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6pppppp:::::::fېff::::::::f::::fېf::::fېfffffې::ې:fې:ff::::f::::::f::::fېf::::fېfffffې::ې:fې:ohb-*'-*'ohb𕌉Q8~bx\O6uuuuuu::ې::ې::ې:::ې:::::ې::::::ې::::::fې:f:::ې:ې:::::ېff::::::::fې:f:::ې:ې:ohb-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::::::::pppxxxݽǨġƢȤ˧̨ΪԵ|||pppohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::::pppxxx޾ʪǣɥ˧ͩϫѭն|||pppohb-*'-*'ohb𕌉Q8z^U=YErUO6::pppxxx࿿гЯѰӲԴֶ׷۾|||pppohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6pppxxxNJ|||pppohb-*'-*'ohb𕌉Q8~bx\O6pppxxx|||pppohb-*'-*'ohb𕌉mmmmmmW[Mppp:f::::fff:::fې:::fff:::::::ې::۶:fېf:::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::ohb-*'-*'ohb𕌉cKcKcKcKcK푑mmmmmmmmm2Tff:f:::f۶::::pppCzHc4!% ) . 3 7=BGMQV]bgnsx!"$%<[Hppp:fff۶::ff:::ې:ېf:ff:::ې:::::ff::fې:ffffېf:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f::::ohb-*'-*'ohb𕌉2Tf:ې:::ې::fې::::f:f:::fpppD{Oo!= - 0 5 :?DINTY^djov{ !#$'<_Ippp:fې::::::ې::ې::ې::::ې::::::ې:::۶f:ff:ffff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶::::ohb-*'-*'ohb𕌉2T::ې::ې::ffffff۶::ff::f:pppCzKm&G7 ;?DJNSZ_dkpu| !#$(?\Gppp:::::f::ې::ې:f:::::::f:fېff۶f:f:ff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::ohb-*'-*'ohb𕌉2T::ېf:ې::f::ff:ې::f:fffې:pppD}Lr&O@EJPTY`ekqv|!"#%&=\Hpppf::fff::ff::۶ff::ff:ff:ff::ff:ffff:fff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:ohb-*'-*'ohb𕌉2T::ې:fff::ېf:::ېpppR`qMS(ZNQW\ahmsy~!"#%(=_Dppp::ې::ff::ې::ې:ې:::ې::ې::ff::ې::ېf:f:ff:ې:::ې:ff:::ې:f::ff:::fff::ې:ff:::ې:f::ffohb-*'-*'ohb𕌉Jff""""""""TpppbhogD~O-eX]bhnsy!"$%)@]Dppp:fff:::fېff::::::::ohb-*'-*'ohb𕌉mmmVVzpppbhpmGvEQ-ncinuz !#$&'>]Hpppff:::ې:::::ې::::::ې::ohb-*'-*'ohb𕌉pppciqqOzN~GW0zrv| "#$&)>`Dpppohb-*'-*'ohb𕌉mmmpppdjruTXePT5} "#$&)A]Dpppohb-*'-*'ohb𕌉pppekryX\buFV6!"#%'(?]Hpppohb-*'-*'ohb𕌉pppels}^agmuE\9&%'*?aDpppohb-*'-*'ohb𕌉pppfltс˃ΖhnuEZ=)*A]Dpppohb-*'-*'ohb𕌉2^^RjjpppXY[fltfmtfmugnuXY[H[>@^Hpppohb-*'-*'ohb𕌉㑑2T::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::fې:pppFaaEpppohb-*'-*'ohb𕌉㑑2Tf:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f::::ېf::ېpppFFpppohb-*'-*'ohb𕌉푑2Tff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶::::ffppppppohb-*'-*'ohb𕌉cKcKcKcKcK푑mmmmmmmmm2Tff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::ffppppppohb-*'-*'ohb𕌉2Tff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:f:ffppppppohb-*'-*'ohb𕌉2Tff:ې:::ې:ff:::ې:f::ff:::fff::ې:ff:::ې:f::ff::ppppppohb-*'-*'ohb𕌉2T:fېff::::::::uuuuuuohb-*'-*'ohb𕌉2T:ې:::::ې::::::ې::葑ohb-*'-*'ohb𕌉Jff""""""""Twwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉VVzohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ϕ󕌉ohb-*'-*'ohb𕌉ѕ󕌉ohb-*'-*'ohb𕌉TTҖvv00ҴҕTTҖohb-*'-*'ohb𕌉UԗUww00ԶԕUԗUohb-*'-*'ohb𕌉1Wؚz1WؚWz1ع1zؚWz1Wؚz1z1zz11عWWW1z11عWWW1z11عz1Wؚzz11عzz11عWz1ؕ1zWWWW1z11zz11zz11عWz1zz11عWz1zz11عzz11ع1zWz1z1zz11عWWW1z11عzz11عzz11عz1ؚWWWW1z11عWz1z1z1عWz1ohb-*'-*'ohb𕌉{11ڻڜWڜW1{W1Wڻ{{{11ڻ1{{1ڻڜW{1{{11ڻW{1ڻWڜW{{11ڻ{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڕ1{WڜWW{{11ڻ1{{1{{11{{11{{Wڻ11{{{{11ڻ1Wڻ{{{11{{11ڻ{{11ڻ1{WڜWWڜWڜW{{11ڻ{W1ڜ{{11ڻ{{11ڻ{{11ڻ1{ڜW{{11ڻ1{{1ڻ{W1ڜWڜW{ڻ{Wڻ11{ڻ{ohb-*'-*'ohb𕌉{11ۼ{{11ۼ{X1X{1ۼ{{11ۼۜ1Xۼ{{{11{{11ۼۜ1X{{{11ۼ{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜە::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::fې:1Xۼ{{11ۼ{{{11{{11{{11ۼۜXX{{11X{1ۼ{{11{{11ۼ{{11ۼۜ1Xۼ{{{11ۼ{{11ۼ{{11ۼ{{11ۼ{{11ۼ{{11{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11ۼۜXXۜohb-*'-*'ohb𕌉}22ݾ}}22ݾ}Y2}}22ݾ}}22ݾ}}22ݾݝYY}}22ݾݝ2Y}}2Y}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝݕf:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f::::ېf::ې}22ݾ}2}2}}22}}22ݾYYݝ}}22}}22ݾ}}22}}22ݾ}}22ݾ}}22ݾ}2Y}}22ݾ}}22ݾ}}22ݾ}}22ݾ}}22}}22ݾ}2}2ݾ}}22ݾ}2YݝYYݝohb-*'-*'ohb𕌉55^^5ɨ^^^5555^^ɨ55Ʉ^^^^555^^^55Ʉ55^^5ɨ^5^^5^5^^때ff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶::::ff^5^^55Ʉ55^5^^ɨ55^^555^^5^5^^555^55Ʉ55Ʉ55Ʉ555^^^55ɨ^^55^5^^ohb-*'-*'ohb𕌉555^555^ʄ55^555^^55ʄ55^^55ʄ5^^555ʄ5^쨄55^^55알ff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::ff55ʄ55ʄ55ʄ5555ʄ55ʄ55ʄ55^^55ʄ55ʄ55^^5^^555^5ʨ^^55ʄ5ʄ555ʄ55ohb-*'-*'ohb𕌉555̅5_̅555핌ff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:f:ff5___55̅555___55_555ohb-*'-*'ohb𕌉555Ά555Ά55ff:ې:::ې:ff:::ې:f::ff:::fff::ې:ff:::ې:f::ff::``55Ά5555``55Ά55Ϊ5`Ά5555ohb-*'-*'ohb𕌉𕌉:fېff::::::::66·66``ohb-*'-*'ohb𕌉񕌉:ې:::::ې::::::ې::ohb-*'-*'ohb𕌉򕌉ohb-*'-*'ohb𕌉򕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼ohb-*'-*'ohbohb-*'-*'ohb3~b8Z~ohb-*'-*'ohb[3߮6Y~ohb-*'-*'ohbމa2ޮ6Y}ohb-*'-*'ohbܮ6X|ܮ6X|6X|܉2[ܮX[[[3|a363X|[[6X|܉26|ܮ6X|ܮ6X|ܮXр2܉26|ܮXX3|a363X|[[6X|܉26|ܮ6X|ܮ6X|܉233|a363X|6X|6X|aa❮6X|a26X|6X|ܮ6X|܉23܉2[6X|[[6X|6X|ܮ6X|ܮXX3|a363X|[[܉2[ܮ6X|ܮ6X|܉2[6X|6X6[XXohb-*'-*'ohbڬ6W{ڬ6W{6W{W~1ڇ{2{~16W{`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{ڬ6W{ڬWWڇ`12{~1`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{`Wڇ{`ڇ2໇61{6W{6W{6~~16W{WW6~6{6W{ڬ6W{`Wڇ{W~1ڬ6W{ڬ6W{ڬ6W{6W{ڬ6W{2{~1`ڇ2໇61{6W{ڬW~1ڬ6W{ڬ6W{W~1ڬ6W{W~1ڇ`1ohb-*'-*'ohb٫6Wz٫6Wz6Wz`1ߛ6~Y6Wzه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz٫6Wzه`1ߛYW`1ߛه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz2zWه`1ߛ62zz6Wz6Wz6~W6Wzه21ߺ٫6Wz6Wz٫6Wz2zWه`1ߛ٫6Wz٫6Wz٫6Wz6Wz٫6Wz`1ߛه`1ߛ62zz6Wzه`1ߛ٫6Wz٫6Wz`1ߛ٫6Wz6Wz2zWohb-*'-*'ohb׫6Vy׫6Vy6Vy1Yׇ1V6Vy`6y6Vy׫6Vy`1ޚYV6Vy׫6Vy׫6Vyׇ`1ޚYV`1ޚ`6y6Vy׫6Vy`1ޚYV6Vy׫6Vyׇ`1ޚ`6y6Vy6Vy1}1׫6Vyׇ21޹׫6Vy6Vy׫6Vyׇ`1ޚׇ1Y6Vy׫6Vy׫6Vy6Vy׫6Vy`1ޚ`6y6Vyׇ1Y׫6Vy׫6Vy1Y6Vy6VyYVohb-*'-*'ohb֪VV5Vy5Vy5Vy`}12yV֪5Vy֪5Vy5Vy֪5VyVVֆ51yVY``ݙ֪5Vy֪VVֆ51y2y}1֪5Vy5Vy֪5VyVVֆ51yVY``ݙֆֆ21ݸ֪5Vy5Vy5Vy`֪Y֪5VyVV5}5yVY``ݙֆֆ21ݸ֪5Vy`}1V}1֪5Vy֪5Vy5Vy֪5Vy2y}1֪5Vy5Vy֪5Vy`}1֪V5y5Vy`}15VyV2ݸ51yohb-*'-*'ohbԪ5UwԪ5Uw5UwԆ0_ۗԪU{0ԪUXXXUX5UwԆ0UԪ5U_{w{0Ԫ5UwԆ0U1wUXXUX5UwԆ0UԪ5U_{w{0Ԇ_0ۗXXԪ5Uw5Uw1wU5UwԆ0{05Uw5U_{w{0Ԇ_0ۗԆ0_ۗ5U5XUX5UwU{05Uw1wUXXUXԆ0_ۗԪ5UwԪ5UwԆ0_ۗ5Uw5Uw0{0ohb-*'-*'ohbԩ5Uwԩ5Uw_ԅ1۶ԩ5Uwԩ5Uwԩ5Uwԩ5Uw1wUԩ5Uw5Uw1wUԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwohb-*'-*'ohb8\ɀ8\ɀb38\ɀ8\ɀ8\ɀ8\ɀ3\8\ɀ8\ɀ3\8\ɀ\\8\ɀ8\ɀ8\ɀ8\ɀohb-*'-*'ohb]ӄ484ʂ8]ʂbb84ʂ8]ʂ84ʂ558]ʂ8]ʂ84ʂ5584ʂb584ʂ8]ʂ8]ʂ8]ʂohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'쪦rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿο-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾ͿͿͿͿͿͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾ͿͿͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾ͿͿͿ-*'-*' οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾ͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾ͿͿ-*'-*'aV  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾Ϳ-*'-*'HwX οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿ-*'-*' %XksbPοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾ͿͿͿ᧠xrl[WR[WR\WS\WS\WS\XS\XS\WS\XS\XT\WS\XT\XT\XT\XT\XT\XT\XT\XT\XT\XT\XT\XT\XT\XU]XU]XU]XU^ZW^ZW_[W_[W_[W_[W_[W^ZW]YV]YV_[X]YV\XU\XU\XU]YU_[W_[W_[X_[X_[X_[X_[X&b&S&S&S'T(T (V!)V!*W"+X$-X%-Y%.Z'/Z'0[(0])1])1])1])1^)1])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P+4gYa-*'-*'Cxe #PNդM۩N}ņοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾ͿͿͿ_[W{.<꯵ܯޮ߮୵୵⭵㭷䭷䫹諹諹꫹뫹뫹쫹쫹쫹쫹쫹쫹쭻묺鬺ꬹ鮸殶家䮶᮶ⴺ⮲Α*.O-*'-*'-.fvh#(ۧJRÂQOئKƒ}οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿ̾;̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿͿͿ林ǾƾƾǾƽǾǾƾǾȾȾǾǾȿȿǾǾȿȿȿȿȿՀwr(5r|r}p}p~p~ppppooonnllllllllllmmmmmmmoopppqqqqquɟՙX[-*'-*' 6~je #QĂRӭOMܫO~οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾Ϳ;;̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿqlgŽϿºº»|smûûûûûûûûûû»»»ûûûûûûüûûûû#.}dpdpdqdqcrcrcrbtbvbv`v`x`y`y`z`z`z`z`z`z`z`{`za{a{a{a{a{a{a{a{azayaycwcwcwcudsdsdsererq{!&O-*'-*'-*'-*'AljkVVEV; NP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿ\WSķ÷ĸĸ÷÷ĸqmhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~qlŸƹƹƹŹŹuojƺƺƺƺƺƺzfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻźźźź%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYE]WYhXUhXUhXUWYE]E]E]E]E]E[E[E[EZGYHWHWIWIWIWIW;-*'-*'8HxxxxxvvvvvvvvvvvvwwkihYVfVSkiwwwwwwwwwwwwwwyyyyˮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼̽̽̽̽̽̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽ͿͿͿͿͿͿͿͿͿͿ\XT℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~||||||||||||}nkhYVhYVnk}}}}}}}}}}}}}α*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼̽̽̽̽̽̽̾̾̾̾̾˽˽˽˽˽˽˽˽˽̾ͿͿͿͿͿͿͿͿ\XT䇃fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރ႐ゐ悐灐灐邐pmhYVfVShYVpm邐郐烐惐バㄐℏބ܄ڄ؅ׅԅԅҵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼̽̽̽̽̽̽̽̾̾̾̾˽˽˽˽˽˽˽˽̾̾ͿͿͿͿͿͿ\XTꊇfVSfVSOX琙֐אؐؐܐܐߐ㐚䐛珛鏛돛쎛펛폛fVSfVSurfVSfVS폛퐛퐛됛鐛鑛摜摜䑜⑜ޑݑڑڑټ49Q-*' οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼̽̽̽̽̽̽̽̽̾̾˽˽˽˽˽˽˽˽˽̾̾̾̿ͿͿͿͿͿ\XT쌉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^蘠ؘژܘܘߘ☢䘢䘣阣阣엣헣yvfWUfWUfWUyvyvfWUfWUfWUyv홣홣왤Ꙥ除晤晤䙣♣ޙޙ8=S䠞,*)A/.,*οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ̽̽̽̽̽̽̽̽̾̾˽˽˽˽˽˽˽˽̾̾̾̿̿̿ͿͿͿͿͿ\XTZbꠦܠܠߠࠨ⠨㠨䠩蟪韩럪ퟪퟫ꠫ꡪ顪桪塨䡨⡨ᡨ;@U.,*GECC0.+(οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ̽̽̽̽̽̽̽̽̾˽˽˽˽˽˽̾̾̾̾̿̿̿̾ͿͿͿͿ\XT_f즬ববব⦭䤭䤮褮餭뤮쥯ꥯ襯槮姮䧮⧮?BV롟-*'c`](,οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾Ϳ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ̽̽̽̽̽̽˼˼˽˽˽˽˽˽̾̾̿̿̿̿̾̾ͿͿ\XT`i쬱଱ଲ㬳䬳䬳謴髴髳荒ꬴꬴ謴欴欳嬲?DYc`]|xua@=4$ .+(.,*cbbdmBFZ/-+.+(da^|xuuTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*']ZXmjg|tqsl-2.0/apps/help/tqslapp/stnloc4.bmp0000664000076400007640000253226612231073120020022 0ustar rmurphyrmurphyBM 6(? (r h' S1#L>8/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)?;8LGDe^Zpid|to@'xZNb][/,)1/-󢟝1/-/,)GB@d]YpidghhͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾碟HC@f`\qqq-*'ͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;οοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳݢ-*'NIF```0.,ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳ.,*B=;222ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ҡ-*(-*'ͿͿͿͿ-*'-*'ͿͿͿͿޡohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohb뺺ohb-*'-*'̾̾̾̾ohb랞ohb-*'-*'̾̾̾̾ohb뎎ohb-*'-*'̾̾̾̾ohb|||vvvvvvxxxohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohb돏Ŀohb-*'-*'˼˼˼˼ohbuuuohb-*'-*'˼˼˼˼ohbsssohb-*'-*'˼˼˼˼ohb{{{ohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉::ohbͿ-*'-*'ohb𕌉::ohbͿ̾-*'-*'ohb𕌉::ې::ې::ې::ې:ffې:fff:::::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::fې::f:f:::f:f::fې:fې:ohbͿ̾-*'-*'ohb𕌉f:::ff::ff:ff::::ې:f:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f::::f:ff:۶f::f:ې::ff:۶f:fffېf::ېf::ېohbͿ̾;-*'-*'ohb𕌉ff۶::::ې::::::::ې::ff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶::::::ې::f::::f::::f:۶::::ffff򶳮ohbͿ;;-*'-*'ohb𕌉ff:f۶:::f۶::::::ff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::::ې::f::::f::::f:۶:::fffffohbͿ̾;̽-*'-*'ohb𕌉ffff::ې::ff:::f::ffff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:::۶ff:۶f::ېff۶:fff:۶f:fff::f:ff۶f:ffohbͿ̾̽̽-*'-*'ohb𕌉ff::ې::ې::ېf۶f:ې:::ېff:ې:::ې:ff:::ې:f::ff:::fff::ې:ff:::ې:f::ff:ې::ff:::ff::ff:fff::ې::::ohb̾̽̽˼-*'-*'ohb𕌉:fېff:::::fېff::::::::::222000111222222222222222000222ohb;̽˼˼-*'-*'ohb𕌉:ې::::::ې:::::ې::::::ې::::000333777<<>>000ohb˼˼ʻʻ-*'-*'ohb𕌉000<<۹ݶXBwYR8::f:::::::III^^^dddLLL::ohb˼˼˼˼-*'-*'ohb𕌉mmmT:~aV<񸷷T>z[R8:f:::f::SSSrrrvvvVVVohb˼˼˼˼-*'-*'ohb𕌉Q8z^U=YErUO6::^^^}}}aaaohb˼˼˼˼-*'-*'ohb𕌉mmmQ8~aV?T@vWO6hhh}}}kkkohb˼˼˼˼-*'-*'ohb𕌉Q8~bx\O6vvv~~~xxxohb˼˼˼˼-*'-*'ohb𕌉mmmW۹ݶXBwYR8::f::::fې::ې::f::::fې::fffffې::::::ې:f@@@DDDwwwCCC000222333222IIIKKK@@@ohb˽˽˽̾-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې:::ې:::fې:f::::f:ې:@@@@@@777***000///,,,:::@@@@@@ohb˽˽̾̾-*'-*'ohb𕌉Q8z^U=YErUO6::@@@@@@zzz111%%%...---%%%333zzz@@@@@@ohb˽˽̾̾-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6@@@@@@zzzzzzzzz***!!!---,,,!!!,,,zzzzzzzzz@@@@@@ohb˽˽̾̾-*'-*'ohb𕌉Q8~bx\O6KKKEEEzzzzzzzzzzzzzzz###---,,,%%%zzzzzzzzzzzzzzzMMMQQQohb˽̾̾̾-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::f::::fې::ې::::ې::ې:fffff:::ې:ff:\\\oooWWWWWWgggdddohb̾̾̾̾-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::fffffې::f:ې:::ې􉉉______ohb̾̾̾̾-*'-*'ohb𕌉Q8z^U=YErUO6::ohb̾̾̾̾-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6ohb̾̾̾̾-*'-*'ohb𕌉Q8~bx\O6ohb̾̾̾̾-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8ff::::f::::::f::::fېf::::fېfffffې::ې:fې:ohbοοοο-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::ېff::::::::fې:f:::ې:ې:ohbοοοο-*'-*'ohb𕌉Q8z^U=YErUO6::::ohbοοοο-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6ڻ컻ohbοοοο-*'-*'ohb𕌉Q8~bx\O6Եohbοοοο-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::f::::fې::ې::f::::fېf::::fېfffffې::ې:fې:è::ېfff:::ې::fې:fff:::::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::ohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::::fې:f:::ې:ې:ί:::fې:ې:ې::ېf::::ې:f:::ېf::::ې:ېf:::ff:۶f::::::ff:۶f:f:::ې:ېf:::ff:۶f::::ohb-*'-*'ohb𕌉Q8z^U=YErUO6::й::::::ې::ې::::ې::ff::ې::ې::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::ې::f:۶::::ohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6::::::ې::ې::::ff::::ې::ې::ې::f:۶::::::::f:۶::::ې::ې::ې::f:۶::::ohb-*'-*'ohb𕌉Q8~bx\O6::ff::ې::ې::ffff::ff::ې::ff:۶f:ff:::ff:۶f:fff::ې::ff:۶f:ff:ohb-*'-*'ohb𕌉mmmmmmW۹ݶXBwYR8::f::::fې::ې::::::::ې::f::::fېf::::fېfffffې::ې:fې:ohb-*'-*'ohb𕌉mmmmmmT:~aV<񸷷T>z[R8::::::ې::::::ې::ې::ې::::::fې:f:::ې:ې:ohb-*'-*'ohb𕌉Q8z^U=YErUO6::::ې::ohb-*'-*'ohb𕌉mmmmmmQ8~aV?T@vWO6ohb-*'-*'ohb𕌉Q8~bx\O6򶳮ohb-*'-*'ohb𕌉mmmmmmW=????????????????????????????????????????????????????????????????????????[>Uohb-*'-*'ohb𕌉2Tf::::fېf::::fېfffffې::ې:fې:<>!!!>۹ݶXBwYR8::::::::z[R8::::::::[MF<:f::::fff:::fې:::fff:::::::ې::۶:fېf:::ېfې:fff:::fff:::ې:f:::::f:f:ffff:::fff:::ې:f::::ohb-*'-*'ohb𕌉cKcKcKcKcK푑mmmmmmmmm2Tff:f:::f۶::::]HG`DG@^HH-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞+*)A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*GECC0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'b`](,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝b`]{xua@=4$ .+(.,*cbadmBFZ/-+.+(c`^{xuuTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'\ZWmjg{tqsl-2.0/apps/help/tqslapp/stnloc3.bmp0000664000076400007640000177532612231073120020026 0ustar rmurphyrmurphyBM6(~wr_ZVQMI/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)B>;OJGib^uniyt~wra[X/,)1/-񢟝1/-/,)JFChb^uni|wa[XοοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺǹȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοο㢟KFDjd`jd`-*'οοοοͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ͿͿ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοآ-*'QMI[UR0.,οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾ͿͿ;̽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοο0.,D@>/,*οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοˠ/,*-*'-*'-*'⥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<YgUcUcUeUfUfTgTgTgTiSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiTgTgTgUfUfUeUcUcYh>-*'-*' L ֤L פ LפV}Y} KWۧIWŀY׫K ŀWŀ ëK } ڧI ۧIW ٦ISzU֣G yRy ԢF }䴉I ʘ;IWIWIWIWHWHWGYEZE[E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E[E[EZGYHWHWIWIWIWIX;-*'-*'W|K YQKLN֤ QKN} }WWL֤Y|  ˆ UJ פHSIU~ y { w z 9=M=M=M=N=O=O=O=O=O=O=Q=QNaming a Station Location

Naming a Station Location

In the Add Station Location dialog, specify a Station Location Name.
1.to make this name meaningful, it is recommended that it incorporate both your callsign and town name, or callsign and location name (see Additional Information below)
2.click the Finish button
tqsl-2.0/apps/help/tqslapp/stnloc2.bmp0000664000076400007640000177532612231073120020025 0ustar rmurphyrmurphyBM6(~wr_ZVQMI/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)B>;OJGib^uniyt~wra[X/,)1/-񢟝1/-/,)JFChb^uni|wa[XοοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺǹȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοο㢟KFDjd`jd`-*'οοοοͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ͿͿ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοآ-*'QMI[UR0.,οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾ͿͿ;̽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοο0.,D@>/,*οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοˠ/,*-*'-*'-*'⥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<YgUcUcUeUfUfTgTgTgTiSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiTgTgTgUfUfUeUcUcYh>-*'-*' L ֤L פ LפV}Y} KWۧIWŀY׫K ŀWŀ ëK } ڧI ۧIW ٦ISzU֣G yRy ԢF }䴉I ʘ;IWIWIWIWHWHWGYEZE[E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E[E[EZGYHWHWIWIWIWIX;-*'-*'W|K YQKLN֤ QKN} }WWL֤Y|  ˆ UJ פHSIU~ y { w z 9=M=M=M=N=O=O=O=O=O=O=Q=QSpecifying a Station Location

Specifying a Station Location

1.select your callsign
2.specify the Grid Square in which your station is located (this is particularly important if you operate on VHF or UHF frequencies or via Satellites, as it provides Grid Square credit to your QSO partners pursuing VUCC awards)
3.specify the ITU Zone in which your station is located
4.specify the CQ Zone in which your station is located
5.if your station is located on an island, specify its IOTA Reference Number; use a two-character continent abbreviation followed by a dash and a 3 digit number, e.g. OC-005. If you do not know your IOTA designation, you can find this information at http://www.rsgbiota.org
6.click the Next button
 Note: if the DXCC Entity, ITU Zone, and CQ Zone are mutually inconsistent, an Invalid zone selections for DXCC entity message will be displayed, and the Next button will be disabled; you must select consistent ITU and CQ zones before proceeding.
7.Depending upon your callsign's DXCC entity, you may be prompted to specify your Province, Oblast, State, and/or County.
tqsl-2.0/apps/help/tqslapp/stnloc1.bmp0000664000076400007640000177532612231073120020024 0ustar rmurphyrmurphyBM6(~wr_ZVQMI/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)B>;OJGib^uniyt~wra[X/,)1/-񢟝1/-/,)JFChb^uni|wa[XοοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺǹȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοο㢟KFDjd`jd`-*'οοοοͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ͿͿ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοآ-*'QMI[UR0.,οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾ͿͿ;̽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοο0.,D@>/,*οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ̾̽̽˼˼˼ʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿͿͿͿͿͿοοοοοοοοοˠ/,*-*'-*'-*'⥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𸵰uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb𹶱䏏䏏ohb-*'-*'ohb𶳮򶳮uuuuuuuuuuuuohb-*'-*'ohb𵲭ppppppppppppohb-*'-*'ohb𵲭􃃃ppppppppppppohb-*'-*'ohb𵲭ppppppppppppohb-*'-*'ohb𵲭􃃗Ѓ􃃗􃃪⾗pppyy11ָVy1ָy1y1ָV֙VVV֙Vy1ָV1y֙pppppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppohb-*'-*'ohb𵲭􃗾⾗⾗⃗Ъ⃪⾗pppzz11عؚWz1عWؚWؚWWؚ1WعzzW1ؚؚWz1عpppppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppohb-*'-*'ohb𵲭ЗЗ⾗Ъppp{{11ڻ1{{{W{11{{11ڻW{1{{11ڻ{1Wppppppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb-*'-*'ohb𵲭􃃪Ъ􃃗⾗􃃗ppp{{11ۼ{{11{{11{1Xۜ1{{1{{11ۼXXۜpppppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppohb-*'-*'ohb𵲭З􃃗Ъ􃗾Ъ⪃ppp}}22ݾYݝY}}22ݾYYݝ}}22ݾ}Y2ݝ22}ݾ}}}22ݾ}2Ypppppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppohb-*'-*'ohb𵲭􃗾Ъ⃃􃃪ppp55^ɨ^55Ʉ55Ʉ^Ʉ555Ʉ5Ʉ5^5pppppp55Ʉ55Ʉ55^^^^55Ʉ55pppohb-*'-*'ohb𵲭ppp^5555^ʄ5555^5pppppp5^^^55pppohb-*'-*'ohb𵲭􃃗Ъppp5̅55555pppppp__55pppohb-*'-*'ohb𵲭ppppppppp55pppohb-*'-*'ohb𵲭ppppppppppppohb-*'-*'ohb𵲭ppppppppppppohb-*'-*'ohb𵲭ppppppppppppohb-*'-*'ohb𶳮򶳮uuuuuuuuuuuuohb-*'-*'ohb𸵱葑葑ohb-*'-*'ohb𾻷𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𠠠ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppvv00Ҵpppohb-*'-*'ohbpppww00Զpppohb-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙pppohb-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عpppohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{pppohb-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{pppohb-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝpppohb-*'-*'ohbppp5555Ʉ55Ʉ55^555^^pppohb-*'-*'ohbppp555555pppohb-*'-*'ohbppp555555pppohb-*'-*'ohbppp55pppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb6`6`66666`·6`Ϋ66·ohb-*'-*'ohb666·6`·6666``666·66``ohb-*'-*'ohb66Ϋ6`·66666·666·6666ohb-*'-*'ohb66·66``6666Ϋ6`·66·66``ohb-*'-*'ohb66·66``6666·`666·66``ohb-*'-*'ohb66Ϋ6`·66666·6`·666·6666ohb-*'-*'ohb666·6`·666`6666`·66·666`ohb-*'-*'ohb6`6·66·6666`Ϋ6`ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppv0T0v0Ҵvpppohb-*'-*'ohbpppww00ԶԶ00wԶwpppohb-*'-*'ohbpppyy11ָyy11ָVy1ָy1V֙yy11ָyy11ָy1y1ָ11yָypppohb-*'-*'ohbpppzz11عzz11عؚWz1عWؚW1zWzz11عzz11عWؚWع11zعzpppohb-*'-*'ohb`6·ppp{{11ڻ{{11ڻ1{{{W{11{{11ڻ{W1{{11ڻ{{11{{11ڻڻ11{ڻ{pppohb-*'-*'ohb66ppp{{11ۼ{{11ۼ{{11{{11{{11ۼ{X1{{11ۼ{{11{1Xۜ11{ۼ{pppohb-*'-*'ohb6`6```6`6666·66ppp}}22ݾ}}22ݾYݝY}}22ݾYݝY2}Y}2ݝYY}2ݾYYݝ}}22ݾ22}ݾ}pppohb-*'-*'ohb6```6·6```·6``6Ϋ`6666``ppp55Ʉ55^ɨ^55Ʉ5^먄55^^55Ʉ55Ʉpppohb-*'-*'ohb6`·6`·666`·66`6Ϋ6666·66ppp55ʄ^5555^ʄ5555ʄpppohb-*'-*'ohb6666```666`6Ϋ66666`ppp55̅5̅55555̅pppohb-*'-*'ohb`666```·6``6Ϋ`6``6``66ppp5`55Άpppohb-*'-*'ohb66·6`·666`·6`66``66·ppppppohb-*'-*'ohb6```6·6`·6`6ppppppohb-*'-*'ohb``6·666·ppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohbwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppv0T0v0Ҵvpppohb-*'-*'ohbpppww00ԶԶ00wԶwpppohb-*'-*'ohbpppyy11ָyy11ָVy1ָy1V֙yy11ָyy11ָy1y1ָ11yָypppohb-*'-*'ohbpppzz11عzz11عؚWz1عWؚW1zWzz11عzz11عWؚWع11zعzpppohb-*'-*'ohbppp{{11ڻ{{11ڻ1{{{W{11{{11ڻ{W1{{11ڻ{{11{{11ڻڻ11{ڻ{pppohb-*'-*'ohbppp{{11ۼ{{11ۼ{{11{{11{{11ۼ{X1{{11ۼ{{11{1Xۜ11{ۼ{pppohb-*'-*'ohb6`6666``6`6666·66ppp}}22ݾ}}22ݾYݝY}}22ݾYݝY2}Y}2ݝYY}2ݾYYݝ}}22ݾ22}ݾ}pppohb-*'-*'ohb66666`·6Ϋ``·6``6Ϋ`6666``ppp55Ʉ55^ɨ^55Ʉ5^먄55^^55Ʉ55Ʉpppohb-*'-*'ohb666666666`·66`6Ϋ6666·66ppp55ʄ^5555^ʄ5555ʄpppohb-*'-*'ohb66666666`666`6Ϋ66666`ppp55̅5̅55555̅pppohb-*'-*'ohb66666666`·6``6Ϋ`6``6``66ppp5`55Άpppohb-*'-*'ohb666666666`·6`66``66·ppppppohb-*'-*'ohb66666666`6ppppppohb-*'-*'ohb6666``6666666·ppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohbwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohb66ϵɤohb-*'-*'ohb66ϵɤohb-*'-*'ohb6·66666```66666·666``666```666·6666ϵɤohb-*'-*'ohb6·666·66666`·6·6`6666`66`66·6·666·6·66``ϵɤohb-*'-*'ohb6`·66·6666·6666````66·666666·66·6666ϵɤohb-*'-*'ohb6666·6666·6666````66·6666·66·666`ϵɤohb-*'-*'ohb666`66``66``6`66·6666``6```66ϵɤohb-*'-*'ohb6`·66``Ϋ66·66```6·666666·66``66·ϵɤohb-*'-*'ohb6·6`666`·``ϵɤohb-*'-*'ohb6·666666·6ϵɤohb-*'-*'ohb66ϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbͶ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\Ͷohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𸵰ohb-*'-*'ohb𹶱ohb-*'-*'ohb𶳮򶳮ohb-*'-*'ohb𵲭ohb-*'-*'ohb𵲭ohb-*'-*'ohb𵲭ohb-*'-*'ohb𵲭mmmmmmmmm߳mmmmmmmmmmmmmmmmmmmmmɳmmmmmmmmmm߳mmmmmmmmm߳m߳mmmmmmmmmmmmm߳mmmmmmmmm߳mmmmmmmmmɝmɳmmmmmmmmmmmmmɳ߅mmɳmmmmmmmmmmmmmmmmɝmm߳ohb-*'-*'ohb𵲭m߳ɝmmmm߳mmɝɝmɝmɝ߳mmm߳mɝm߳߳mmߝmmmɝmohb-*'-*'ohb``𵲭߳߳߳mmmmmmmmmmmmm߳mm߳߳mmmmmmmmmmmm߳߳mɳ߳߳mm߳mmmmmmmmmmmm߳ohb-*'-*'ohb`6𵲭߳߳߳߳mmmmɝmm߳mmmɝmmɳm߳mmmmɝ߳mmmmmmmmm߳m߳ohb-*'-*'ohb66·`6`66`6`666666```666`·666·𵲭߳mɝ߳mmmmmmmmmmmm߳mmmmmɝm􅅳߳mmmmmmmmmmmmmmmmmɝmmmmmmmmmmmmmmm􅅳߳m߳ߝmɳ߳mmmmmmmmmmmm߳m߳m􅅳߳mohb-*'-*'ohb66``6`6`6```6```666666·`666·`66·6𵲭߳ɝm߳m߳m߳mm߳߳߳m߳߳mɳ߳m􅅳߳߳m߳ohb-*'-*'ohb6666Ϋ```6Ϋ6`·6`·666666·66·66·66````𵲭ߝ߳߳mmɝm߳ɝ߳m߳ɝ߳mmm߳߳߳􅅅߳mߝmm߳ohb-*'-*'ohb66```6·6666666666·66·66·66````𵲭mm߳mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmɳmmmmmmmmmmmɝmmmmmmmmɳmmmmmmmmmmmmmmmm߳mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm߳mmmmmmmm߳mmmmmmmmm߳mmmmmmmmmmmmmmmmmɝmmɳmmmmmmmmmmmmmmɳmmmmmmmmmm߳mmmmmmmmmmmmmmmmɝmmmohb-*'-*'ohb66``66·`6`6666``6·66·66·66````𵲭ohb-*'-*'ohb6666Ϋ6`6666·66·6666``6``666666`6`·𵲭ohb-*'-*'ohb666``·66`6```6```666666𵲭ohb-*'-*'ohb6`````````66·66·66·66𵲭ohb-*'-*'ohb𶳮򶳮ohb-*'-*'ohb𸵱ohb-*'-*'ohb𾻷ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𸵰ohb-*'-*'ohb𹶱ohb-*'-*'ohb𶳮򶳮ohb-*'-*'ohb𵲭ohb-*'-*'ohb𵲭mmmmmm߳ohb-*'-*'ohb𵲭ohb-*'-*'ohb𵲭mɳm߳mmmmmm߳mmmmmmmmmɝohb-*'-*'ohb𵲭mɝmmɝmm߳m߳mmmɝohb-*'-*'ohb``𵲭mmmmmmmmmmmm߳mmmmmmmmmmmm߳m􅅳߳m߳ohb-*'-*'ohb``𵲭m߳m߳mmmohb-*'-*'ohb6````666·66·6666·66`6·6666𵲭􅅳߳m􅅳߳mmmmmmmmmmmmɝmɅɝmohb-*'-*'ohb6```Ϋ666·6·66·66`666·666`·66·6666𵲭߳m߳߳m߳߳ߝmm߳ohb-*'-*'ohb6`·66·66·66·66``Ϋ66`·666·6666𵲭߳߳mmmɝm߳߳mmm߳ohb-*'-*'ohb6666·66·66``66·6666·6666𵲭mmmmmmmmmm߳mm߳mmmmmmmmm߳ohb-*'-*'ohb`6``66·66``66``666``6𵲭ohb-*'-*'ohb66·66·66·66``66·66·66``𵲭ohb-*'-*'ohb6```66·666`·``𵲭ohb-*'-*'ohb``66·666·666𵲭ohb-*'-*'ohb66·66𶳮򶳮ohb-*'-*'ohb𸵱ohb-*'-*'ohb𾻷ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'騥rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'Ϳ̿̿̿ͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾Ϳ-*'-*'Ϳ̿̿ͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾ͿͿ-*'-*'ͿͿͿͿͿͿͿͿͿ̾̾̾̾̾ͿͿͿͿͿ-*'-*'ͿͿͿͿͿͿͿͿͿ̾̾ͿͿͿͿͿͿͿ-*'-*'ͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿοοο-*'-*'ͿͿͿͿͿͿͿͿοοοοοο-*'-*'ͿͿͿͿͿͿοοοοοοοο-*'-*'ͿͿοοοοοοο-*'-*'οοοοοX`+4f (P (P")Q#*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])2])2])2[)2[)2Z)1Y(0X'/W%.V%.U$,T#+S")Q (P (P+4gX`-*'-*' ~ ŀ JLQפY }UۨI ŀ | ŀ  ŀ |UJTإH y  x { u rοοο(-Mx|͵᮶᮶᮶家殸欹鬺ꬺꬺ쬺쬻ꬻꬺ鮹殶殶家⮶ⴺ⮲y}).N-*'-*' U}YLפ Lפ }W}QW֤U}WۨIY֫K ŀY֫K ŀWK ëK  ŀ W ~VפH yUբG xRԢF ӡF u sX[uqqqqqpppoommmmmmmmmmmmmmmmmoopppqqqqquɟՄX[-*'-*' ŀLU֤Y֪K }WڧIWڧIL ֤ ŀYժK LUգLUգ   û I zUբG xVͦHVͥH v s!&Oq{ererdsdsdscucwcwcwayayaza{a{a{a{a{a{a{a{a{a|a|a|a|a|a|a|a|a{azazcxcwcwcudsdsdsererq{!&O-*'-*' ŀ ŀ ŀLVפY׫K }YׂWۨJYŀY֫K ŀLU֤LU֤ ŀ ŀ ý VzUգG yWϦIVΦH w t>YgUcUcUeUfUfTgTgTgTiSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiTgTgTgUfUfUeUcUcYh>-*'-*' L ֤L פ LפV}Y} KWۧIWŀY׫K ŀWŀ ëK } ڧI ۧIW ٦ISzU֣G yRy ԢF }䴉I ʘ;IWIWIWIWHWHWGYEZE[E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E[E[EZGYHWHWIWIWIWIX;-*'-*'W|K YQKLN֤ QKN} }WWL֤Y|  ˆ UJ פHSIU~ y { w z 9=M=M=M=N=O=O=O=O=O=O=Q=QDefining or Modifying a Station Location

Defining or Modifying a Station Location

A Station Location specifies both a Callsign Certificate and an operating location.

Defining a Station Location
1.In TQSL, select the Station Locations tab and click the Create a new Station Location button; the Add Station Location dialog will appear.
2.In the Add Station Location dialog, specify your callsign, grid square, ITU zone, CQ zone, and IOTA Reference Number.
  
   2.aselect your callsign
   2.bspecify the Grid Square in which your station is located (this is particularly important if you operate on VHF or UHF frequencies or via Satellites, as it provides Grid Square credit to your QSO partners pursuing VUCC awards)
   2.cspecify the ITU Zone in which your station is located
   2.dspecify the CQ Zone in which your station is located
   2.eif your station is located on an island, specify its IOTA Reference Number; use a two-character continent abbreviation followed by a dash and a 3 digit number, e.g. OC-005. If you do not know your IOTA designation, you can find this information at http://www.rsgbiota.org
   2.fclick the Next button
    Note: if the DXCC Entity, ITU Zone, and CQ Zone are mutually inconsistent, an Invalid zone selections for DXCC entity message will be displayed, and the Next button will be disabled; you must select consistent ITU and CQ zones before proceeding.

3.Depending upon your callsign's DXCC entity, the Add Station Location dialog may prompt you to specify your Province, Oblast, State, and/or County. The example below shows this for a station in the United States:
  
   3.ain the Add Station Location dialog, select your US State (this is particularly important as it provides US State credit to your QSO partners pursuing WAS awards)
   3.bselect your US County
   3.cclick the Next button

4.In the Add Station Location dialog, specify a Station Location Name.
  
   4.ato make this name meaningful, it is recommended that it incorporate both your callsign and town name, or callsign and location name (see Additional Information below)
   4.bclick the Finish button
5.To protect your new Station Location, direct TQSL to create a Backup File.
6.If you have TQSL installed on multiple computers, then perform the following steps on each such computer:
   6.aObtain a copy of the Backup File you created in step 5 (via your home network, or by using a thumb drive)
   6.bStart TQSL, and direct it to Restore from the backup file you obtained in step 6.a; this will update all Callsign Certificates, Station Locations, and Preferences on this computer to match those on the computer you used to define the Station Location in step 1.

Modifying a Station Location
1.In TQSL, select the Station Locations tab, which lists your Station Locations:
  
2.On the Stations Locations tab, click on the name of the Station Location you wish to modify:
  
  and then click the Edit Station Location button; the Edit Station Location dialog will appear.
3.In the Edit Station Location dialog, select a different callsign, or modify the grid square, ITU zone, CQ zone, or IOTA tag as desired.
4.Click the Next button. Note: if the DXCC Entity, ITU Zone, and CQ Zone are mutually inconsistent, an Invalid zone selections for DXCC entity message will be displayed, and the Next button will be disabled; you must select consistent ITU and CQ zones before proceeding.
5.If your station is in a DXCC entity for which a Province, Oblast, State, and/or County can be selected, modify your selection(s) as desired.
6.Click the Next button.
7.Modify the Station Location Name as desired.
8.Click the Finish button.
9.To protect your modified Station Location, direct TQSL to create a Backup File.
10.If you have TQSL installed on multiple computers, then perform the following steps on each such computer:
   10.aObtain a copy of the Backup File you created in step 9 (via your home network, or by using a thumb drive)
   10.bStart TQSL, and direct it to Restore from the backup file you obtained in step 10.a; this will update all Callsign Certificates, Station Locations, and Preferences on this computer to match those on the computer you used to define the Station Location in step 1.

 

Additional Information
  • If you always operate with the same callsign and from one location, use a name that combines them both, e.g. K9UW(Amherst) or AA5AU-Louisiana. If you operate with more than one callsign or from more than one location, see this example.
  • You can move a Station Location from one computer to another
tqsl-2.0/apps/help/tqslapp/stnloc.bmp0000664000076400007640000143765612231073120017744 0ustar rmurphyrmurphyBM?6(x?```RRR/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)BBBOOOiiivvvbbb/,)1/-󢟝1/-/,)KKKiiivvvbbbοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ碟KKKkkkkkk-*'οοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾ޢ-*'RRR0.,οοοοοοοͿͿͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ.,*EEE///οοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳӡ///-*'-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbүohb-*'-*'ohb𯯯㯯𸵰ohb-*'-*'ohb𯯯𹶱ohb-*'-*'ohb𯯯𶳮򶳮ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭⃃Ъ􃃪⾗ohb-*'-*'ohb𯯯𵲭⾗􃃪⾗⃪⾗ohb-*'-*'ohb𯯯𵲭⾗Ъohb-*'-*'ohb𯯯𵲭Ѓohb-*'-*'ohb𯯯𵲭о⪃ohb-*'-*'ohb𯯯𵲭⾗ohb-*'-*'ohb𯯯𵲭⾗􃃪⾗ohb-*'-*'ohb𯯯𵲭⃃⾗ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯𵲭ohb-*'-*'ohb𯯯㯯𶳮򶳮ohb-*'-*'ohbү𸵱ohb-*'-*'ohb𾻷ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohb66·66·66·66·6``·666```66666·`·6```666```666·6`66666`6`6````666```666·6`6666ppppppohb-*'-*'ohb`666``66``6``6``6`·6·6`666·`6666·6·`666``6Ϋ`666666``6Ϋ`6`666·6·`666``6Ϋ`6666ppppppohb-*'-*'ohb``Ϋ6666·666666·666666``66·66·66·66·66·66`6Ϋ66666666`6Ϋ6666·66·66·66·66`6Ϋ6666ppppppohb-*'-*'ohb``6`Ϋ666`Ϋ6666·6`Ϋ6666``6666·66·66·66`6Ϋ66666666`6Ϋ6666·66·66·66`6Ϋ6666ppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppohb-*'-*'ohb````66·66``666`66Ϋ``66``66``66``66·66``6Ϋ`6``666``6Ϋ`6```66·66``6Ϋ`6``6ppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppohb-*'-*'ohb``66·66·66·`Ϋ`6·666·66``6·666·6``666·6`66``666```66·6``666·6`66``pppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb-*'-*'ohb6`·``6666666`·``66666666ppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppohb-*'-*'ohb6·66666666·66666·666666·66ppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppohb-*'-*'ohb6666ppp55Ʉ55Ʉ55^^^^55Ʉ55pppohb-*'-*'ohbppp5^^^55pppohb-*'-*'ohbppp__55pppohb-*'-*'ohbppp55pppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppvv00Ҵpppohb-*'-*'ohb𐇂pppww00Զpppohb-*'-*'ohb𐇂pppyy11ָyy11ָy1y1yy11y1V֙pppohb-*'-*'ohb𐇂pppzz11عzz11عWؚWzz11zz11عWz1عpppohb-*'-*'ohb𐇂ppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{pppohb-*'-*'ohb𐇂ppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{pppohb-*'-*'ohb𐇂ppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝpppohb-*'-*'ohb𐇂ppp5555Ʉ55Ʉ55^555^^pppohb-*'-*'ohb𐇂꿿ꪪppp555555pppohb-*'-*'ohb𐇂ꧧꗗppp555555pppohb-*'-*'ohb𐇂꒒ꂂppp55pppohb-*'-*'ohb𐇂{{{xxxppppppohb-*'-*'ohb𐇂sssvvvppppppohb-*'-*'ohb𐇂uuuvvvppppppohb-*'-*'ohb𐇂ꏏ|||uuuuuuohb-*'-*'ohb𐇂葑ohb-*'-*'ohb𐇂𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂뺺ohb-*'-*'ohb𐇂랞ohb-*'-*'ohb𐇂뎎ohb-*'-*'ohb𐇂|||vvvvvvxxxohbͿ-*'-*'ohb𐇂ohbο-*'-*'ohb𐇂ohbͿο-*'-*'ohb𐇂ohbͿͿ;-*'-*'ohb𐇂ohbͿ;;-*'-*'ohb𐇂ohbο;̽-*'-*'ohb𐇂ohbͿ;;̽-*'-*'ohb𐇂ohbͿ;;̽-*'-*'ohb𐇂ohb;;̽̽-*'-*'ohb𐇂ohb;̽̽ʻ-*'-*'ohb𐇂ohb;̽˼ʻ-*'-*'ohb𐇂ohb;˼˼ʻ-*'-*'ohb𐇂ohb̽˼ʻʻ-*'-*'ohb𐇂ohb˼ʻʻʻ-*'-*'ohb𐇂ohb˼ʻʻ˼-*'-*'ohb𐇂ohb˼ʻ˼˼-*'-*'ohb𐇂ohbʻ˼˼˽-*'-*'ohb𐇂ohbʻ˼˽˽-*'-*'ohb𐇂ohb˼˽˽˼-*'-*'ohb𐇂ohb˼˽˼˼-*'-*'ohb𐇂ohb˽˼˼̽-*'-*'ohb𐇂ohb˽˼˼̽-*'-*'ohb𐇂ohb˼˼̽̽-*'-*'ohb𐇂ohb˼̽̽˽-*'-*'ohb𐇂ohb̽̽˽˽-*'-*'ohb𐇂ohb̽̽˽̾-*'-*'ohb𐇂ohb̽˽̾;-*'-*'ohb𐇂ohb˽˽;̽-*'-*'ohb𐇂ohb˽̾̽̾-*'-*'ohb𐇂ohb̾;̾Ϳ-*'-*'ohb𐇂ohb;̾ͿͿ-*'-*'ohb𐇂ohb̽̾Ϳο-*'-*'ohb𐇂ohb̾ͿͿ-*'-*'ohb𐇂ohbͿ̾-*'-*'ohb𐇂ohb̾Ϳ-*'-*'ohb𐇂ohbͿ-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂fff:ېffohb-*'-*'ohb𐇂ff::f:ohb-*'-*'ohb𐇂ff:::ې::::f:::fې::ې:::f::::ې::::ې::::ې::::ېfې::f::fff:::ې:f::::ohb-*'-*'ohb𐇂ff::ې:::ff::ff:fې:f::::ې:ff::::ې::::ې::::ff:ې:ېf::ې::f:ff:::ې::f::::ohb-*'-*'ohb𐇂:ff:::::ې:ې::ې:ff::ې:::fې::::::ې::::ې::::ې::ffffff::ff۶::::ې::ې::::::ohb-*'-*'ohb𐇂fff:::ff::۶:fې::۶:fېfff:::::ff:ې:::ې::ې::::ې:::::fffffff:::::f::ې::::::ohb-*'-*'ohb𐇂ffff:ې:::ff::ېf:::ېf:۶fff:::f::ff:::ې:ې:::ff::ff:ff::fffff:ff::ېff::ff:f:ff:ohb-*'-*'ohb𐇂:ې:fې::ې:::ff:ې:fې::ې:fې::fې::f::fې::::ff۶::ې::ff::ff::ې:f:fې::::ff::ې::ېff::ffohb-*'-*'ohb𐇂::ې::fff::::fېf::::fېf::::fېfffffې::ې:fې:::f:::::::ohb-*'-*'ohb𐇂::::ېf::ې:::::fې:f:::ې:ې::f:::f::ohb-*'-*'ohb𐇂::::ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂𸵰ohb-*'-*'ohb𐇂𹶱ohb-*'-*'ohb𐇂::f:::ې:::f:ې::f:ffې::::f::fې::ffې:::f:::ې:::f:ې:𶳮򶳮ohb-*'-*'ohb𐇂::f:fې:f:::::f::ې:::::ff:۶fېf::ې:ff:ې::ېf:ff:۶fېf::ې::f:fې:f:::::f::ې:::𵲭ohb-*'-*'ohb𐇂:::ېf::ff::ې::::ff:fې::::::f:ff:ې:::ې::ې::f:ff:::ېf::ff::ې::::ff:fې::𵲭ohb-*'-*'ohb𐇂::ې::ې::fff:::::::ې:::::ې:::::f:ff::۶:fې::ې::ې::f:ff:ff:::ې::ې::fff:::::::ې::::𵲭ohb-*'-*'ohb𐇂::ff::fff:::f::ې::::ff:۶ff:ff::ېf:ې::ې::۶ff:۶ff:ff::ff::fff:::f::ې::𵲭􃃗􃃗⾗􃃗Ѓ⾗􃃗ohb-*'-*'ohb𐇂::f۶f:::fې::f:::ff:fې:::f:::ې:fې::::ې::f::::f۶f:::fې::f:::ff:fې𵲭􃃪Ъ􃃪Ъ⃃Ъ􃃪Ъohb-*'-*'ohb𐇂f::::fې::fffffې::::::ې:f::f::::fې::ې::f::::fې::fffffې::::::ې:f𵲭⾗⾗ohb-*'-*'ohb𐇂:ې:::fې:f::::f:ې:::::::ې:::ې:::fې:f::::f:ې:𵲭Ѓо⃃о􃃗ohb-*'-*'ohb𐇂::𵲭Ъ⾗⪃ohb-*'-*'ohb𐇂𵲭􃃗⾾􃃗􃗾⾗􃃗ohb-*'-*'ohb𐇂𵲭􃃗Ъohb-*'-*'ohb𐇂𵲭􃃗Ъohb-*'-*'ohb𐇂𵲭ohb-*'-*'ohb𐇂::fې::f::ې:f:ې:ff:f:ffې::::f::fې::ffې:::fې::f::ې:f:ې:ff𵲭ohb-*'-*'ohb𐇂:::ې::ffffې:f::::ې:::fې:::ff:۶fېf::ې:ff:ې::ېf:ff:۶fېf::ې:::ې::ffffې:f::::ې:::fې:𵲭ohb-*'-*'ohb𐇂:::۶f:fېff::ې::۶:fې::۶:fې::::f:ff:ې:::ې::ې::f:ff:::۶f:fېff::ې::۶:fې::۶:fې𵲭ohb-*'-*'ohb𐇂::f:::fff:::ې::::f::ې:::::f:ff::۶:fې::ې::ې::f:ff:ff:::f:::fff:::ې::::f:𶳮򶳮ohb-*'-*'ohb𐇂:::::ېf:ff::ې::fې:::ff:۶ff:ff::ېf:ې::ې::۶ff:۶ff:ff:::::ېf:ff::ې::fې:𸵱ohb-*'-*'ohb𐇂::::ې::ې:fې::۶:fې:fې:::f:::ې:fې::::ې::f::::::ې::ې:fې::۶:fې:fې𾻷ohb-*'-*'ohb𐇂::ې::ې:fffff:::ې:ff:::f::::fې::ې::::ې::ې:fffff:::ې:ff:ohb-*'-*'ohb𐇂::fffffې::f:ې:::ې::::::ې::::fffffې::f:ې:::ېohb-*'-*'ohb𐇂::ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂f:ېfff:ېohb-*'-*'ohb𐇂::f:::ohb-*'-*'ohb𐇂:::f:::fې::ې:::f:ې::ffff:::::ې::fff:::ې::::fff::::::f:::fې::ې:::fohb-*'-*'ohb𐇂:ff::ff:fې:f::::ې:ff:f:::ېf:::ې::::ې::ې:::ې:::ې:ې:::::fې:ې::ff::ff:fې:f::::ې:ff𸵰ohb-*'-*'ohb𐇂:ې::ې:ff::ې:::fې::fffff۶ې:fې::ې::ffff::::ې::ې::::ې:::::ې::ې:ff::ې:::fې::𹶱ohb-*'-*'ohb𐇂::۶:fې::۶:fېfff:::::ff:ې:f:f:f:f:::۶ffff::ې::ې::::ې:::::ې:::۶:fې::۶:fېfff:::::ff𶳮򶳮ohb-*'-*'ohb𐇂::ېf:::ېf:۶fff:::f::ff:ې:fې:fffffffff::ff:ff:ff::::ېf:::ېf:۶fff:::f::ff𵲭ohb-*'-*'ohb𐇂:ې:fې::ې:fې::fې::f::fې:::fېfffې:fې:::ې:f:f::::ې::ff:::ې:fې::ې:fې::fې::f::fې::𵲭ohb-*'-*'ohb𐇂f::::fېf::::fېfffffې::ې:fې:ff::::f::::::f::::fېf::::fېfffffې::ې:fې:𵲭ohb-*'-*'ohb𐇂::::fې:f:::ې:ې:::::ېff::::::::fې:f:::ې:ې:𵲭􃃗⾪􃃃⾗Ѓ⾗ohb-*'-*'ohb𐇂::::𵲭⾗⾗ohb-*'-*'ohb𐇂𵲭⾗ohb-*'-*'ohb𐇂𵲭⾗ohb-*'-*'ohb𐇂f:ېf:ې𵲭􃃗⃃Ъ⾗ohb-*'-*'ohb𐇂::::𵲭􃃗⾗⃗⾗ohb-*'-*'ohb𐇂:::f:::fې::ې:::f:f:ffې::::f::fې::ffې::::f:::fې::ې:::f𵲭ohb-*'-*'ohb𐇂:ff::ff:fې:f::::ې:ff::ff:۶fېf::ې:ff:ې::ېf:ff:۶fېf::ې:ff::ff:fې:f::::ې:ff𵲭􃃗⾗ohb-*'-*'ohb𐇂:ې::ې:ff::ې:::fې::::::f:ff:ې:::ې::ې::f:ff:ې::ې:ff::ې:::fې::𵲭ohb-*'-*'ohb𐇂::۶:fې::۶:fېfff:::::ff:ې:::::f:ff::۶:fې::ې::ې::f:ff:ې:::۶:fې::۶:fېfff:::::ff𵲭ohb-*'-*'ohb𐇂::ېf:::ېf:۶fff:::f::ff::ff:۶ff:ff::ېf:ې::ې::۶ff:۶ff:ff::ېf:::ېf:۶fff:::f::ff𵲭ohb-*'-*'ohb𐇂:ې:fې::ې:fې::fې::f::fې:::::f:::ې:fې::::ې::f:::ې:fې::ې:fې::fې::f::fې::𵲭ohb-*'-*'ohb𐇂f::::fېf::::fېfffffې::ې:fې:::f::::fې::ې::f::::fېf::::fېfffffې::ې:fې:𶳮򶳮ohb-*'-*'ohb𐇂::::fې:f:::ې:ې:::::::ې::::::fې:f:::ې:ې:𸵱ohb-*'-*'ohb𐇂::𾻷ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂ohb-*'-*'ohb𐇂f:ېf:ېohb-*'-*'ohb𐇂::::ohb-*'-*'ohb𐇂:::f:::fې::ې:::f:f:ffې::::f::fې::ffې:::::ې::ې::ې::fې::::f:::fې::ې:::fohb-*'-*'ohb𐇂:ff::ff:fې:f::::ې:ff::ff:۶fېf::ې:ff:ې::ېf:ff:۶fېf::ې::::ې::ې::ې::ېf::ې:ff::ff:fې:f::::ې:ffohb-*'-*'ohb𐇂:ې::ې:ff::ې:::fې::::::f:ff:ې:::ې::ې::f:ff::::ې::ې::ې::ff:ې::ې:ff::ې:::fې::ohb-*'-*'ohb𐇂::۶:fې::۶:fېfff:::::ff:ې:::::f:ff::۶:fې::ې::ې::f:ff::::ې::ې::ې::ff:ې:::۶:fې::۶:fېfff:::::ffohb-*'-*'ohb𐇂::ېf:::ېf:۶fff:::f::ff::ff:۶ff:ff::ېf:ې::ې::۶ff:۶ff:ff::ې::ې::ې::f:ff::ېf:::ېf:۶fff:::f::ffuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb𐇂:ې:fې::ې:fې::fې::f::fې:::::f:::ې:fې::::ې::f::::::ې::ې::ې:::::ې:fې::ې:fې::fې::f::fې::䏏ohb-*'-*'ohb𐇂f::::fېf::::fېfffffې::ې:fې:::f::::fې::ې::::::::ې::f::::fېf::::fېfffffې::ې:fې:uuuuuuohb-*'-*'ohb𐇂::::fې:f:::ې:ې:::::::ې::::::ې::ې::ې::::::fې:f:::ې:ې:ppppppohb-*'-*'ohb𐇂::::ې::ppppppohb-*'-*'ohb𐇂ppppppohb-*'-*'ohb𐇂pppyy11ָVy1ָy1y1ָ1VָyVy1ָyV1֙yV1֙yV1֙pppohb-*'-*'ohb𐇂pppzz11عؚWz1عWؚWz11Wz1WzWWWعzzW1ؚzW1ؚzW1ؚpppohb-*'-*'ohb𐇂ppp{{11ڻ1{{{W{11{{11ڻ1{W{1WڻW1{WڜWpppohb-*'-*'ohb𐇂::ې::fې:::::ې::::::ې:f::ې::fې::f:fېf:ې::::돏Ŀppp{{11ۼ{{11{{11{1Xۜ1Xۼ{XX{X1{ۜX1pppohb-*'-*'ohb𐇂fff:۶:::ې:::ff::::::ff:۶f::fff:ff:۶f::fې:ffffې::::uuuppp}}22ݾYݝY}}22ݾYYݝ}}22ݾYYݝ2}YYYݝY}2Yݾpppohb-*'-*'ohb𐇂::::::::ې::ېf:::::::ې::f:۶::ې::::ې::f::۶f:ff:ff::::sssppp55^ɨ^55Ʉ55Ʉ55Ʉ^5^5pppohb-*'-*'ohb𐇂ff:f:::f۶:::::ې:::::ې::f:۶:::f::ې::f::fېff۶f:f:::::{{{ppp^5555^ʄ55pppohb-*'-*'ohb𐇂f:ې:::ې::fې::::f:f:::f::ff:۶f::ff::ې::۶ff:۶fff:ffff:f:ff:ppp5̅555pppohb-*'-*'ohb𐇂::ې::ې::ffffff۶::ff::f:::::ې:f::ې::ې:ې::f::ېf:f:۶::ffppppppohb-*'-*'ohb𐇂::ېf:ې::f::ff:ې::f:fffې:::::::::ppppppohb-*'-*'ohb𐇂::ې:fff::ېf:::ې::::::::ppppppohb-*'-*'ohb𐇂::ppppppohb-*'-*'ohb𐇂uuuuuuohb-*'-*'ohb𐇂葑ohb-*'-*'ohb𐇂𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𐇂ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'멦rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹȺɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺɻɻʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺɻɻɻɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹȺȺɻɻɻɻʼʼ˽̾ͿͿ-*'-*'֢GLvοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'ުKzۅM̙οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹȺȺȺȺȺȺȺɻɻɻɻʼ˽̾ͿͿ-*'-*'N{֡FοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾ͿW_*4f (P (P")Q#*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fW`-*'-*' ULӢ VإH { ~UإJSMԢVKMSԢW٦JNSբNSգVLSLQڧJSҪKQNբSѫKSЫK|PNҟRͪKÀ߫L}ÀQ˩KQ˪KāކLLz֡GοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾ͿͿ(,Mx|̴୵୵୵㭵䭷䫸竹諹諹꫹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쬺쬺쬺쬺쬺묺꫹諹諸筷䭵䭵㭵୵೹ୱy})-N-*'-*'} JVJ XLԢTإHKTӢ~ Jϋ}VMԢ}MSԢ~T~NTգNT֣VۧJXN֤NפTN֤RLъSҬLT҅TҫLSѫL}QͅRͫL⇿ÀKÀÀQÀQ˩KQ˩KÀÀĂJ٥IաGοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾̾VZ~tp~p~pppooonnlllllllllllllllllnnooopppp~p~t~ǞӄW[-*'-*' ּKTӢ VإHWԨJKTӡ 뻋U€MSԢ}MSӢÀāNSգNTբVڧJUڧJRƨJRۨJOSӫLщSҫL~~SѫLSѪK}|}RͪKᇿNLџQ˩KQ˩KÀÁN֡GοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺɻȺȺȺȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ &Npzdqdqcrcrcrbtbvbvbv`x`x`y`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`y`x`xbvbvbvbtcrcrcrdqdqpz &O-*'-*' ٥HU٦I VJXJKTԢ ئHMԢ~MSԢāŁNT֤NTפVܨKVܨKRǨJRܨKLҊSӫL~TӫLSҫL}}}RΫLإIĀNLџÀQ˪KQ̪KÀĀłM֡GοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺɻɻȺȺȺȺȺȺȺȺȺȺȺɻɻɻȺɻɻ˽̾̾>XfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiRiShSfSfSfTeTeTdTbTbXf>-*'-*'V{V٦I | XԩJ ~U|KUԢV{MԢ~NTգNգTTLXՅVܨKXՅNץTԅLҊTԬLLSӅTܨJRƂ~KRυR٦IO}ÀOÀLĀQؤHOÀÀ|ۧK}ڥJކ֡GοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺɻɻɻȺȺȺȺȺȺȺȺȺȺɻɻɻȺɻɻʼ̾̾Ϳ;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'VJ ~ T{T~VJץJ€KMSԢW٦JNTTۧJVۧJSۨJSҪLQNգS҆LPNԢKPNҠR΅KN~OKÀ~MMJQ˅KM}MОÀ}JOLI֡GοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺɻɻɻȺȺȺȺȺȺȺȺȺȺȺȺǹȺȺɻɻ˽̾̾ 9A/8(/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)?;9LGDe^Zqie|tocGV>B0/,)1/-󢟝1/-/,)GC@d^YqidZAB0ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ碟HD@g`\I5-*'ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳޢ-*'OIF=,0.,ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ.,*B>;ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾ӡ-*(-*'-*'-*'ߢohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'Ϳohbohb-*'-*'Ϳohbohb-*'-*'Ϳohb뺺ohb-*'-*'ͿͿohb랞ohb-*'-*'ͿͿͿohb뎎ohb-*'-*'ͿͿͿͿohb|||vvvvvvxxxohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbffff:fffff::ffohb-*'-*'ͿͿͿͿohbfffffff:f:::ffohb-*'-*'ͿͿͿͿohb:::fې::fې:::ې::::::fff:::fff:::ې::ې::::f:fff:::::ې::fې:::ې::ې::ې::fې:fې:fff:::f:ې::۶:fې::ې:f:ff:::::ې::ې::fff:::::ې:f::ې:ffې:::fff:::::ې::fې::f:::ff:ې::fff:::ې::ې::ې::ېf:ohb-*'-*'ͿͿͿ̾ohb:ff:ې::f:ff::::ff:::ې::fې:ې:ې::ې:::::fې::f:::::ې::ېf::ې::ې::ې::ffېf::ېf:::::ې::fې::ff:ې::ې:ff:۶ff::ې:::ې::ې::ې:::ې::ې::f::ff:۶fېf::ېfff:::::ې::ېf::ې::f:ې::ff:۶f:fې::ې:::::ې:ې::ې::ې::ېf:ohb-*'-*'ͿͿ̾̾ohb:ې:::::ې::::::::::ې::ې::::ې::ې::::fې:::::ې::::ې::ff::ې::ې::ې::ffff۶::ې::fې:::ې::ffff::f:۶::::::ې::ې::::ې::ffff::::ې::f:ff۶::::ې::::ې::ff:::f::::f:f:::ې::::ې::ې::ې::ې::ohb-*'-*'Ϳ̾̾̾ohb::۶:fې::::ې:f۶:::::f::ې::::ې::ې::::ې::::::ې::::ې::ff::ې::ې:::fffff::ې:::::fffff::f:۶::::::ې::ې::ې::۶ffff::::ې::f:ff:f::ې::::ې::ff:::f::::f:۶::::ې::::ې::ې::ې::ohb-*'-*'Ϳ̾̾̾ohb::ېf:::::۶ff:::f:fff::ffff::ې:::ff:ff::::ې:ff:ې::f:ff::ېf:ېf:ff::f:ff۶f:ffffff::ff::ffffff:۶f::::::ېf:ېf:ffffff:f::ff:۶ff:ffff::::ې:ff:ې::f:ff::ېff۶:fff:۶fff:::fff::ېf:ېf:ohb-*'-*'Ϳ̾̾̾ohb:ې:fې:ff::fې:::ې::ff::ff::ې::ې::ې::ې::ff:::ff:::ff::::f:::f۶f:f::ې::::::ې::ې::ې:f:fې:f::::f:::f۶f:f::ې:f:fېff::ې:f::ې::ې:ff:::ff::::f:::ff::ff:f::ې::ff::ېf:::f۶f:fohb-*'-*'̾̾̾̾ohbf::::fېf:::::::ې::::::ې::ohb-*'-*'̾̾̾̾ohb:::fې::::ې::::ې::::::::ې::::ohb-*'-*'̾̾̾̾ohbff::::::::ohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbې::ff::ff::::ffohb-*'-*'̾̾̾̾ohb::ff::f:::::ffohb-*'-*'̾̾̾̾ohb:f:ffې::ې::f::ې:f::ې:ffff:::fff:::ېf::::f::ې:f::ې:f:ff::ff::::f::ې:ffff:::fff:::ې::fff:::fې::ff:::ې:f:f::fې:fې::::ff:::ې::ې::::ې:fېf:ې::fff:::::::::fې::ff:::ې::fې:::::ې::ې:::::ff:::ې:::ff:::ې::fff::::::f:::f:::f:f::fې:fې:::ې::::f:::ohb-*'-*'̾̾̾̾ohb::ff:۶ff::f:::ېf:::ې::fې:۶f::f:ې::ff:۶f:::ې::fې:ې:ېf::ff:ې::ff::::ې::ff:۶f:fې::f::ې:ې::f:ې::ff:۶f:::ې::fې:ې:ff:fې:ې:ېf::f::ې::f:fffېf::ېf::ې::ېf::ې:ې::ې:::ې:::fې:ffffې::ېf:::::::ffېf::f::ې:ې::ېf:::::ې::ff:f::f::ې:fff::ې:ff:fې:ې:::۶ff:۶f::::f:ې::ff:۶f:fffېf::ېf::::ې:::::fې::ohb-*'-*'̾̾̾̾ohb::::f:::fffff۶ې:fې::::ې:::f::ې::f:۶::ې::ې:::::ې:::::ې::::::f:f:::::::ې:::f::ې::f:۶::ې::ې::::ې::::::ff۶::::ې::::::ffff::ې::::ې::ې::ffff:۶f:ff:ff::ې::ې::::::::ff۶::::ې::ې::::::ې::ې::ff::ې::::ې::::::ې::::::::ې::f:۶:::::f::::f:۶::::ffff۶::ې::::fې::::fohb-*'-*'̾̾̾̾ohb::::f:::f:f:f:f:::::ې:::f::ې::f:::ې::::::۶:fې::ff::::::f:۶::::::::ې:::f::ې::f:::ې:::::f۶::::ff::::ې:::::fffff::ې::::ې::ې::۶ffff:fېff۶f:f:::ې::ې:::::::fff::::ې::ې::::::ې:::fff::ې:::::f۶:::::f۶::::::ې::f:۶:::::f::::f:۶:::fffff::ې::::ې:::::fohb-*'-*'̾̾̾̾ohb::ff:۶f:::ې:fې:fff::::::ېff۶::ff:۶fffff::::ېf:ې::ff::::ې::ff:۶fff::::::::ېff۶::ff:۶fffff::ff::ff::f:ff۶:::::f:fff::f:ff۶f:ff::ې::::ې::ې::ffffff:ffff:fې::ې::ې:ff::fff::f:ff۶::::ې::ې:::f۶::ې::ff:::f::ې::::ff::ې::::ff::ff::::۶ff:۶f:f::ېff۶:fff:۶f:fff::f:ff۶f:ff۶:::ff:ff::::ohb-*'-*'̾̾̾̾ohb:::f:ې::fېfffې:fې:::::f:::ff::ې:f::ې:::ې:fې:::::ې::::ې:::f::::::f:::ff::ې:f::ې::ې::ې::::ې::::۶ffff::ې::::f:::ې::ې:::f:fې::ېf:f:۶:::ff:::ff::ff::ې::ې::::ې:::ې:::::ې::ې::ېf:ې::::ې::ې::::ې::ې::f::f::fff:::ff::ff:fff::ې::::ې::ې::ff::::ohb-*'-*'̾̾̾̾ohb::::۶ff::::f::ې::::::::f::::fې:::f::::::::::f:::ې::::ې::::ې::fې::ېf::::::f:fې::f::ohb-*'-*'̾̾̾̾ohb::::ې::::ېff۶:::::::::::f:f:::::::::fې::ې::::ې::ې::::ې::ff:ېf:f۶::ې:::::fې::ff:ff:ohb-*'-*'̾̾̾̾ohb::::::::::ff::ې:::::::۶ffې:::::ff:۶ffې:ohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohb::ff::f:ېohb-*'-*'̾̾̾˽ohb::ff::::ohb-*'-*'̾̾˽˽ohb:::fېfې:fې:::ې::ې::ې:::ffff:::ې::::f:fې::f:ff::::f::ې:ffff:::fff::::ې::f::ې:ffې:ohb-*'-*'̾˽˽˽ohb:ff:ېf:f:ff::ې::ې::ې::f:ېf:::ې:::::fې::f:ff:۶ff::ې:ې::f:ې::ff:۶f:::ې::fې:ې:::ې:ې:fff::::ې:fې:ېf::ېohb-*'-*'̾˽˽˽ohb:ې:::::ې::::ې::ې::ې:::fې::ې::ې::::fې:::::ې::f:::::ې:::f::ې::f:۶::ې::ې:::::fې:fې::ff:fې::ffohb-*'-*'̾˽˽˽ohb::۶:fې::::ې:f۶::ې::ې::ې:::fې::ې::ې::::ې::::::ې::f:::::ې:::f::ې::f:::ې:::::fې::ffff::ffffohb-*'-*'˽˽˽˽ohb::ېf:::::۶ff::::ېf:ېf:::ېff::ې:::ff:ff::::۶ff:۶f::::::ېff۶::ff:۶fffff::::::ffff::ff۶f:ffohb-*'-*'˽˽˽˽ohb:ې:fې::::ې:::ېf:::f۶f:ff:::ff:ff:::ې::ff:::ې::f::::f:::ff::ې:f::ې::::ې:fې::ff:fې::::ohb-*'-*'˽˽˽˽ohbf::::fې::::::::::::ff:fې:ې:fې::fېff:ې:fې:ohb-*'-*'˽˽˽˽ohb::::::::ې:::::::::ې::ې::ې::ې:ohb-*'-*'˽˽˽˽ohb::::ohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbfffffffff:ې:fffohb-*'-*'˽˽˼˼ohbffffffff::fff:ohb-*'-*'˽˼˼˼ohb::ې::f:ې::::ې::ې::::f::ff:::fې:::ې::::f::ffff:::ې::ې::fې:::f:ې:::::::f:::fې::ې:::f:fې::ېf:f::f:f::::::fff:::fې:::ې::ې::f::f::::::ې::ې:::::fې::::ې::ې:f:::::f:::::::::::f:f:::fېohb-*'-*'˼˼˼˼ohbf:::ې:::fې::ې::::ې::ې:::::fې::f::ې:ېf::::ې:::::fې:::fff۶:::ې:ې::ې::ېf:::::fې::ې:::::ff::ff:fې:f::::ې:ff:ې:::ff:f:f:fff:fff::::::ېf:::ېf::ې::fې:۶f::f:ې::::::::fff::::::ff:::::f::::ې:fې::::ff:ې::::ې::::ff:::fff:ff:돏Ŀohb-*'-*'˼˼˼˼ohbff۶::fې:::ې::::ې::ې::::fې:::::::ff۶::ې::::fې::::fې::ې::ې::ې::ff۶::fې:::ې:::::ې::ې:ff::ې:::fې::::::۶fff:۶:fې:fې::::::ې::ې::ې::ffff::::ې:::ېf::ې::::::::::ff:::ې:::::ff:fې::ې:::ې:::ېf:::ې::::ېf:::۶:fې:ې:uuuohb-*'-*'˼˼˼˼ohbff::ې::::ې::::ې::ې::::ې::::::::ff::ې::::ې::::::::ې::ې::ff::ې::::ې::::::۶:fې::۶:fېfff:::::ff::fff:ې::::::::::ې::ې::ې::ffff::::ې::ې::ې::ې::::::::ffff::::۶:fې::::ff::ff۶::::۶:fې::ff::ې::::::ې::::۶:fېsssohb-*'-*'˼˼˼˼ohbff::ff:::ff:ې:::ff:ff::::::f:ff۶:::ff:ff::f:ff::ې::f:ff۶::ff:::ff:::ېf:::ېf:۶fff:::f::ff::ff::ېf:f::::ff:ې::ې::ې::ffff::::ې::ff::ې::::::ې::ffff::::ېf:::::ff::ff۶:f::ېf:ې::ff۶::ې::::ې::f:::ېf:::ېf:{{{ohb-*'-*'˼˼˼˼ohbff::ې::ې::ff::ې::ff::::::::ې::ې::ff::::ې::ې::ې::::ې::ې::ې::ff:ې:fې::ې:fې::fې::f::fې::::::۶:f::::ې::ې::::ff:ff::::::f:fې::::ې::f۶f::ې::::::::::ff:::ې:fې:::::ff:fې::ې:::ې:fې::::ې:ff::ې::::ff::::ې:ې:fې:ohb-*'-*'˼˼˼˼ohb:fېff:fff::ې::f::::fېf::::fېfffffې::ې:fې::::ffې::f:fff:fff::::::::::f::::fې::ې:::::::::f:fېff::f::::fې:::::fېff:ې:fې:::f::::fېf::::fې:::::ې::::f::::ffff::::fېohb-*'-*'˼˼˼˼ohb:ې:::::::ff::ې::::::::fې:f:::ې:ې::fffffffff::ې::ې::ې:::::::ې:::::::ff::::f:::ې::::ff:::ې:ې::ې::f:::ff:::::ې:fff::ohb-*'-*'˼˼˼̽ohb::ې::ohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ̾-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿ̾-*'-*'ohb𕌉䏏ohbͿ̾;-*'-*'ohb𕌉uuuuuuohbͿ;;-*'-*'ohb𕌉ppp                     pppohbͿ̾;̽-*'-*'ohb𕌉ppp                        pppohbͿ̾̽̽-*'-*'ohb𕌉ppp               )          pppohb̾̽̽˼-*'-*'ohb𕌉ppp           )) * * * * * * *     pppohb;̽˼˼-*'-*'ohb𕌉ppp            * *((0((01-/1-/1-/1-/1-/1-/((0'#&     pppohb̽̽˼˼-*'-*'ohb𕌉ppp           * *((01-/738?;B?;BDBHDBHDBHDBHDBH?;B?;B7381-/1-/'#&   pppohb̽̽˼˼-*'-*'ohb𕌉ppp          * *((0*1:?;BDBHCHTTKQZSXZSXeVXeVXeVX`NOTKQYECR?=F76=/.2(''#&  pppohb̽˼˼ʻ-*'-*'ohb𕌉ppp        ) *((0*1:738DBHTKQZSXi\bZSXe`]e`]e`]e`]e`]e`]eVXTKQ`NOTKQR?=F761-/'#&  pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp         *((0*1:?;BTKQZSXTYfe`]hegnonlqunonnonnonnonhege`]e`]DBHTKQ`NOYEC?;B=/.'#&   pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp        *((0*1:?;BTKQeVXe`]hegheguwxuwxuwxuwxuwxuwxuwxe`]none`]ZSXeVXCHT738aKH?;B=/.'#& pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp        *((0*1:?;BTKQi\be`]nonuwxuwxlqu{{{uwxnonheg?;BZSXeVXhegheg?;B((0((0`NOR?==/.'#& pppohb˼ʻʻʻ-*'-*'ohb𕌉ppp      ) **1:?;BTKQeVXe`]lquuwx{e`]?;BgguvgguhegTYfDBH*1:*1:ZSXCHT((0((0aKHR?=1-/(  pppohbʻʻʻʻ-*'-*'ohb𕌉ppp       *((0738DBHZSXe`]TYfnonhegTYf/CHTTYfJP\uwxJP\TYfgguCHTCHT?;BDBHnonnone`]738'#&YEC=/.2(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp     ) **1:?;BTKQeVXZSXuwxlquuwx  ?;B{KervlquTYfCHT*1:ZSX{e`]e`]e`]((0((0((0R?==/.(  pppohbʻʻʻʻ-*'-*'ohb𕌉ppp      *((0738DBHeVXZSXuwx{TYfDBH//CHT{TYfTYfnonCHTTKQZSXnonheg?;B738heg7381-/?;BaKHR?=F762('2(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp      **1:?;BTKQe`]{hegJP\gguSa//'#&oZZoZZoZZhQOhQOaKH܇sthQOܨaKHYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp     **1:DBHZSXnonuwxgguJP\p//JP\stxegoUQoZZhQOYEChQOaKHR?=aKHYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp    )((0738DBHi\bxegCHTlqu/ TYf{}nkxegoZZoUQoUQhQOhQOoUQxegoZZaKHYECaKHaKHoUQhQOYECaKH=/.uwxpppohbʻʻʻʻ-*'-*'ohb𕌉ppp     *((0738DBH}nkhegi\buwxJP\prZSXp/SavCHTCHTDBH?;BCHT?;B?;BZSXDBH738((01-/'#&'#&aKHF762(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp   *((01-/?;BDBHTKQxstlqu*1:'#&TYfJP\JP\JP\DBH?;B?;B?;BTKQDBH7381-/1-/1-/738TKQhQOF76F762('( pppohbʻʻʻʻ-*'-*'ohb𕌉ppp 1-/KerCHTCHTJP\TYfi\bststpTYf{hegheg*1:Saggu{gguKerJP\CHTi\beVXTKQeVXpJP\eVXDBHTKQhQOTYfSaoZZaKHJP\DBH*1:R?=1-/*1:YECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp  YEC`NOeVXLoZZpxegVSai\bxegstgguhegxjrhegi\bSai\bi\boZZeVXpeVXhQOe`]hQOoUQaKHaKHYECYECF76pppohbʻʻʻʻ-*'-*'ohb𕌉ppp  R?='`NO738eVXi\bxegxegxegxegsToLgguggu'i\bxegxeg/xjrTKQeVX'JP\oUQoZZF76oUQaKHYECF76pppohbʻʻʻʻ-*'-*'ohb𕌉ppp R?='`NO'#&?;BoZZ}nkstLxeggguNmpr{'xjrheg'st'oZZDBHTKQl/paKH2('oUQ'aKH'pYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp R?='`NO *738oZZ'}nke{'lqu{xjrexjrYR}nk'eVXDBH`NOYLY`NO2('oUQ'aKHLYEC2('pppohbʻʻʻʻ-*'-*'ohb𕌉pppR?='`NO ((0eVXest}nkxe}nklђprxjr{e{{LstqKereVXhQOe}nkhQO'hQOhQOoUQeYECYECYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp aKHeaKHF76'#&YECLstRlчststxjrъ{xjrst{LststLxegi\beeVX`NOQoUQeaKHaKHYECYECYEC=/.pppffffohbʻʻʻʻ-*'-*'ohb𕌉ppp2('aKHaKHaKHR?= ((0hQOoZZstst{ststxegxjr{stxegi\beVXZSXoZZi\bhQOR?=ZSXoZZaKHhQOR?=aKHYECYECYECYECYECR?=pppffffohbʻʻʻʻ-*'-*'ohb𕌉ppp 1-/R?=hQOɿÚuwxssgzpr?;BR?=DBH1-/1-/DBH aKHR?=2('ppp:f:ff:::ې::::fې::ffff:::::ې:::f:ff::::f:f::۶fې::f::fff:::::ې:::ې::f:f::::fff:::::ې::fې:::ohbʻʻʻ˼-*'-*'ohb𕌉ppp    ((0738R?=hQOȻɿ䶨ЌlquTYfTYfTYfgzBZNm?;B738YEC1-/2('2('aKHF762('  ppp::ff:۶f:fې::::ې::::f:ff:۶ff:::::ff::ff:۶f:fې::ې:::۶fff:۶fff:۶f::fې:ff:۶f::f:::::ff:f:::ېf:::ې:ff:۶f:::::fې:ې:f:::ې::ېf:ffohbʻʻ˼˼-*'-*'ohb𕌉ppp   2('738DBH`NO愆prU~prToTYfssgzTo1-/R?=?;BYECF761-/(  ppp::::f:f:::::ې::::::ې::f:::ې::::ې::::::f:f:::ې::f:۶::f:۶::f:۶:::f::f:::::ې::::ې::fffff۶ې:fې::f:۶::::ې::::ff۶::ې::ې::ohbʻʻ˼˼-*'-*'ohb𕌉ppp    2('F76R?=`NOllU~U~YECgzgzgzTKQZSXZSXYECF76=/.(  ppp::::f:۶::::::ې::::::ې::f:::ې:::::f::::f:۶::::ې::f:۶::f:۶::f:۶:f::f:::::ې:::::ff:f:f:f:::f:۶::::ې::::ff::ې::ې:fohbʻʻ˼˼-*'-*'ohb𕌉ppp   2('738R?=aKH擳撍sspr}nk`NOYECF76=/.(  ppp::ff:۶fff:::::ff:::۶ff:۶f::ې:ff:ff::::ff:۶fff::::ې:ې:ff:۶fff:۶f::f:ff:۶f::::ې:ff:ff:::ې:fې:fffff:۶f:f::ff::ff::ې::۶ff::ohbʻ˼˼˼-*'-*'ohb𕌉ppp  '#&1-/F76R?=YEC`NOȻɴݨxxxaKHYECF76=/.2('(  ppp:::f::::ې::ff:ې::f:ff:::ff::ې:::f::f:::f:ې:f:f::f:ې:ff::ff:::ff::ې:fېfffې:fې::f::ff۶::ې::ff:::ې:::ېohb˼˼˼˼-*'-*'ohb𕌉ppp  '#&2('=/.F76R?=R?=YECaKHaKHaKHaKHaKHYECR?=F76=/.2(''#&  ppp::::::ې::::::::f:::ې::ff::::f:::::::fېff::ohb˼˼˼˼-*'-*'ohb𕌉pppYECYEC2('YECYECYECYECYECYEC aKHF76aKHaKHhQOaKHhQOhQOaKHhQOhQOhQOR?==/.1-/2('(    ppp::::::::ې:::::::::fې::ې::::::ېff:::::ې:::ې::ohb˼˼˼˼-*'-*'ohb𕌉pppR?=YEC R?=YECYECYEC2('YECF76R?=}nkYECsthQOaKHaKHR?=(   ppp::::::ff::::::ohb˼˼˼˼-*'-*'ohb𕌉pppR?=YEC YECYECYEC=/.YECF76aKHF76aKHaKHaKH2('(   pppohb˼˼˼˼-*'-*'ohb𕌉pppYECR?=YECYECR?=YECYECYEC YECF76stF76stYECYEC pppohb˼˼˼˼-*'-*'ohb𕌉pppF76YECYECYECYECYECYECYECYECYECYEC2('YECYECYECYECYECYECYECYEC( pppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉葑ohb˽˽˽˽-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb˽˽˽˽-*'-*'ohb𕌉䏏ohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉pppTTT````````````````````````````````````````````````aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUUUpppohb˽˽˽˽-*'-*'ohb𕌉pppSSSUUUpppohb˽˽˽˽-*'-*'ohb𕌉ppp]]]naaapppohb˽˽˽˽-*'-*'ohb𕌉ppp___TxE]6\ps___pppohb˽˽˽˽-*'-*'ohb𕌉pppaaa氽*Uk*21B*[tSv```pppohb˽˽˽˽-*'-*'ohb𕌉pppcccpCfxYdG)a}?iaaapppohb˽˽˽̾-*'-*'ohb𕌉pppeee8d{dވރ]XtX{aaapppohb˽˽̾̾-*'-*'ohb𕌉pppggg싢0hߝ"uNnDmaaapppohb˽˽̾̾-*'-*'ohb𕌉pppiiiBj~j["wQr2_vaaapppohb˽˽̾̾-*'-*'ohb𕌉pppkkk)]uׁR&"W{ Qk{aaapppohb˽̾̾̾-*'-*'ohb𕌉pppmmmWv,dgr\*!]Mha~aaapppohb̾̾̾̾-*'-*'ohb𕌉pppooo³e'\xare/" dKiMoaaapppohb̾̾̾̾-*'-*'ohb𕌉pppqqq扡(ZtVsk8"!mLkDkaaapppohb̾̾̾̾-*'-*'ohb𕌉pppsss윰1`xKrnA"!tQr6cyaaapppohb̾̾̾̾-*'-*'ohb𕌉pppttt3`v@~pqK#"|Ux&Voaaapppohb̾̾̾̾-*'-*'ohb𕌉pppwww黻ÿ:bv5qmsV&"\Ni}```pppohb̾̾̾̾-*'-*'ohb𕌉pppxxxÿJm+eir_+! bNkd```pppohb̾̾̾̾-*'-*'ohb𕌉pppzzz°^}&^{brf1"!jLkOt```pppohb̾̾̾̾-*'-*'ohb𕌉ppp|||&[vYrl:"!$q|Mx@^pppohb̾̾̾̾-*'-*'ohb𕌉ppp݀좳.\tAqqQk܉j  ?gpppohb̾̾̾̾-*'-*'ohb𕌉ppp݂ÿ5_t:u۔^~  :lpppohb̾̾̾̾-*'-*'ohb𕌉ppp݄¿Ch|Ltޝ9>  @]pppohb̾̾̾̾-*'-*'ohb𕌉ppp놆ÿ]~>h聁TT.. Aapppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp눈v0]}円__884 A\pppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp뉉务2_|uN^Csppp:f::::fff:::fې:::fff:::ې:::::::f::ې:f۶::::ې::ې::ې:::::f::fې:::f:ې::::ې::ې::::f:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::ې::ې::::f:ohb̾̾̾̾-*'-*'ohb𕌉ppp싋游覷KqKhC^ppp:fff۶::ff:::ې:ېf:ff:::ې:ې:::::ff:ې::ff::ې::::ې::ې::ff::۶ff:۶f::ېf:::::fې::ې::::ې::ې:::::fې:::::ې:ې:::::fې:ې:f::ې:ې::f:ې::ff:۶f:::ې::fې:ې:ې::ې:::::fې::ohb̾̾̾̾-*'-*'ohb𕌉ppp썍⁂ppp:fې::::::ې::ې::ې::::ې::ې:::::ې:::::ې::ې::::ې::ې::ې::::ې::f:۶::ff۶::fې:::ې::::ې::ې::::fې:::::ې::ې::::ې::::::::ې:::f::ې::f:۶::ې::ې::::ې::ې::::fې:::ohb̾̾̾̾-*'-*'ohb𕌉ppp쏏ppp:::::f::ې::ې:f::ې::::::۶:fې::ff::ې::::ې::ې:::f::ې::f:۶::ff::ې::::ې::::ې::ې::::ې::::::ې::::ې::::::::ې:::f::ې::f:::ې::::ې::ې::::ې::::ohb̾̾̾̾-*'-*'ohb𕌉ppp쑑pppf::fff::ff::۶ff::ff:ff:::ېf:ې::ff::ې:f::ې::ې::ff::::۶ff:۶f:ff:ff۶::ff:::ff:ې:::ff:ff::ff:ff:ff::::::::ېff۶::ff:۶fffff::ې:::ff:ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp풒ppp::ې::ff::ې::ې:ې:::ې::ې::ff:ې:fې:::::ې::ې::f:ې::ې::ېf::f::ff::ې::ې::ې::ff::ې::ff::::ې::ff::::::f:::ff::ې:f::ې::ې::ې::ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp픔ppp:fff::f::::fې:::f::ې::f:::f:::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp햖pppff:::::f:f۶:f:fې::ې:::fې::::::::::ې::ohb̾̾̾̾-*'-*'ohb𕌉ppp࿿pppff::ff::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp߾pppohb̾̾̾̾-*'-*'ohb𕌉ppp߿pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppp𜜜텅pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp񙙙ကpppohb̾̾̾̾-*'-*'ohb𕌉ppp񞞞pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉uuuuuuohb̾̾̾̾-*'-*'ohb𕌉葑ohb̾̾̾̾-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾ͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿͿͿͿ-*'-*'ohb𕌉䏏ohbͿͿͿͿ-*'-*'ohb𕌉uuuuuuohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉pppҎpppohbͿͿͿͿ-*'-*'ohb𕌉pppҐyyypppohbͿͿͿͿ-*'-*'ohb𕌉pppxxxxxxxxxxxxxxxxxxxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԈxxxxxx000---555CCCxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԃxxxxxxJJJJJJxxxpppohbͿͿͿο-*'-*'ohb𕌉pppԓxxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖¼xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖Ч˸xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖٣ʱxxxxxxJJJJJJxxxpppohbͿοοο-*'-*'ohb𕌉ppp֖ܿ«xxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖݦʻxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖޛɞxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖߝҟxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ௯לyyyxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږԠʫʓyyyyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږӳ󛛛zzzyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ῿zzzzzzJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppۖ⽽{{{zzzKKKKKKxxxpppohbοοοο-*'-*'ohb𕌉pppۖNo||||{{{KKKKKKyyypppohbοοοο-*'-*'ohb𕌉pppۖRw&V%S||||||LLLKKKyyypppohbοοοο-*'-*'ohb𕌉pppݖά2_rŐJq=_||||||LLLLLLzzzpppohbοοο-*'-*'ohb𕌉pppݖ&V^@jiŠ3_bt}}}|||LLLLLLzzzpppohbοο-*'-*'ohb𕌉pppݖ;eJrQwD0]d$T~}}}}}}MMMLLLzzzpppohbοο-*'-*'ohb𕌉pppݖxÕ:ehɊIDDMtNu5_~~~}}}))))))JJJMMM{{{pppohbο-*'-*'ohb𕌉ppp떖+Yn͎)XCDDIeŇ8dg~~~~~~111///111BBB|||pppffff::ffohbο-*'-*'ohb𕌉ppp덗*Y_ȂHqCCCCD)Ykȋ'V~~~~~~~~~}}}}}}|||pppffff::ffohb-*'-*'ohb𕌉ppp>>;;;???\\\pppohb-*'-*'ohb𕌉pppDOO? ? ? ?8d{{{JJJ;;;GGGpppohb-*'-*'ohb𕌉pppK @<<<<<<<<EDn>>??8d~ޜMpppohb-*'-*'ohb𕌉pppNF99999999 ?MM~Cm>>>H2_𜜜pppohb-*'-*'ohb𕌉pppNN 844444445L;f @=> A`̓N𛛛pppohb-*'-*'ohb𕌉pppNL 4...... 3M2_== B}ޙOpppohb-*'-*'ohb𕌉pppLM1^:++++ 5Lx==NߜOpppohb-*'-*'ohb𕌉pppdʆܰ%S@?F/\쭕 A B_c΅Mpppohb-*'-*'ohb𕌉pppMqΐˁ㝛p3`p̑4aNpppohb-*'-*'ohb𕌉ppp+[ަխvٔ8dNpppohb-*'-*'ohb𕌉pppLL Q(X)XPMpppohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉葑ohb-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ãS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<=????????????????????????????????????????????????????????????????????????[>Uohb-*'-*'ohb𕌉<>!!!>= """?$?GIHFDHMP R T V W S T UTPI@"?>EL T\ Ja'f+j.m0o1u7splgb] Z VN@>DL V_gVj1q5v9y;z<~A"{upic] Y T&&&@ D H J JO3-%zrib\ V ^9@̜4(r>QΥ;ŕ,!{q`***AjBpHa _i s }&.6+Σ'ӬJ׶dܿ{ȍЛצݫkմۛՉsܼ[ҬBǜ<\]+kE---B` zSyR[e o z%/ū9ʱAOʢҫ;׵ZܽrƅΕՠڨެߧܟؑh׵OͥCǝayEnGnFBc;iBkDpHxQZe p |(è4ʱ@йKԿT]eg`ŕ4ڻJܽgẏѐԖ֗֔Ӌmٺ]ԱmęA~g |U{SBxRvP{T^j u".Ȯ:ζFӽQ[dlrt|̤_cmx}zrqܿ|̪ŲJ2q `}XF<ffff::ffohb-*'-*'ohb𕌉!r ` F<::ې::f:ې::::fff:::::ې:ff:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::::fې:fff::::ff:::fې::f::ې::ې::fff:::fff:::ې:ffff:::ې::ې::::ېfې::f:f:f:::ې::fohb-*'-*'ohb𕌉Ϸ@ҼHQX_cfgfc_YRҽHՇqӾ[ȱL-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞+*)A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*GECC0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'b`](,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝b`]{xua@=4$ .+(.,*cbadmBFZ/-+.+(c`^{xuuTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'\ZWmjg{tqsl-2.0/apps/help/tqslapp/signupload.htm0000664000076400007640000001750012231073120020576 0ustar rmurphyrmurphySubmitting a Log File to LoTW via the Internet

Submitting a Log File to LoTW via the Internet

To digitally sign a log file and upload via the Internet to the ARRL's Logbook of the World (LoTW) online service,
1.Verify that all of the QSOs in the log file were made with the same Station Callsign (the callsign you used over the air during the QSO), and from the same location. If this isn't the case, use your logging application or a text editor to split the log file into multiple log files, each of whose QSOs were made with the same Station Callsign from the same operating location, and separately submit each log file.
2.Start TQSL. If you do this before receiving your Initial Callsign Certificate, an Alert window will appear that informs you that you have no Certificate, and asks if you want to request one; click the Yes button, and proceed as described here.
3.Select the Log Operations tab
  
  and click the Sign a log and upload it automatically to LoTW button.
4.In the Select File to Sign dialog,
   4.aSet the Files of type selector (on OS X, set the Enable selector) to ADIF files or Cabrillo files.
       *You can digitally sign Cabrillo log files for these contests without additional configuration.
       *When submitting a Cabrillo log file, mode PH is submitted as SSB
       *If your logging application does not ensure that only new or newly modified QSOs are presented to TQSL for submission to LoTW, enabling the Prompt for QSO Date Range option will help spare LoTW from having to process QSOs that it's already processed.
       *You can change the file extensions displayed when you set the Files of type selector.
       *You can enable or disable the submission of nonamateur callsigns.
   4.bNavigate to the folder containing the log file you wish to submit
   4.cSelect log file you wish to submit
   4.dClick the Open button
5.In the Select Station Location for Signing dialog, select the Station Location that specifies the Callsign and operating location used to make the log file's QSOs, and click the Ok button.
  

6.In the TQSL - Confirm signing dialog, verify that the information displayed is correct, and click the Yes button.
7.If TQSL is configured to not submit QSOs that lie outside a specified date range, the QSO Date Range dialog will appear; specify the desired Start Date and End Date, and click the Ok button.

If your logging application does not ensure that only new or newly modified QSOs are presented to TQSL for submission to LoTW, the QSO Date Range dialog can help prevent the submission of QSOs that have already been uploaded and processed.

8.If the Callsign Certificate associated with the selected Station Location is password-protected, the Enter password dialog will appear; enter the password, and click the OK button.
9.If TQSL detects any QSOs in the log file that have already been submitted to LoTW and haven't been subsequently modified, it will display the Duplicate QSOs Detected dialog:
  
   9.aClick the Exclude duplicates button to continue processing, ignoring the duplicate QSOs (recommended)
   9.bClick the Cancel button to abandon processing so you can either select a log file that doesn't contain duplicate QSOs, or use the QSO Date Range dialog to exclude duplicate QSOs
   9.cClick the Allow Duplicates button to submit the duplicate QSOs; note that the digitally signed log file submitted to LoTW will be marked as containing duplicate QSOs
    Note: if all QSOs in the log file are duplicates, the Exclude duplicates button will not be displayed
10.The Status Log in TQSL's main window will display the results of the operation, including the number of QSOs ignored because their dates were outside of the specified Date Range, and the number of duplicate QSOs detected:
  
   10.aIf the upload to LoTW failed, a dialog box will be displayed offering to repeat the upload; click Yes to upload the digitally signed file again, or click No to abandon the operation.
11.After processing, the uploaded file will be shown in LoTW's Your Activity list with the filename selected in step 4.c above preceded by <TQSLUpl YYYYMMDD-HHMM>, where YYYY is the current year, MM is the current month, DD is the current day, HH is the current hour, and MM is the current minute.
 

tqsl-2.0/apps/help/tqslapp/signing.htm0000664000076400007640000002021212231073120020061 0ustar rmurphyrmurphySubmitting a Log File from a Computer without Internet Access

Submitting a Log File from a Computer without Internet Access

To digitally sign a log file for submission to the ARRL's Logbook of the World (LoTW) online service,
1.Verify that all of the QSOs in the log file were made with the same Station Callsign (the callsign you used over the air during the QSO), and from the same location. If this isn't the case, use your logging application or a text editor to split the log file into multiple log files, each of whose QSOs were made with the same Station Callsign from the same operating location, and separately submit each log file.
2.Start TQSL. If you do this before receiving your Initial Callsign Certificate, an Alert window will appear that informs you that you have no Certificate, and asks if you want to request one; click the Yes button, and proceed as described here.
3.Select the Log Operations tab
  
  and click the Sign a log and upload it automatically to LoTW button.
4.In the Select File to Sign dialog,
   4.aSet the Files of type selector (on OS X, set the Enable selector) to ADIF files or Cabrillo files.
       *You can digitally sign Cabrillo log files for these contests without additional configuration.
       *When submitting a Cabrillo log file, mode PH is submitted as SSB
       *If your logging application does not ensure that only new or newly modified QSOs are presented to TQSL for submission to LoTW, enabling the Prompt for QSO Date Range option will help spare LoTW from having to process QSOs that it's already processed.
       *You can change the file extensions displayed when you set the Files of type selector.
       *You can enable or disable the submission of nonamateur callsigns.
   4.bNavigate to the folder containing the log file you wish to submit
   4.cSelect log file you wish to submit
   4.dClick the Open button
5.In the Select file to write to dialog, navigate to the folder where you want the digitally signed log file created, specify the name of the file to be created, and click the Save button.
6.In the Select Station Location for Signing dialog, select the Station Location that specifies the Callsign and operating location used to make the log file's QSOs, and click the Ok button.
  

7.In the TQSL - Confirm signing dialog, verify that the information displayed is correct, and click the Yes button.
8.If TQSL is configured to not submit QSOs that lie outside a specified date range, the QSO Date Range dialog will appear; specify the desired Start Date and End Date, and click the Ok button.

If your logging application does not ensure that only new or newly modified QSOs are presented to TQSL for submission to LoTW, the QSO Date Range dialog can help prevent the submission of QSOs that have already been uploaded and processed.

9.If the Callsign Certificate associated with the selected Station Location is password-protected, the Enter password dialog will appear; enter the password, and click the OK button.
10.If TQSL detects any QSOs in the log file that have already been submitted to LoTW and haven't been subsequently modified, it will display the Duplicate QSOs Detected dialog:
  
   10.aClick the Exclude duplicates button to continue processing, ignoring the duplicate QSOs (recommended)
   10.bClick the Cancel button to abandon processing so you can either select a log file that doesn't contain duplicate QSOs, or use the QSO Date Range dialog to exclude duplicate QSOs
   10.cClick the Allow Duplicates button to submit the duplicate QSOs; note that the digitally signed log file submitted to LoTW will be marked as containing duplicate QSOs
    Note: if all QSOs in the log file are duplicates, the Exclude duplicates button will not be displayed
11.The Status Log in TQSL's main window will display the results of the operation, including the number of QSOs ignored because their dates were outside of the specified Date Range, and the number of duplicate QSOs detected:
  

12.Submit the signed log file to LoTW.
   12.aMove the signed log file to a computer with internet access
   12.bDirect a web browser on that computer to navigate to https://p1k.arrl.org/lotwuser/default
   12.cLogin using your LoTW web username and password
   12.dSelect the Upload File tab
   12.eClick the Choose File button, and select the signed log file you moved in step 10.a
   12.fClick the Upload file button
 

tqsl-2.0/apps/help/tqslapp/signdone.bmp0000664000076400007640000006600612231073120020232 0ustar rmurphyrmurphyBMl6(.j  @@ bbb&'VWBCnn67bbJK¶z|./^_vx>?jlRSqseg~Z^NRFG:;"#23**ZZNN~~0!.!!!,!!!!+!!!!(!!!!!&!!!!!#!!!!!!!!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!! !!!! !!!!! !!!! !!!!! !!!!! !!!!!&3u3o!!!!'1t4n!!!!!'5t5m! !!!   }!! !!!       }!! !!!      }!! !!!   }! !!!      }!!!!!        }!!!!    }!!!!! )  + # }!!!!! "  ( # }!!!!! !!!! !!!!!&33u)!!!!'11t)!!!!!'55t)!! !!!   #!! !!!          "! !!!         "!! !!!       "! !!!           "!!!!!        #!!!!!        "!!!!!  '  "!!!!(  #!!!!! !!!! !!!!! !!!!! X{!!!!!!Yz! !!!  8!! !!!   8! !!!  8!!!!!     8!!!!!  8!! !!!     8! !!!     8!! !!!K   8! !!!!   8!!!!! !!!!! !!!!!"!!!!$!!!!!&!!!!(!!!!!(!!!!!%!!!!!%!!!!%!!!!!%!!!!%!!!!!%!!!!!. !!!!!u!!!!u!!!!!!!!!  !!!!! !!!!! !!!!! !!!!  !!!!!!!!!  # !!!!!   !!!!!%!!!!!%!!!!%!!!!!%!!!!%!!!!!%!!!!!&!!!!!'!!!!!!!!!!!  9999)9)9))66666666686888888787777757755555%55% % % % % 4 4 4444<<<<33<<3<'<'3' '' ' 2 ; ; ; 2;#2##2##2/##/##/&/////&&/&/ &-&----$$$--$$$$$??? 0??0 00 0 1 1 = =1=1==1(=(1 (....*,***,* *+ *+ ++ >> > > >>> !!!!!!   999)9)9))))6666666688888888787777575555%5%5 % % 4 4 444<<<3<3'<'<' ' ' ; ; ;2;;22#2#2#2# #//#///&/&//& &&-&-&-&--$--$-$$-$$???0 ? ? = 1 11=1=11(1(=((( ....., ****,** **+*++ +> +>+> :>>>>> !!!!   99999)9))9))666666666688888887877757775555%5%5%5% % % 4 44 44443<<<<3<3'<''3' ' ' ' ;; ;; ;2;;2;;#2#2#/#//////&/&&&&-&-- $--$$$-$$$$????0 0 0 0 1= == 1=11==(=((1((( .....**,**,* +* * ++ ++> >> >:> !!!!        999)99)))666666668888 87878788 775555%%55%5% % 4 4444<<3<<33'<<' '' ' 22 2;;2#;##2# /##/#/#/#///&/&/ &-&-&&-&-$-$$- $?0 ?00? ?? ? == =11==1(11((((  .... ****  * ++ + +> > >>>!!!!      99))9)))6666666688888 87777877 7777755%%5%%5% % 44 4443<<<3<3''<33' ' ' 2;2 ;2;;22;2#22##/#////&/&/& -&-----$-$$-$$$00? 00? ? 0 1=1 1==1((1(( .......****,* ++**+ + > > >>> " " "!!!!       9))9 )666666666688888877 7 7775575 5% % 44 4 <3''<<3 ' ;22;#;# /##/##/#/#//&/&/&/& &-&&---$$- $0??? 0 11=((= ((  ... ****,,* + + > >:>>:::: :: :!!!!       9 ) 666666666 888787878 7775 5%5% 44<3< ' ' ;2;2;22 #/#/#///// & -&--&---$$- $$ 0 ? 0 1=1=1= (( .......*,***** ++ + ++ >> : >:>!!!!    9 9)))66666668888887 777755%5% % % 44<3<3<' ' ; 22;2 ###/#/#/#///////&//&/&&-&---$$- $ 0 ? = 11=11=1(( ( ......  *,***** * *+ +>> >     !!!!     99)99)))6666666668888777 775555% % % %% 4  4 <<'<<' ;2; 22;;2;;2;22 # //&//&/&&//& &------$$-$--$$$$$0??? =1= 1==1(1=(. .....,*****+ ** +  > >:>>:> !!!!!!!!!!!!!!!!!!!     999)99))))) 6666666668888888787 7755%55%55% %% 4  44444<<3<3'<<' '' '' ; ; 2;2#;2###/#/#/#//&/&/&&& &&-&----$-$-- $$?0??0 00 00 = 1 11=1(==( (((((.......,**** ** **++ +> >>> !! !!!!!!!!!!!!!!   9999))9)))666668888888777775555%5%%55% % % 44 4444<<3<3<''<' ' '' 2 ;2 22;2#2;2## ///&/&&/&&-&&---$-$-$$-$ $$$$?000?0? 0 00 1 1= ==11==1=((=(((( .....***** * *++* + ++ > > >:>>  !!!!      9999)99)9)))) 6666666 6888888787777555%5%5%5% % % % 4 4 4444<<<<33'33'<' ' ' ' ; 2 ; ;2#2#;# ##/#//#///&/&&/&/&&&&-&&----$-$- $$???00 0 ? ? = = = 1==1=1(11(1(((( ..... ****,** * *+*+ + + > >+>>:>>> !!!!    999)9)9)))6666668888888877777555%5%5% % % 4 4 444<<<3<'<'<' ' ' ; ; ;2;#;2##/##/// //&//&/&/& &-&--- --$$--$-$-$$$$0???0?0 0 ? = = =1=1=1=(=(=(((...*****+* *+ + > : >:>>>  !!!!     9999)9)9))) 66666888 888777777555%5%%5% % % 4 4 444<<<<3<<3<<'<'<' ' ' ; ;; 22;#2##;###////&/&//&&&&----$-$--$$$??0 ?0?0 0 ? = =1 1==11(=(1((( .... ,****** * *++ +>>+>>>   !!!!      99)99 )))6666666 88 8888777 7775 5%55% %% 4 444<33<3<<'<< ' '' ; 2;22#2 ###///&/&&/&/ & &&---$-$$-$- $$$??0?0?0?0? ?? 1 =1=11=(== (((....., ****,*, *+**+ > >:>   !!!!     99))9))6666688 8887877755%5% % 44 44<<''<' ' ; ;2#2##////&/&& ---$-$$???0?0? ? = =11((1((. ....,*,**,*,* +* +> >:>>!!!!     9 ) 6 6  88  7  5 % 4  < ' ; # /&/ &-$- $ ?00? =1= (   ... **,,,, * + >   !!!!!!!!!      9 ) 666  88 7  5 % 4  < ' ; #  / &  - $  ? = (  .... ,,, * >   !! !!!!+!!!!,!!-!!/!tqsl-2.0/apps/help/tqslapp/signconf.bmp0000664000076400007640000003343412231073120020231 0ustar rmurphyrmurphyBM76(5  @@bbbjl"#FGVW**¶:;vvbbNO./rt^`~ >?23y{Z^egnp&&ZZBCJNRS66JJ>>>L'>S'>'7>'>'>'>'> '>'> ' >'>'>>'L>'g>,'>'>'I> '>>>>>(|(>'>>'(|(>>>>>(|(>'>>'(|(>>>>>(|(>'>>']([(>>>>>](Y((>'>>'](Y((>>>>>](Y((>'>>'](Y((>>>>>]((Q((Pd(>'>>']((Q(((Md(>>>>>](((L((M(d(>'>>']((L(((M(d(>>>>>]((L(((M(d(>'>>']((L(((M(d(>>>>>]((L(((M(d(>'>>'](( (((((( ((( (d(>>>>>](( (((((((((( ((((((d(>'>>'](( (( (((( (((((((d(>>>>>](( (((((( (((((((d(>'>>']((((((((((( ( ((((((((d(>>>>>]((((((((((((( (((((((d(>'>>>]((((((((( (((( (d(>>>>'](((((((( ((&(d(>'>>>](((((((( ((&(d(>>>>']((L(((M(d(>'>>>]((L(((M(d(>>>>']((L(((M(d(>'>>>]((M(((M(d(>>>>']((N((N(d(>'>>>]((Q((Od(>>>>'](Y((>'>>>](Y((>>>>'](Y((>'>>>](Y((>>>>'](Z(>'>>>](\(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>> (h (>>>>' (h (>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>'((((((((((((((((((>'>>>((((((((( (((((((((((((((((((((((>>>>'(((((((((((((((((((((>'>>>((((((((((((((((((((((>>>>'((( (((((((( ((((((((((((((>'>>>((((((((((((((((((((( (((((((((((((((>>>>'(((((((((( ((((((((((((>'>>>( (((7((((((>>>>'( ((((0((((>''>>(|(>>>>'(|(>'>>>(|(>>'>'(|(>'>>>(|(>>'>'(|(>'>>>(|(>>'>>((((((((((((((( ((((((((>'>>>(((((((( (((((((((((((((((((((>>'>>((((((((((((((((((((((((((((>'>>>(((((((((((((((((( ((((( ((>>'>>((((((( ((((((((((((( ((((((((>'>>>(((((((((((((((((((((((((((>>'>>((((((((((((((((((( (((((((>'>>>(((((((( (((((((((((((((((((((>>'>>((((( ((((((((((( ((((((((>'>>>(|(>>'>>(|(>'>>>(|(>>'>>(|(>'>>>9((@(>>'>>8(((?(>''>><((?(>>>>>((((((((((((((((((((((( (>'>>>((((((((((((((((((((( ((((((((((( (>>>>>((((((( ((((((((( ((((((((((>'>>>( ((((((((((((( (((( ((((((>>>>'( ((((((((((((( ((((((((>'>>>((((((((((((((((((((((((( ((((((>>>>'( ((((((( (((( (((( ((((((>'>>>(( ((($((((((((((>>>>'( ((( (((((((((((>'>>>(|(>>>>'(|(>'>>>(|(>>>>'(|(>'>'>D(&(3(U(:(4((>>'>'C(((1((U(8((2(((>''>>C(((5(U(<(6((>>>>'(((((((((((((((((((((((((((((((( ((((((((((((((((((((( (((((((((((((((((((((((((((((((((((((( (>'>>>((((((( ((((((((((((((( ((((((((((((((((((((((( ((((((((((((((((((((((((( ((((((((( ((((((((((((((((((((((((((((((((((((((((((((((((((((((((>>>'>((((( ( (((((( ((((((( ((((((((((((((((((((( ((((((((((((((((((((( ((((((((((((((((((((((((((((( (((((((((((((((((((((((((>'>>>(((((( ((((((((((((( (((((((((((((((((((((( ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((>>>>>((((((( (((((((((((((( ((((((((((((((((((((((( ((((((((((((((((((((( ((((((( (((((((((((((((((((((((((((((((((((((((((((((((((>'>>>(((((((( ((((((((( ((((((( (((((((((((((((((((((( (((((((((((((((((((((((( ((((((((( (((((((((( ((((((((((((((((((((((((((((((((((((((((((((((((( (>>>>>((((((((((((((((((((( ((((((((((((((((((((((( (((((((((( (((((((( ((((((((((( (((((((((((((((((>'>>>((((((((((((((((((((((((((((((3(0(>>>>>(((((((((((((((((((((((((((((((((((>'>>>(|(>>>>>(|(>'>>>(|(>>>>>(|(>'>>>(|(>>>>>(|(>'>>>(|(>>>>'(|(>'>>>(|(>>>>>(|(>'>>>(|(>>>>'(|(>'>>>(|(>>> >'>'>'>'>''>'> '>''>''>''> ''>''>''>''>'>' >'>>'>>'>' >'>'>>'>'>''>>''>'>'> ' >'>'>>''> '>'>'>'>'>>'>''>'>' >'>''>'>'''''>''>'>'>>'>''>>'>''>'>>> ":":":&:&&;;;;# ## 33%%=%==$$$7 77 8 ?8??8?889999 4...... 2***  !!!!/!!))) ---55<6666, ,  '''>'>>>":":":"&:&:&&&&;#;;# # 3 33%%%==%==$$77 ?? ?889 4+44+ .....2222 **** **  ///!!!/ !))----550< 6<66666,,, , ,  ''>>>>  ":":&:&; # # 3 3%=%== $777 ? 889 ++4+4+ ....2222** **   /!//!! ))--5-- 5<66, , ''>>>>>  ":":&:&;; ##;#;## # # 3 3 %===$$7  ?88?99 4+4+4....222****** * *  /!!!!))---5555<6666,,, , , ''>'>>>  ":"::&&;# # 3%% ==$$#7$77    ?8899 99 + 444.......22 ** ** * *   //!//!!)) ))---55555<<666,, , ,   0''>>>>>  ":":"&&&&&;;;#;;#;## # # 333353%%%%=====$$$$777  ??89 9 4 4++4....22**** **   ///!!!!!)))--505<<<<66,,, , , ,, ,''>'>>>  ":"":::&&;;;##;# # #  3%3%%=%===$$$777   ??99 9 4 44+44 ........ 22222** ** /!!!!!)))-555<5<66,, ,     ''>>>>> ":": &&&&&;;##;#  33(%%%%%===$#7777   ??8899 9 44 44+4+4 .....222 *****   //!/!!!!)))-)---555< 6<66666,,, ,  ''>'>>>":":&&&&;;;#;# # # 333%% ======'$77$77 7  8?999 4 2 **** /!!/!!)) ----55 <66666,, ,, , ,  ' >>''''>>>>>" :":::&::&;;;# # # # 3  33 %% ===$ $$77  ???99 44+4.... 222*** *  //!!!!))-550<666666,,, , ''>'>>> "::&&&;;# # 3 3 %%%%=$%$$$777  ?88889 4+4.....2 ** * ** /!/!!! )----- 5<6666,,,, ,, (( (''>>>>>  ":":: &&&&;;;;# # # #3 3333%%==$=$7$7 ? ?88?9 4+4..22** *   //!!/!/!!!))--55<<666,, ((((''>'>'> ":&:&&&& ;;;#;;# 3 3333%=%%=$$77 77 ? ??899 99 4 4+444.....22 * *  !/!!) ))---5555<<666,,, ,  11 11''>>>>>  " :""&":":&:&&;;#;# # ##3 3 33%%=%= ==$$$7$7 7 ? ?88899 9 4 4+44...222** * *  //!!!!!))--5-5 5<<<66666,,, ,, ,    1''>'>>>  " ::"":&&::&:&&;;#;# ## # 3 3 33%%=%===$$7$7 7 ? ?88?899 9 4 44+44.....222** * *  //!!!))-)--55<5< 666666,,, ,, ,   >'>>>>'  " :":"&":&&:&&;;;##;# # # 33 33%%%==%= =$$$$77$7 7 ?? ?8?999 9 44 44.....2222*** *  //!/!!))))--555 5<<66<66,, ,  ''>'>>>":&":&;# # 3 %==$7 ?9 4..2*  * ////!!))--5<<6,  '>>>'>":":&;# # 3%=$7 ?9 4.2* //!! ))56,  ' '>'>>>'>>>>>>tqsl-2.0/apps/help/tqslapp/sign1.bmp0000664000076400007640000264446612231073120017463 0ustar rmurphyrmurphyBM6I 6(?I kM`FV>A/8(/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)EEE/GScGV>B0/,)1/-󢟝1/-/,)N7nnnEj|ZAB0ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ碟OOOaqqI5-*'ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳޢ-*'"=V=,0.,ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ.,*ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾ӡ-*'-*'-*'ߢohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'Ϳohbohb-*'-*'Ϳohbohb-*'-*'Ϳohbohb-*'-*'ͿͿohbuuuohb-*'-*'ͿͿͿohbUUU___yyyohb-*'-*'ͿͿͿͿohb000%%%%%%(((<<|Mx@^pppohb̾̾̾̾-*'-*'ohb𕌉ppp݀좳.\tAqqQk܉j  ?gpppohb̾̾̾̾-*'-*'ohb𕌉ppp݂ÿ5_t:u۔^~  :lpppohb̾̾̾̾-*'-*'ohb𕌉ppp݄¿Ch|Ltޝ9>  @]pppohb̾̾̾̾-*'-*'ohb𕌉ppp놆ÿ]~>h聁TT.. Aapppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp눈v0]}円__884 A\pppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp뉉务2_|uN^Csppp:f::::fff:::fې:::fff:::ې:::::::f::ې:f۶::::ې::ې::ې:::::f::fې:::f:ې::::ې::ې::::f:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::ې::ې::::f:ohb̾̾̾̾-*'-*'ohb𕌉ppp싋游覷KqKhC^ppp:fff۶::ff:::ې:ېf:ff:::ې:ې:::::ff:ې::ff::ې::::ې::ې::ff::۶ff:۶f::ېf:::::fې::ې::::ې::ې:::::fې:::::ې:ې:::::fې:ې:f::ې:ې::f:ې::ff:۶f:::ې::fې:ې:ې::ې:::::fې::ohb̾̾̾̾-*'-*'ohb𕌉ppp썍⁂ppp:fې::::::ې::ې::ې::::ې::ې:::::ې:::::ې::ې::::ې::ې::ې::::ې::f:۶::ff۶::fې:::ې::::ې::ې::::fې:::::ې::ې::::ې::::::::ې:::f::ې::f:۶::ې::ې::::ې::ې::::fې:::ohb̾̾̾̾-*'-*'ohb𕌉ppp쏏ppp:::::f::ې::ې:f::ې::::::۶:fې::ff::ې::::ې::ې:::f::ې::f:۶::ff::ې::::ې::::ې::ې::::ې::::::ې::::ې::::::::ې:::f::ې::f:::ې::::ې::ې::::ې::::ohb̾̾̾̾-*'-*'ohb𕌉ppp쑑pppf::fff::ff::۶ff::ff:ff:::ېf:ې::ff::ې:f::ې::ې::ff::::۶ff:۶f:ff:ff۶::ff:::ff:ې:::ff:ff::ff:ff:ff::::::::ېff۶::ff:۶fffff::ې:::ff:ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp풒ppp::ې::ff::ې::ې:ې:::ې::ې::ff:ې:fې:::::ې::ې::f:ې::ې::ېf::f::ff::ې::ې::ې::ff::ې::ff::::ې::ff::::::f:::ff::ې:f::ې::ې::ې::ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp픔ppp:fff::f::::fې:::f::ې::f:::f:::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp햖pppff:::::f:f۶:f:fې::ې:::fې::::::::::ې::ohb̾̾̾̾-*'-*'ohb𕌉ppp࿿pppff::ff::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp߾pppohb̾̾̾̾-*'-*'ohb𕌉ppp߿pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppp𜜜텅pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp񙙙ကpppohb̾̾̾̾-*'-*'ohb𕌉ppp񞞞pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉uuuuuuohb̾̾̾̾-*'-*'ohb𕌉葑ohb̾̾̾̾-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾ͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿͿͿͿ-*'-*'ohb𕌉䏏ohbͿͿͿͿ-*'-*'ohb𕌉uuuuuuohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉pppҎpppohbͿͿͿͿ-*'-*'ohb𕌉pppҐyyypppohbͿͿͿͿ-*'-*'ohb𕌉pppxxxxxxxxxxxxxxxxxxxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԈxxxxxx000---555CCCxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԃxxxxxxJJJJJJxxxpppohbͿͿͿο-*'-*'ohb𕌉pppԓxxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖¼xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖Ч˸xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖٣ʱxxxxxxJJJJJJxxxpppohbͿοοο-*'-*'ohb𕌉ppp֖ܿ«xxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖݦʻxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖޛɞxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖߝҟxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ௯לyyyxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږԠʫʓyyyyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږӳ󛛛zzzyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ῿zzzzzzJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppۖ⽽{{{zzzKKKKKKxxxpppohbοοοο-*'-*'ohb𕌉pppۖNo||||{{{KKKKKKyyypppohbοοοο-*'-*'ohb𕌉pppۖRw&V%S||||||LLLKKKyyypppohbοοοο-*'-*'ohb𕌉pppݖά2_rŐJq=_||||||LLLLLLzzzpppohbοοο-*'-*'ohb𕌉pppݖ&V^@jiŠ3_bt}}}|||LLLLLLzzzpppohbοο-*'-*'ohb𕌉pppݖ;eJrQwD0]d$T~}}}}}}MMMLLLzzzpppohbοο-*'-*'ohb𕌉pppݖxÕ:ehɊIDDMtNu5_~~~}}}))))))JJJMMM{{{pppohbο-*'-*'ohb𕌉ppp떖+Yn͎)XCDDIeŇ8dg~~~~~~111///111BBB|||pppffff::ffohbο-*'-*'ohb𕌉ppp덗*Y_ȂHqCCCCD)Ykȋ'V~~~~~~~~~}}}}}}|||pppffff::ffohb-*'-*'ohb𕌉ppp>>;;;???\\\pppohb-*'-*'ohb𕌉pppDOO? ? ? ?8d{{{JJJ;;;GGGpppohb-*'-*'ohb𕌉pppK @<<<<<<<<EDn>>??8d~ޜMpppohb-*'-*'ohb𕌉pppNF99999999 ?MM~Cm>>>H2_𜜜pppohb-*'-*'ohb𕌉pppNN 844444445L;f @=> A`̓N𛛛pppohb-*'-*'ohb𕌉pppNL 4...... 3M2_== B}ޙOpppohb-*'-*'ohb𕌉pppLM1^:++++ 5Lx==NߜOpppohb-*'-*'ohb𕌉pppdʆܰ%S@?F/\쭕 A B_c΅Mpppohb-*'-*'ohb𕌉pppMqΐˁ㝛p3`p̑4aNpppohb-*'-*'ohb𕌉ppp+[ަխvٔ8dNpppohb-*'-*'ohb𕌉pppLL Q(X)XPMpppohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉葑ohb-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb𕌉䏏ohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉ppppppohb-*'-*'ohb𕌉ppp4Q*d4j7i7[0C"pppohb-*'-*'ohb𕌉ppp$D2V=fHrPwTuRlJR8!3`1FKNPQQPMJx>= pppohb-*'-*'ohb𕌉ppp%Y?amu|wnmggT k+GKNPQQRSSRQNJx>$pppohb-*'-*'ohb𕌉ppp(kMpu}zb^ ~;GKLKJKLNPQSTSQLG= pppohb-*'-*'ohb𕌉ppp^@\ooi >GIHFDHMP R T V W S T UTPI@"pppohb-*'-*'ohb𕌉pppxRam~xc|9EFDAADr5LORTU[" W V V V UQKpppohb-*'-*'ohb𕌉pppN3|Vco}i-l)DDB?@EJw;RVY[!\"b(^] [ Y X VQGpppohb-*'-*'ohb𕌉pppgD|Vcn~u d\CC@=?EL R~BY ]#a&d(e)k/hfb_\ Y WPN-pppohb-*'-*'ohb𕌉pppqJ{Tbl ~r/q-A@>>EL T\ Ja'f+j.m0o1u7splgb] Z VNpppohb-*'-*'ohb𕌉pppxQ_jw t A@>>DL V_gVj1q5v9y;z<~A"{upic] Y Tpppohb-*'-*'ohb𕌉pppuMZfrzz} y~D??BL Xdo yf{> D H J JO3-%zrib\ V ^9pppohb-*'-*'ohb𕌉ppppH}Vbhvrv ª _1?@BM \iv'0(yOUY\[_I̡@ș5‘* }sh_ Y {Kpppohb-*'-*'ohb𕌉pppwO\fiyqrz Ȳ ι)̹/R=@EP^lz+8”Dʟ9` h$o%r$p(r`ײUѪH˟9Ĕ,!}sg [Upppohb-*'-*'ohb𕌉pppqI}Vafgysw ˵+:CPFGT]mv*8EřQͣFē's.~2436nڹcԮT̢EÕ6)zpeXpppohb-*'-*'ohb𕌉pppwN[cc[b}zʵ':P_[XW`k{| ~GKVd'u18Ž=ǖ@̜?͞<ʙ4*{ eP$g2&vlbpppohb-*'-*'ohb𕌉pppoF{S]b]zSxS ůѾ5PͼPcGo1bkx.×9Z^#o.8?ʙDϡGҨGԪEҨ>̜4(r>QΥ;ŕ,!{q`pppohb-*'-*'ohb𕌉pppsJW^^}VpIgAíϼ/J/^ d igsv5ɟJЪUϩ*p'v2<ǕCΡIөK֯KرI֮CФ8œ[ͤsܼ[ӬCɛ1%ulOpppohb-*'-*'ohb𕌉pppvNY]YqKa;Z4d?g[ p^f m i v Ř9ͥPӯeٹoں:4?˛FѧL֯OسOٴJװDѥsۺ|bֱH˟5'{pppohb-*'-*'ohb𕌉pppnFyQZ[xRkF`:b:f=g?mEsKxQX_f n uyCV ɝ;ϩTճiۼ|ŅIʜ?͠HԬRٳV۶TڵM֯Ǥٕe׳L̢8)(~pppohb-*'-*'ohb𕌉pppoG{RYWsMlGd<e<g?lDrIwO~V]e m v~'ĕˠ;ѫT׵kܽ~ǏЗWծG֮TٵY۷Vٴϰޥٕ~d׳L̢7)1jLpppohb-*'-*'ohb𕌉ppppH{SW~Y~YzSa:e=iAoFtLyR[c l u~$Tfț͢2ҬQ׶jܿ~ȐѝؤbܺMٴVٵԶݢؐzaձIʠ4=[Bpppohb-*'-*'ohb𕌉pppqI{SZmZgAc;f>jBpHa _i s }&.6+Σ'ӬJ׶dܿ{ȍЛצݫkմۛՉsܼ[ҬBǜ<\]+kEpppohb-*'-*'ohb𕌉pppqI{UtnkFd<d<e>` zSyR[e o z%/ū9ʱAOʢҫ;׵ZܽrƅΕՠڨެߧܟؑh׵OͥCǝayEnGnFpppohb-*'-*'ohb𕌉pppvPvgebb:kEptM~V`k v",Ū7˳BкLӾT^,̤"׳Fڻdyˋҗןڤܥܣ۝דуoٺWЫQʣuI[ vNsKpppohb-*'-*'ohb𕌉ppp݆bstMnFf>c;iBkDpHxQZe p |(è4ʱ@йKԿT]eg`ŕ4ڻJܽgẏѐԖ֗֔Ӌmٺ]ԱmęA~g |U{Spppohb-*'-*'ohb𕌉ppp`rsMnEf=d;f>xRvP{T^j u".Ȯ:ζFӽQ[dlrt|̤_cmx}zrqܿ|̪ŲJ2q `}Xpppffff::ffohb-*'-*'ohb𕌉ppp_lhkCe=d;e=e uP}Wb n z&ĩ2˳?ѺLWajpw}ڂׂ{ɏ˞̩ͧˤƘnّrUƭ7{i\pppffff::f:ohb-*'-*'ohb𕌉pppa eklGf@d=tNvwSYf r (ǭ5͵CҼOZdmu{ف܅݇܇ۆ؃~xqi^ҼRݐyZ̶>!r ` ppp::ې::f:ې::::fff:::::ې:ff:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::::fې:fff::::ff:::fې::f::ې::ې::fff:::fff:::ې:ffff:::ې::ې::::ېfې::f:f:f:::ې::fohb-*'-*'ohb𕌉ppp^ac`abl p[i v!*ɯ8ηDӾQ\fow}ڃ܇݊݋܊ۇك~wmbԾSq`ѽB%{ pppf:::ې:::fې::ې:::::::ې:::ff:۶f:fې:::::ې:ې:::::fې:ې:f::ې:ې::f:ې::ff:۶f:::ې::fې:ې:::ېf::::ې:f::ې:ېf:ff:۶f::ې::ې::ې:::ې:ېf::::f:::ې:ې::ې:::ې:f:ff:۶f::ff:۶f:::f:::ېf:::ې:ohb-*'-*'ohb𕌉ppp}W~W{TwOyS}Vdx{tx"è*ɰ8ϷEӽQ]gow~ڄ܈݋ލ݌܉څ׀xocT؄bHì*ypppff۶::fې:::ې::::::ې::::ې::f:f:::::ې::ې::::ې::::::::ې:::f::ې::f:۶::ې::ې::::::ې::::ې::ې::::ې::ې::f:۶::ې::ې::::ې::ې::ې::ې::::ې::ې::ې::ffff::ې::f:::::f:::fffff۶ې:fohb-*'-*'ohb𕌉pppzT xRvPrKtMzT`q )~#è*ʰ6ϷCӽP\fow~ل܈݋ݍ݌܊چ׀yocTihKDz/~pppff::ې::::ې::::::::ې::f:۶::::::ې::::ې::::::::ې:::f::ې::f:::ې::::::ې::::ې::::ې::ې::f:۶::ې::ې::ې::ې::ې::ې::::ې::ې::۶ffff::ې::f:::::f:::f:f:f:f:ohb-*'-*'ohb𕌉ppptLtLqIsKyR_n6#ç*ɯ3ζ@ҼMYdmu|؂ۇ܊݋݋܈ڄwm`[̵A`qUƲ8$pppff::ff:::ff:ff::ff:۶fff::ff:ff:ff::::::::ېff۶::ff:۶fffff::::ې::ff::::ې::۶ff:۶f::ېf:ېf:ff::ې:::fff::ې::ffff::۶ff:۶f::ff:۶f:::ې:fې:fffohb-*'-*'ohb𕌉ppprJsJsJuL{T_p )͸Dĭ?"(Ƭ0ʹ<ѺHU`jryلۇ܈܇ۅف{shtԉw4b=rkpppff::ې::ې::ff::ې::ې:f::::ې::ff::::::f:::ff::ې:f::ې:::::ې:::ې:::::ې::ff:::f۶f:f::ې:ff:::۶ff::ې::ې:::f:fې:ې::f:::f:::fېfffې:fې:ohb-*'-*'ohb𕌉ppptMrHuKxNWbr !ʴ4J͸J[ϺP˱7ϷBҼNZdmtzقڃڃف|uma֋сҾ_/$pppp:fېff::::::::::::::::ې::::::::ff::::f::ohb-*'-*'ohb𕌉pppsKuKzPYeuʴ-Ѿ=MV+Ƭ2ӿSdԾT]fmtx{||yuneYz~ϺY)}pppp:ې:::::::::::::ې::::::ې::::ې:::::::ff:::::ېffohb-*'-*'ohb𕌉pppvL|RYhw«̸-:FNмH^nʲ<һIS\djorsrojd[S\{gŭJ:yppp::::::::::ې::ohb-*'-*'ohb𕌉ppp{T |QZiyưκ/=EOX^rɱ>Ϸ@ҼHQX_cfgfc_YRҽHՇqӾ[ȱL-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞ A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*%%%C0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'olj(,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝omiya@=4$ .+(.,*cbadmBFZ/-+.+(544uTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'D1P:EDDtqsl-2.0/apps/help/tqslapp/secondarycertops.htm0000664000076400007640000000141012231073120022011 0ustar rmurphyrmurphyTQSL Secondary Callsign Certificate Operations

Secondary Callsign Certificate Operations

tqsl-2.0/apps/help/tqslapp/savestnl.bmp0000664000076400007640000005252212231073120020261 0ustar rmurphyrmurphyBMRU6(T  @@ ff&':;bbbFG¶VXrtº23NO^_~¾npz|..BDfjRSbfJKZ[vx67*+bb"">?jl= =(== =(== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(== P == =(==(M(M (M = =(==(M(M (M == =(==(M(M (M = =(==(M(M (M == =(==(M(M (M = =(==(M(M (M == =(==(M(M (M = =(==(M(M (M == =(==( ( ( = =(==((  ( == =(==(( ( = =(==( ( (  == =(==(( (  = =(==(( (  == =(==( ( (  = =(==( ( ( == =(==( (  ( = =(==(M(M (M == =(==(M(M (M = =(==(M(M (M == =(==(M(M (M = =(==(M(M (M == =(==(M(M (M = =(==(N(N (N == =(==O(O( O( = =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(== (( = =(==  == =(=== =(==== =(=== =(==  == =(==  (( = =(==  (( == =(==  +((d( = =(==  +((d( == =(==  ((((((((((d( = =(==  ((((((( ((((((((((((d( == =(==  ((((( (((((((((d( = =(==  (((((((((((((d( == =(==  (((((((((((((d( = =(==  (((((( ((((((( ((((((d( == =(==  (((((((((((d( = =(==  (%((d( == =(==  (("((d( = =(==  (( == =(==  (( = =(==   == =(==  = =(==== =(=== =(==== =(=== =(==  !== =(==     = =(==    $== =(==    = =(==     == =(==     = =(== !== =(==  7= =(==  7== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(== (( == =(== ( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== M( (( (( = =(== L("(((( == =(== L("(((( = =(== ((( (((((((((((((((((((((((( == =(== ((((((((((((((((((( ((((((((((((((((((( (((( = =(== ((((((((((((((( ((((((((((((((((((((( == =(== (((((((( (((( ((((((((((((((( (((((( = =(== (((((((( ((( ((((((((((((((((((( == =(== (((((((((((((( ((((((((((((((( (((((( = =(== (((((((((((((((((((((((( (((((( == =(== (((( ( (((( (((((((((((((( = =(== (( ( (( (((((((((((( (( == =(== ((( = =(== ((( == =(== ((( = =(== ((( == =(== )( ((D(( = =(== (("((C(( == =(== (("((C(( = =(== (((((((((((((((((B(( == =(== ((((( (((((((((((((((((( ((B(( = =(== ((((( (((((((( (((((((((B(( == =(== ((((( ((((((((((((( ((((B(( = =(== (((( ((((((((((((((((B(( == =(== ((((( ((((((((((( ((((B(( = =(== (((((((((((((( ((((C(( == =(== (((((((((((((C(( = =(== (((((((((((D(( == =(== ((( = =(== ((( == =(== ((( = =(== ( == =(==  = =(=== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==\ \== =(==[     \= =(==[     \== =(==`   \= =(==^     \== =(==\    \= =(==[]== =(==[ #: m= =(==\ #; j== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(==+= =(==+== =(==+= =(== == =(== = =(==  == =(==  = =(==  == =(== = =(==== =(==  %$ = =(==   $ == =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(==== =(=== =(===#===================2= =========0======---9= =(==   ***77'77'7'':::88$8$$$666 6 ;%;%;%%;% 2,,,,3333 99/>>>>44"4"""""555 # 00 11< < ? ? ? ? & & &=== =(== ***7 '::::8888$8$$66 6 ;%;;%;%  2 ,, ,,33333//9/9/9/++>>>>444"4""55##55### 0011!1<1< < ? ?? ? ? & &&  == =(==   * *77 7'':: 8$$$6 66 ; ;%;;%;%2222,,,,3333 9//9//>>>>> 4444"4""4""55##5##000111<1< << < ? ??.? ? ?  & &= =(==    **777 '::88$$66 6 ;; ; %%;;%;%%%222 , ,3,3333 9/9/99/9+>>> 44"4""5#5#5##00000 11<1< < ? ?? ? ?? & &&&( = =(==   ((*((*((((*((((7('((( ((:((:((:(((((8(((66( ((6 (( (( ;(;;((%%((;%;%%%222 ,,,,333399/99//++>>>>>44"4"4""55#5#5###000111<1< < ? ? ?? & & &&&( ! = =(==   ((*(*((((77 ((77'((''(('( ((::((:(((:((((88((8$$(($((((((6((6((6 (( (( (;((;;((%((;%((%%2222, ,,,3333 //9/9/9/>>>>444"4""4""5#55##00001111!1< < ? ?? ? ? && ( .  . = =(==   ((*( **((*((((7*((77'((''(('((((((::((:((((((((8(($1(($$((((66((6 ((66(( (( (( ;((;((;%((;%;%%%22 ,,,333/99/9//+>>>>>44"4"44" """5555##5###0000111 <1<1<1<< << < ? ? ?.? ?? & && ( &   = =(==  (*((*((((((77''(''(('(::((:((((:((((88((8$$(($8$$((((((6( (( ((;((;;((%((;%((%22 ,,,33 /99/99/++>>>444"4""55###0000 11< < ? ? ? & &  ( = =(==   ((((*((*((*((((7'('(('((((::((:((:((((8((8(($(($$((((666((66(( ((;((;;((;((;%((%;%;%%  2,,,, 39/9//>>>44"4"555 #  0 1 <1<1<< << < ? ? ? ?  & &&(==== = =(==    ((*((*((*((((7(''7''((((((:((:(((((((8((8,$$(($8$$((((6((6((6((6 (( (( (( ((;;((%(%((% 2 ,,,,3333 //9//9++>>> >>>>>44"4"555##55# 0 1<1< << ? ? ?.?  &&& (-- = =(==  (**(*((((**((((7(('77((('((:((::( (((($8((88$((6(66( (( ;( ;;((%((;;;%22 ,,3333 // ++>>>> 4444 "55##55# 0011<1< < ? ?? ?  ? & ()) = =(==   *(*((((7 ((7''(('7((''::((:::888$$8$$(($$$$$66  6 66 6(( ; ; %;%;%;%%22 ,,3333 /99/9/++>>>>44 "55#5#00011!<1<1< ? ? & & ( = =(==   ((*((**((77( 7'(('':':((:((::88((8$$666 6(( ((; ; ; %;;;%;%%%2222,,, ,3,3333399//9//+>>>>44"44"""555#5#5###000011<1< < ? ?? ?. ? ??  &&( = =(==   ****77'77'7'7'::::::888888$$8$$ 66666 6 6 ; ; %;%%;;%%2222,,,3339/9 /9/++>>>>>4"4"4""55#5##0000111<1<1< << < ? ? & &&(  = =(==    ***77''7'77''::::88$8$$$66 6 ; ;%;;%%222,,,,3339/9/9/9//+>>>>44"4""555#55##00011 <1<1<< << < ? .?? ?? ? & &  (  == =(==   ****777 ''7'''''::::8888$8$ $$6666 6 ;; ; %;;%%;%%%222,,,,,33339999/9/9>>>>4""4""555##5##000011<<1< < ? ? ? && &&(= =(==  * 7''7''7' :: 8$  6 ;%;% 2  , 3 9// >  4 " 5 #  0  1 < ? & & && == =(==    *  7''7'  :: 8 $$6 ;%;% 2 ,, 3 9  >  4 " 5 # 0   1 < ?  & &  === =(== =(== =(( ==tqsl-2.0/apps/help/tqslapp/save.htm0000664000076400007640000000315312231073120017366 0ustar rmurphyrmurphySave Certificate

Save Certificate

When you select a certificate and choose the Certificate menu Save command, you save the selected certificate and its private key to a PKCS#12 file. That file can be loaded into TQSL later using the Callsign Certificate menu Load Callsign Certificate from File command. (PKCS#12 is a standard format for containing digital certificates, so the saved file can also be loaded into other PKCS#12 compliant systems, such as Microsoft Windows.)

You will first be presented with a file selection dialog, allowing you to specify the name of the file to save to.

Once you have chosen the file, you specify the password that will be used to protect the PKCS#12 file.

It's wise to protect the file with a password. If you do not, anyone who gains posession of the file will be able to use the included certificate and private key to create digital signatures using your identity. You can choose not to use a password, but you are responsible for keeping your private information private!

Note: If the private key for the certificate you are saving is password protected, you will have to supply the password to unlock the key so it can be saved in the PKCS#12 file. If needed, you will be prompted to supply the password.

Note: The saved PKCS#12 file contains only a single certificate. If you have more than one certificate, you should save each one to a separate PKCS#12 file.

tqsl-2.0/apps/help/tqslapp/replaced.bmp0000664000076400007640000000206612231073120020177 0ustar rmurphyrmurphyBM66(   llllllllllll lllxxxlll.........llllll>>>>>>lllIIIIIIIIIlllooolllmmmlll ......>>>>>>>>>IIIIIItqsl-2.0/apps/help/tqslapp/renewing2.bmp0000664000076400007640000220754612231073120020334 0ustar rmurphyrmurphyBMf 6(s0 ~xs`ZWRMJ/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)B>/-+οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾ɡ/-+-*'˽˽̾̾-*'-*'ञohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb˽˽̾̾-*'-*'ohbohb˽̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb𸵰һQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<YgUcUcUeUfUfTgTgThTjSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiThThThUgUgUfUdUdYh>-*'-*'VL֤ }LVפYܩKVƃVܩK€ۧKVSO~NNNԤNNԤRҫLMPNPեLQJԣ儾NͬOKRԣ䃽L˭PͨRHԣĄJăz٧P}ĆxݥTE͜;IWIWIWIWHWHWGYEZE\E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E\E\E[GZHXHXIXIXIXIX;-*'-*'WڦILU֤UڧIYօKRNץƂWԃU~OKLOӡNLϬNNӣNNԣڧL憿PNLNLLN~MQӢKMHاNL˫PHÃ~ăJĆz}UҡF֤N 9=M=M=M=N=O=O=O=O=O=O=Q=QA/8(/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)D<.QH8l`JuhP{mTcGV>B0/,)1/-󢟝1/-/,)LD4h]GocLZAB0ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ碟KC3eZFI5-*'ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳޢ-*'NE5=,0.,ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳ.,*A:-ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾ӡ-(-*'-*'-*'ߢohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'Ϳohbohb-*'-*'Ϳohbohb-*'-*'Ϳohb뺺ohb-*'-*'ͿͿohb랞ohb-*'-*'ͿͿͿohb뎎ohb-*'-*'ͿͿͿͿohb|||vvvvvvxxxohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohb돏Ŀohb-*'-*'˼˼˼˼ohbuuuohb-*'-*'˼˼˼˼ohbsssohb-*'-*'˼˼˼˼ohb{{{ohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ̾-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿ̾-*'-*'ohb𕌉䏏ohbͿ̾;-*'-*'ohb𕌉uuuuuuohbͿ;;-*'-*'ohb𕌉ppppppohbͿ̾;̽-*'-*'ohb𕌉ppppppohbͿ̾̽̽-*'-*'ohb𕌉ppppppohb̾̽̽˼-*'-*'ohb𕌉ppps:q8s9s:t:t:t:s:q8r:pppohb;̽˼˼-*'-*'ohb𕌉pppr8u;~@FOV\^^\VOF@u;r9pppohb̽̽˼˼-*'-*'ohb𕌉pppp7t9DSdlqsuvwvtqleSDu9q7pppohb̽̽˼˼-*'-*'ohb𕌉pppp6v:GYmppqsuwyyxvtrqqnZGv:p6pppohb̽˼˼ʻ-*'-*'ohb𕌉pppp6~?Rfklmpruwyz{zxvsqnmlfR~?p6pppohb˼˼ʻʻ-*'-*'ohb𕌉ppps8C^hghkmpruw{|}|yvsqnlihi_Cs8pppohb˼˼ʻʻ-*'-*'ohb𕌉pppr8G]ecehjjjmoqsuvtqpmkjkifdf^Hr8pppohb˼˼ʻʻ-*'-*'ohb𕌉ppps8F`a`behicԨxժ{֫{׫{ج{٬{ج{ج{׫{֪{ժ{ԩ{djifcabbGs8pppohb˼ʻʻʻ-*'-*'ohb𕌉pppp6AY^]`beghbdihfca^_ZBp6pppohbʻʻʻʻ-*'-*'ohb𕌉pppp5{=W[Z\_adfg_bhheb`][\X|=p5pppohbʻʻʻʻ-*'-*'ohb𕌉pppt9JZWY[^`cef_̟p͡rѭѭ̡r̠r_gfda_\ZX[Kt9pppf:ېohbʻʻʻʻ-*'-*'ohb𕌉pppo6ATTUXZ]_bdfeder%Ȼt)eeegec`^\ZWUVBo6ppp::ohbʻʻʻʻ-*'-*'ohb𕌉ppps8LTRTWY\^`befiis%ȼu)iihfdb_]ZXUSUMs8ppp:::f:::fې::ې:::fohbʻʻʻʻ-*'-*'ohb𕌉pppp6|>RPQSVXZ\_acefgq%ȹs)ggedb`^\YWURPS}?p6ppp:ff::ff:fې:f::::ې:ffohbʻʻʻʻ-*'-*'ohb𕌉ppps8FOMPRTVY[]_acdep%ȸr)eedb`^\ZXVSQOPGs8ppp:ې::ې:ff::ې:::fې::ohbʻʻʻʻ-*'-*'ohb𕌉pppw;MLLOQSUWY[]_`bbo%ȷq)bca`^\ZYVTRPMMNx;ppp::۶:fې::۶:fېfff:::::ffohbʻʻʻʻ-*'-*'ohb𕌉pppo4{=MLLMOQSVWY\_abao%ȵq)`a_^\ZYWTRPNLLN}>o4ppp::ېf:::ېf:۶fff:::f::ffohbʻʻʻʻ-*'-*'ohb𕌉pppo6@QS UY]di"m&p(t,w.z2~6ŀ8ŀ8Nӻ~@omf`ZXVUSQNMLLL@o6ppp:ې:fې::ې:fې::fې::f::fې::ohbʻʻʻʻ-*'-*'ohb𕌉pppp6J h(m/o1q4s5t6u6w6w6y6z6{6{6}6|5MXŃ?Ń?ĄAŇG>t-cUQOMLLLLBp6pppf::::fېf::::fېfffffې::ې:fې:ohbʻʻʻʻ-*'-*'ohb𕌉pppp6Or6u:u:u:u:u:w:x:y:z:{:|:}:~:}:QT}9~:}:}:~=CMT~Et6c!UMLKBp6ppp::::fې:f:::ې:ې:ohbʻʻʻʻ-*'-*'ohb𕌉pppp6Ru;w>w>w>w>w>x>y>z>{>|>}>}>~>~=TX~=>~>}>|>|>z>z>|C~GJIx>d!MBp7pppohbʻʻʻʻ-*'-*'ohb𕌉pppp7Uy@{B{B{B{B{B{B{B|B}B~B~B|@}A|?X\ABBB~B}B|B{B{B{B{B{B{COV_(q7pppohbʻʻʻʻ-*'-*'ohb𕌉pppq7U{C}F}F}F}F}F}F}F}F~FF~EyAܿۿƯ_FFFFF~F~F}F}F}F}F}F}F}FMf2r8pppohbʻʻʻʻ-*'-*'ohb𕌉pppr8R}FKKKKKKKKKKJ{EÒeJKKKKKKKKKKKKKRa+t9ppp::ffff::::ohbʻʻʻʻ-*'-*'ohb𕌉pppr8M|GOOOOOOOOOONJĕiNOOOOOOOOOOOOOTX!t9ppp::f:ff::::ohbʻʻʻʻ-*'-*'ohb𕌉pppG zESSSSSSSSSSSQڽ۾ڽڽڽڽڽڽճ^SSSSSSSSSSSSSSWLppp::ې::fې::f::fff:::::ېfff:::::ې:::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې::::f:::f:f::ې::fff:::ې::fې::::f::ohbʻʻʻ˼-*'-*'ohb𕌉ppp|@vAWWWWWWWWWWWVVVUUUUUUUVWWWWWWWWWWWWWWRCppp::ff::ېf::::f:ې::ې:::ې::ې:f:::::ff:f:::ې:ې::ې::ېf:::::fې::ې:::::fff::f:::ې::ې:::f:::ې:ېf:ff::f:ې::ff:۶f::f:ff::f:::ffېf::ې::۶ff:۶f::ohbʻʻ˼˼-*'-*'ohb𕌉pppz=_'Î^\\\\\\\\\\\\\Œ[Y`řrřraXŒ[\\\\\\\\\\\\\œei4|>ppp::::ې::ff۶:::f::::ې::ffff::ې::::ې::::::ې::ې::ې::ff۶::fې:::ې::::::::::::ې::ې::ې::ې::::ې::ې::ې:::::f::::f:۶:::f::::::ې::ې::ff::ې::f:۶::ohbʻʻ˼˼-*'-*'ohb𕌉pppy;FÒdÐ`Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_[jk[Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Ï_Đ`ˠxI {=ppp::ff۶::ff:::f::ې::۶ffff::ې:::::f::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:f:::f::::f:۶:::f:f۶::::ې:::fff::ې::f:۶::ohbʻʻ˼˼-*'-*'ohb𕌉ppp}?r<ǕgƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƒdfgƒcƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdƓdənP@ppp::ff۶::f:ff۶::ېff۶::ffffff::ې:ff:ff:::fff::ې::f:ff۶::ff:::ff::fff:::f::ې::ې::ې:::fff::۶ff::::ېff۶:fff:۶f::ېffff:::f::ې::ff::f:ff::۶ff:۶f:fohbʻ˼˼˼-*'-*'ohb𕌉ppp}>TdǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhƔgˣˤƓfǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhǕhƛr[@ppp::::ې::::f:::ff::::ې:f:fې:ff:::ff::ېff::ې::ې::::ې::ې::ې::ffff::ې::ff:ff:::f:۶ff::ې:ې:::ېf:::ff::ff:ff:::ff::ې::ff:ff:::ې::ې::f::f::ffohb˼˼˼˼-*'-*'ohb𕌉pppEp;͟vʘlʘlʘlʘlʘlʘlʘlʘlʘlʘlɗkЫѬȖjʘlʘlʘlʘlʘlʘlʘlʘlʘlʘlϤ}{HHppp:::f::::ې::::ې::::f:::::f:ohb˼˼˼˼-*'-*'ohb𕌉pppH R×mΡy˛p˛p˛p˛p˛p˛p˛p˛p˛p˛oΤΥ˚o˛p˛p˛p˛p˛p˛p˛p˛p˛pϢzȠyWJ ppp:f::::::ې::::ې::::::ې::۶:fې::::::ې:::fېohb˼˼˼˼-*'-*'ohb𕌉pppRf-ɟyϡyΞtΞtΞtΞtΞtΞtΞtΞtΞt͝sٵٶ͝sΞtΞtΞtΞtΞtΞtΞtΞtΞtТzͧl3Uppp::::::ې::ffffohb˼˼˼˼-*'-*'ohb𕌉ppp\ yEհҥϡxϡxϡxϡxϡxϡxϡxϡxϡxϡyز¨éسϡyϡxϡxϡxϡxϡxϡxϡxϡxϡxҦ״}J_#pppohb˼˼˼˼-*'-*'ohb𕌉pppf,SҰխѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}Ѥ}ѥ}֭ճZi/pppohb˼˼˼˼-*'-*'ohb𕌉pppp8RִڶӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧӧڵظXs;pppohb˼˼˼˼-*'-*'ohb𕌉ppp}JS̩۷֬ժժժժժժժժժժժժժժܷ֬ϬWLpppohb˼˼˼˼-*'-*'ohb𕌉ppp^TƟw׹Ȱ޼د׭׭׭׭׭׭׭׭׭׭د޼ȰغȢzX_pppohb˼˼˼˼-*'-*'ohb𕌉pppefɣ|ٽι˴©߾߼߻߻߼࿣éʳ˳׹ʥ}jgpppohb˼˼˼˽-*'-*'ohb𕌉pppǢ{Ğt˨ԵèʲѼӿҽ˳Īն̩ƠvȤ}pppohb˼˼˽˽-*'-*'ohb𕌉pppбϯбӴԷԷӵѲѱѲpppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉葑ohb˽˽˽˽-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb˽˽˽˽-*'-*'ohb𕌉䏏ohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉ppp4Q*d4j7i7[0C"pppohb˽˽˽˽-*'-*'ohb𕌉ppp$D2V=fHrPwTuRlJR8!3`1FKNPQQPMJx>= pppohb˽˽˽˽-*'-*'ohb𕌉ppp%Y?amu|wnmggT k+GKNPQQRSSRQNJx>$pppohb˽˽˽˽-*'-*'ohb𕌉ppp(kMpu}zb^ ~;GKLKJKLNPQSTSQLG= pppohb˽˽˽˽-*'-*'ohb𕌉ppp^@\ooi >GIHFDHMP R T V W S T UTPI@"pppohb˽˽˽˽-*'-*'ohb𕌉pppxRam~xc|9EFDAADr5LORTU[" W V V V UQKpppohb˽˽˽˽-*'-*'ohb𕌉pppN3|Vco}i-l)DDB?@EJw;RVY[!\"b(^] [ Y X VQGpppohb˽˽˽˽-*'-*'ohb𕌉pppgD|Vcn~u d\CC@=?EL R~BY ]#a&d(e)k/hfb_\ Y WPN-pppohb˽˽˽̾-*'-*'ohb𕌉pppqJ{Tbl ~r/q-A@>>EL T\ Ja'f+j.m0o1u7splgb] Z VNpppohb˽˽̾̾-*'-*'ohb𕌉pppxQ_jw t A@>>DL V_gVj1q5v9y;z<~A"{upic] Y Tpppohb˽˽̾̾-*'-*'ohb𕌉pppuMZfrzz} y~D??BL Xdo yf{> D H J JO3-%zrib\ V ^9pppohb˽˽̾̾-*'-*'ohb𕌉ppppH}Vbhvrv ª _1?@BM \iv'0(yOUY\[_I̡@ș5‘* }sh_ Y {Kpppohb˽̾̾̾-*'-*'ohb𕌉pppwO\fiyqrz Ȳ ι)̹/R=@EP^lz+8”Dʟ9` h$o%r$p(r`ײUѪH˟9Ĕ,!}sg [Upppohb̾̾̾̾-*'-*'ohb𕌉pppqI}Vafgysw ˵+:CPFGT]mv*8EřQͣFē's.~2436nڹcԮT̢EÕ6)zpeXpppohb̾̾̾̾-*'-*'ohb𕌉pppwN[cc[b}zʵ':P_[XW`k{| ~GKVd'u18Ž=ǖ@̜?͞<ʙ4*{ eP$g2&vlbpppohb̾̾̾̾-*'-*'ohb𕌉pppoF{S]b]zSxS ůѾ5PͼPcGo1bkx.×9Z^#o.8?ʙDϡGҨGԪEҨ>̜4(r>QΥ;ŕ,!{q`pppohb̾̾̾̾-*'-*'ohb𕌉pppsJW^^}VpIgAíϼ/J/^ d igsv5ɟJЪUϩ*p'v2<ǕCΡIөK֯KرI֮CФ8œ[ͤsܼ[ӬCɛ1%ulOpppohb̾̾̾̾-*'-*'ohb𕌉pppvNY]YqKa;Z4d?g[ p^f m i v Ř9ͥPӯeٹoں:4?˛FѧL֯OسOٴJװDѥsۺ|bֱH˟5'{pppohb̾̾̾̾-*'-*'ohb𕌉pppnFyQZ[xRkF`:b:f=g?mEsKxQX_f n uyCV ɝ;ϩTճiۼ|ŅIʜ?͠HԬRٳV۶TڵM֯Ǥٕe׳L̢8)(~pppohb̾̾̾̾-*'-*'ohb𕌉pppoG{RYWsMlGd<e<g?lDrIwO~V]e m v~'ĕˠ;ѫT׵kܽ~ǏЗWծG֮TٵY۷Vٴϰޥٕ~d׳L̢7)1jLpppohb̾̾̾̾-*'-*'ohb𕌉ppppH{SW~Y~YzSa:e=iAoFtLyR[c l u~$Tfț͢2ҬQ׶jܿ~ȐѝؤbܺMٴVٵԶݢؐzaձIʠ4=[Bpppohb̾̾̾̾-*'-*'ohb𕌉pppqI{SZmZgAc;f>jBpHa _i s }&.6+Σ'ӬJ׶dܿ{ȍЛצݫkմۛՉsܼ[ҬBǜ<\]+kEpppohb̾̾̾̾-*'-*'ohb𕌉pppqI{UtnkFd<d<e>` zSyR[e o z%/ū9ʱAOʢҫ;׵ZܽrƅΕՠڨެߧܟؑh׵OͥCǝayEnGnFpppohb̾̾̾̾-*'-*'ohb𕌉pppvPvgebb:kEptM~V`k v",Ū7˳BкLӾT^,̤"׳Fڻdyˋҗןڤܥܣ۝דуoٺWЫQʣuI[ vNsKpppohb̾̾̾̾-*'-*'ohb𕌉ppp݆bstMnFf>c;iBkDpHxQZe p |(è4ʱ@йKԿT]eg`ŕ4ڻJܽgẏѐԖ֗֔Ӌmٺ]ԱmęA~g |U{Spppohb̾̾̾̾-*'-*'ohb𕌉ppp`rsMnEf=d;f>xRvP{T^j u".Ȯ:ζFӽQ[dlrt|̤_cmx}zrqܿ|̪ŲJ2q `}Xpppfff:ېohb̾̾̾̾-*'-*'ohb𕌉ppp_lhkCe=d;e=e uP}Wb n z&ĩ2˳?ѺLWajpw}ڂׂ{ɏ˞̩ͧˤƘnّrUƭ7{i\pppff::ohb̾̾̾̾-*'-*'ohb𕌉pppa eklGf@d=tNvwSYf r (ǭ5͵CҼOZdmu{ف܅݇܇ۆ؃~xqi^ҼRݐyZ̶>!r ` ppp::::ې::ې::::ې::۶:fېf:fff:::::ې:::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې::::::f:::::f:::fې::ې:::fohb̾̾̾̾-*'-*'ohb𕌉ppp^ac`abl p[i v!*ɯ8ηDӾQ\fow}ڃ܇݊݋܊ۇك~wmbԾSq`ѽB%{ ppp::ffff::::ff::fې:ffffېf:::::ff:f:::ې:ې::ې::ېf:::::fې::ې:::::fff::f:::ې::ې:::f:::ې:ېf:ff::۶ff:۶f:::ff::ff:fې:f::::ې:ffohb̾̾̾̾-*'-*'ohb𕌉ppp}W~W{TwOyS}Vdx{tx"è*ɰ8ϷEӽQ]gow~ڄ܈݋ލ݌܉څ׀xocT؄bHì*yppp::ېf:::::::ې:::۶f:ff:ff::ې::::ې::::::ې::ې::ې::ff۶::fې:::ې::::::::::::ې::ې::ې::ې::::ې::ې::ې::::ې::f:۶:::ې::ې:ff::ې:::fې::ohb̾̾̾̾-*'-*'ohb𕌉pppzT xRvPrKtMzT`q )~#è*ʰ6ϷCӽP\fow~ل܈݋ݍ݌܊چ׀yocTihKDz/~ppp:::f۶:::::f:fېff۶f:f:::ې:::::f::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:f::ې::f:۶::::۶:fې::۶:fېfff:::::ffohb̾̾̾̾-*'-*'ohb𕌉ppptLtLqIsKyR_n6#ç*ɯ3ζ@ҼMYdmu|؂ۇ܊݋݋܈ڄwm`[̵A`qUƲ8$ppp::f:۶ff:::ff:ff::ff:ffff:f::ې:ff:ff:::fff::ې::f:ff۶::ff:::ff::fff:::f::ې::ې::ې:::fff::۶ff::::۶ff:۶f:f::ېf:::ېf:۶fff:::f::ffohb̾̾̾̾-*'-*'ohb𕌉ppprJsJsJuL{T_p )͸Dĭ?"(Ƭ0ʹ<ѺHU`jryلۇ܈܇ۅف{shtԉw4b=rkppp::ff::ې::ff::ې::ېf:f::ff:::ff::ېff::ې::ې::::ې::ې::ې::ffff::ې::ff:ff:::f:۶ff::ې:ې:::ېf::f::ff:ې:fې::ې:fې::fې::f::fې::ohb̾̾̾̾-*'-*'ohb𕌉ppptMrHuKxNWbr !ʴ4J͸J[ϺP˱7ϷBҼNZdmtzقڃڃف|uma֋сҾ_/$pppp::f:::ې::::ې::::f:::f:f::::fېf::::fېfffffې::ې:fې:ohb̾̾̾̾-*'-*'ohb𕌉pppsKuKzPYeuʴ-Ѿ=MV+Ƭ2ӿSdԾT]fmtx{||yuneYz~ϺY)}pppp::ې::ې::::ې::::::ې::۶:fې:::::fې::::fې:f:::ې:ې:ohb̾̾̾̾-*'-*'ohb𕌉pppvL|RYhw«̸-:FNмH^nʲ<һIS\djorsrojd[S\{gŭJ:yppp::::ې::ffffohb̾̾̾̾-*'-*'ohb𕌉ppp{T |QZiyưκ/=EOX^rɱ>Ϸ@ҼHQX_cfgfc_YRҽHՇqӾ[ȱLѸ,ͱɫƦâ <  xA@pppohbοοοο-*'-*'ohb𕌉ppp;ŭȄwgVEӺ4ϴ$ˮǨ ťâ z BApppohbοοοο-*'-*'ohb𕌉ppp3©z˽pξdѾWӽGӻ8е)ͰɫƦģâ xz y-,pppohbοοο-*'-*'ohb𕌉ppp+dò[ǵQ˵Eζ8ϵ*ͱʫǨ Ťģâ | Pz ]#"ɽA@pppohbοο-*'-*'ohb𕌉ppp"NG>Ů4ʰ(˯ʬǨ ťģģâ | n$; ))pppohbοο-*'-*'ohb𕌉ppp:4,#ũȪǧ Ťģģģâ | }iSA  pppohbο-*'-*'ohb𕌉ppp(#ť Ťģģģģâ | {h XG"( #",,pppfff:ېohbο-*'-*'ohb𕌉ppp âģģģģģâ | }hTA "$$pppff::ohb-*'-*'ohb𕌉ppp âģģģģģâ z s (^"#%% ppp::ېfff:::f:::fff:::::ې:::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې::::::f:::::f:::fې::ې:::fohb-*'-*'ohb𕌉ppp âĢģģģģâ yO ~""&& pppf:::ې:::ې::fffې:fff:::::ff:f:::ې:ې::ې::ېf:::::fې::ې:::::fff::f:::ې::ې:::f:::ې:ېf:ff::۶ff:۶f:::ff::ff:fې:f::::ې:ffohb-*'-*'ohb𕌉ppp&%"çǩǨƦ ŤŤģâ l{99..pppff۶::ې::f::fې::::ې::::ې::::::ې::ې::ې::ff۶::fې:::ې::::::::::::ې::ې::ې::ې::::ې::ې::ې::::ې::f:۶:::ې::ې:ff::ې:::fې::ohb-*'-*'ohb𕌉ppp%#"!Ĩ ɬ!ʬ ʬʬɫɪǩzMM^^.. pppff::ff:fې:f::ې:::::f::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:f::ې::f:۶::::۶:fې::۶:fېfff:::::ffohb-*'-*'ohb𕌉ppp%#" Ĩɬʬʬʬ ʬ ʬ ɬ$ʨ#zJJffXX==pppffffffffff::::ې:ff:ff:::fff::ې::f:ff۶::ff:::ff::fff:::f::ې::ې::ې:::fff::۶ff::::۶ff:۶f:f::ېf:::ېf:۶fff:::f::ffohb-*'-*'ohb𕌉ppp&$#!Ĩ ɬ ʭ ʭ ʭ ʬʬ ̬ť0zLLeeVVPPII11pppff::ېf:ff::ې:ff:::ff::ېff::ې::ې::::ې::ې::ې::ffff::ې::ff:ff:::f:۶ff::ې:ې:::ېf::f::ff:ې:fې::ې:fې::fې::f::fې::ohb-*'-*'ohb𕌉pppŦƦƦƦǨ!˭ԬT {MMggWWNN77--++  ppp:fېff::ې::::ې::::f:::f:f::::fېf::::fېfffffې::ې:fې:ohb-*'-*'ohb𕌉pppƦ"ذ { !!{MMhhXXOO99//..//..--  ppp:ې:::ې::::ې::::::ې::۶:fې:::::fې::::fې:f:::ې:ې:ohb-*'-*'ohb𕌉pppΨ !!{OOiiYYQQ99--,,++**))****))(( ppp::::ې::ffffohb-*'-*'ohb𕌉ppp1{}!!|OOjj[[PP88++))((&&%%$$##""##%%''))..11,,""pppohb-*'-*'ohb𕌉pppn%% {PPll\\QQ@@<<::;;<<>>??@@BBBBCCCCDDCCCCCCDDFFpppohb-*'-*'ohb𕌉pppm))II??""RRmm]]SSLLEEAAAAAAAA@@@@@@@@@@@@@@@@@@@@@@BBpppohb-*'-*'ohb𕌉pppo))MMPP22UUoo]]TTKKEE@@@@@@@@@@@@@@@@@@@@AABBBBCCDDHHpppohb-*'-*'ohb𕌉ppp))LLNN00YYuu__UULLEEAA@@AAAAAAAAAAAA@@??<<7722++%% pppohb-*'-*'ohb𕌉ppp++OONN22^^ffXXNNFF@@>>==;;9977553311..(("" ##%%pppohb-*'-*'ohb𕌉ppp22[[PPLL88^^ooYYLLDD==885511..----------....////////..--pppohb-*'-*'ohb𕌉ppp>>ii``ee[[NNHHFFDDAA==995511--,,,,pppohb-*'-*'ohb𕌉ppp::llffZZRRKKpppohb-*'-*'ohb𕌉ppp00ccpppohb-*'-*'ohb𕌉ppppppohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉葑ohb-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb𕌉䏏ohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉pppc%h'i(i(i(i(i(i'pppohb-*'-*'ohb𕌉pppX!h'i'i'j'j'k'k&k&l&l%k$pppohb-*'-*'ohb𕌉pppg$m&l%m%m%n%o%o$p%p#p#q#q#r#m pppohb-*'-*'ohb𕌉pppo$q$p#q#q#r#s$qt#ru#u!u!v!v!w!x pppohb-*'-*'ohb𕌉pppt"s"t"u!u!u!x% mjoy!wz zz{{{pppohb-*'-*'ohb𕌉pppw w x y yy|" tGMЯx~~pppohb-*'-*'ohb𕌉ppp{||}}{/5Ó{ pppohb-*'-*'ohb𕌉N{{aaaaaaN{{ppp!qu pppohb-*'-*'ohb𕌉Ԫppp׶SW pppohb-*'-*'ohb𕌉N{{N{{ppp ə8< pppohb-*'-*'ohb𕌉Ԫ::fې::f::ې:f:ې:ff::ې::f::f::::::ې::ې:::::fې::::ې::ې:f:::::f:::::::::::f:f:::fېpppwzԧ!vxKN!%    pppohb-*'-*'ohb𕌉aa:::ې::ffffې:f::::ې:::fې::fې:۶f::f:ې::::::::fff::::::ff:::::f::::ې:fې::::ff:ې::::ې::::ff:::fff:ff:ppp \_̑ɅBE    pppohb-*'-*'ohb𕌉N{{:::۶f:fېff::ې::۶:fې::۶:fې::::ې:::ېf::ې::::::::::ff:::ې:::::ff:fې::ې:::ې:::ېf:::ې::::ېf:::۶:fې:ې:ppp su ʁ'*eg  pppohb-*'-*'ohb𕌉mmmmmmmmmmmmmmmmmmN{{ԑ::f:::fff:::ې::::f::ې:::::ې::ې::ې::ې::::::::ffff::::۶:fې::::ff::ff۶::::۶:fې::ff::ې::::::ې::::۶:fېppp   :=[] ̀!no    pppohb-*'-*'ohb𕌉aa:::::ېf:ff::ې::fې:::::ې::ff::ې::::::ې::ffff::::ېf:::::ff::ff۶:f::ېf:ې::ff۶::ې::::ې::f:::ېf:::ېf:ppp      ~       pppohb-*'-*'ohb𕌉mmmԪ::::ې::ې:fې::۶:fې:fې::::ې::f۶f::ې::::::::::ff:::ې:fې:::::ff:fې::ې:::ې:fې::::ې:ff::ې::::ff::::ې:ې:fې:ppp   }~  pppohb-*'-*'ohb𕌉N{{::ې::ې:fffff:::ې:ff:::::f::::fې::ې:::::::::f:fېff::f::::fې:::::fېff:ې:fې:::f::::fېf::::fې:::::ې::::f::::ffff::::fېppp       {| pppohb-*'-*'ohb𕌉mmmaa::fffffې::f:ې:::ې:::::ې:::::::ff::::f:::ې::::ff:::ې:ې::ې::f:::ff:::::ې:fff::pppڏ~pppohb-*'-*'ohb𕌉N{{pppڣ ڄHHpppohb-*'-*'ohb𕌉mmmN{{N{{pppۚȝpppohb-*'-*'ohb𕌉N{{pppۧ֨pppohb-*'-*'ohb𕌉mmmppp۪՟pppohb-*'-*'ohb𕌉fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffpppݠͥtt11^^ŵpppohb-*'-*'ohb𕌉mmmN{{aaaaaaN{{f333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fppp݋ġءՌՉٙpppohb-*'-*'ohb𕌉Ԫ33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333pppݩpppohb-*'-*'ohb𕌉mmmN{{N{{f3333333333333333333333333333333Z333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fpppݺpppohb-*'-*'ohb𕌉Ԫ3Z333Z3333333Z333Z3333333333333Z3Z333Z33Z3333333333Z33Z33333Z3333333Z33Z3333333Z333Z3333ZZ33Z3Z3Z3333ppp뙙ƿpppffohb-*'-*'ohb𕌉mmmaaf3333Z333Z3333Z33ZZ333333333333333Z3Z33Z3Z333Z33Z3333Z333333333Z33Z33333Z33Z33Z3333333Z333ZZ333Z3333333333ZZ3333ZZ3333Z3333Z3Z33333Z3fppp뢢{}{pppffohb-*'-*'ohb𕌉N{{3Z3Z33333Z333333Z3333333333Z333ZZ3ZZ3Z333Z33Z3333Z333Z333333333Z33Z333Z33Z333333333333333ZZ3333333Z3Z33ZZ3333Z3333Z333333Z33ppp릦׹ppp:f:ffff:::fff:::fff::::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::ohb-*'-*'ohb𕌉mmmmmmmmmmmmmmmmmmN{{ԑf33Z333Z333333Z33Z3333333Z333Z333ZZ3ZZ3Z333Z33Z3333Z333333333333Z333Z3333Z33Z33333333333Z3333Z33333333Z33Z3ZZ3333Z333Z3Z333333Z333fppp즦տppp::ff:۶f:::ې::fې:ې::::ې::fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:ffohb-*'-*'ohb𕌉aa333Z333Z33333Z33333333333333Z333ZZ3Z3Z333Z33ZZ33333333333Z3333Z333Z33Z333333Z333333333Z3ZZZZZ33Z33Z33333333Z33ppp좢ʰ옘prpppp::::f:۶::ې::ې::::::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ohb-*'-*'ohb𕌉mmmԪf33Z333Z3333333Z33333Z3333333333Z333ZZ33Z3Z333Z33Z3333Z333Z333333333Z333Z3333Z33Z333333333333333ZZ33333333Z333ZZ3333Z3333Z3333333Z333fppp옘ϲ컻Ͻppp::::f:::ې::::::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fohb-*'-*'ohb𕌉N{{333333333333333ZZ3333333333333Z333Z33Z3Z333Z33Z3333Z33333333333Z33333333Z33Z3333333333ZZ333Z3333333333333ZZ3333Z3333Z3Z3333333ppp췷Ɲ즦}~ppp::ff:۶fffff::fff:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::ohb-*'-*'ohb𕌉mmmaaf333Z3333Z33333Z333Z333333333333Z333Z333Z33333333Z3333333Z3333333Z33333Z3333333Z333fpppĘٱppp:::f::ې::::ې::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ېohb-*'-*'ohb𕌉N{{333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333pppȥppp:::::fff::ې:::fff::f:::ohb-*'-*'ohb𕌉mmmN{{N{{f333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fppp휜ο횚ppp::::ff::ې::::ff::ې::۶:fې::::ohb-*'-*'ohb𕌉N{{333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333ppp襤°Ѱppp::::ې::ffohb-*'-*'ohb𕌉mmmffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffpppγpppohb-*'-*'ohb𕌉ppp︸pppohb-*'-*'ohb𕌉pppﹹpppohb-*'-*'ohb𕌉f:ېppppppohb-*'-*'ohb𕌉2^^Rjj::ppppppohb-*'-*'ohb𕌉㑑2Tfې::f::ې:f:f::ې::fff:::ې::ې::ې:ffff:::fې:::fې:ppppppohb-*'-*'ohb𕌉㑑2Tf::ې:fff:::ې:::fffff::f:::ې::ې:::f:::ې:ېf:ffېf::ېppppppohb-*'-*'ohb𕌉푑2T::۶:fې::ff۶:::fې::::::ې::ې::ې::ې::::ې::ې::ې::ffppppppohb-*'-*'ohb𕌉cKcKcKcKcK푑mmmmmmmmm2T::ې::ffff:::::f۶::::ې::ې::ې::ې::::ې::ې:fffppppppohb-*'-*'ohb𕌉2T::ې::ffff::f:ff:::f::ې::ې::ې:::fff::۶ff::f:ffppppppohb-*'-*'ohb𕌉2T:::fې::ff::::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې::ppppppohb-*'-*'ohb𕌉2T:::ې:fې::fېff:::fff::f:::uuuuuuohb-*'-*'ohb𕌉2T:::ې::ې:::ff::ې::۶:fې::::葑ohb-*'-*'ohb𕌉Jff""""""""Tffwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉VVzohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉󕌉ϕohb-*'-*'ohb𕌉󕌉ѕohb-*'-*'ohb𕌉TTҖvv00Ҵҕohb-*'-*'ohb𕌉UԗUww00Զԕohb-*'-*'ohb𕌉1Wؚz1WؚWz1ع1zؚWz1Wؚz1z1zz11عWWW1z11عWWW1z11عz1Wؚzz11عzz11عWz11z1عzWz1WWW1z11عWWW1z11عz1Wؚzz11عzz11عz1Wؚz1Wؚz1ؚWWWW1z11عWWW1z11عz1Wؚzz11عzz11عWz1ؕffohb-*'-*'ohb𕌉{11ڻڜWڜW1{W1Wڻ{{{11ڻ1{{1ڻڜW{1{{11ڻW{1ڻWڜW{{11ڻ{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڜW1{{11ڻ{W1ڜ{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11ڻ{{11ڻڜWڜW1{W1{ڜW{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڕffohb-*'-*'ohb𕌉{11ۼ{{11ۼ{X1X{1ۼ{{11ۼۜ1Xۼ{{{11{{11ۼۜ1X{{{11ۼ{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜۜXXۜ{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼ{{11ۼ{{11ۼ{X1{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜە:ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::fې:ohb-*'-*'ohb𕌉}22ݾ}}22ݾ}Y2}}22ݾ}}22ݾ}}22ݾݝYY}}22ݾݝ2Y}}2Y}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝYY}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾ}}22ݾ}}22ݾ}Y2}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝݕ:fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:ffېf::ېohb-*'-*'ohb𕌉55^^5ɨ^^^5555^^ɨ55Ʉ^^^^555^^^55Ʉ55^^5ɨ^5^^5^5^^^^55^^55Ʉ55^^5ɨ^5^^555^^5ɨ^5^^^55Ʉ55^^5ɨ^5^^5^5^^때:fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ffohb-*'-*'ohb𕌉555^555^ʄ55^555^^55ʄ55^^55ʄ5^^555ʄ5^쨄55^^55^^5ʄ555ʄ5^^555ʄ5^쨄55^^555^^^55ʄ5^^555ʄ5^쨄55^^55알::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fffohb-*'-*'ohb𕌉555̅5_̅5555_̅__55555555핌f:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::f:ffohb-*'-*'ohb𕌉555Ά555Ά555Ά55555Ά555555Ά55::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې::ohb-*'-*'ohb𕌉𕌉:fff::ې:::fff::f:::ohb-*'-*'ohb𕌉񕌉ff::ې::::ff::ې::۶:fې::::ohb-*'-*'ohb𕌉򕌉::ې::ffohb-*'-*'ohb𕌉򕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼ohb-*'-*'ohbohb-*'-*'ohb3~b8Z~ohb-*'-*'ohb[3߮6Y~ohb-*'-*'ohbމa2ޮ6Y}ohb-*'-*'ohbܮ6X|ܮ6X|6X|܉2[ܮX[[[3|a363X|[[6X|܉26|ܮ6X|ܮ6X|ܮXр2܉26|ܮXX3|a363X|[[6X|܉26|ܮ6X|ܮ6X|܉233|a363X|6X|6X|aa❮6X|a26X|6X|ܮ6X|܉23܉2[6X|[[6X|6X|ܮ6X|ܮXX3|a363X|[[܉2[ܮ6X|ܮ6X|܉2[6X|6X6[XXohb-*'-*'ohbڬ6W{ڬ6W{6W{W~1ڇ{2{~16W{`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{ڬ6W{ڬWWڇ`12{~1`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{`Wڇ{`ڇ2໇61{6W{6W{6~~16W{WW6~6{6W{ڬ6W{`Wڇ{W~1ڬ6W{ڬ6W{ڬ6W{6W{ڬ6W{2{~1`ڇ2໇61{6W{ڬW~1ڬ6W{ڬ6W{W~1ڬ6W{W~1ڇ`1ohb-*'-*'ohb٫6Wz٫6Wz6Wz`1ߛ6~Y6Wzه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz٫6Wzه`1ߛYW`1ߛه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz2zWه`1ߛ62zz6Wz6Wz6~W6Wzه21ߺ٫6Wz6Wz٫6Wz2zWه`1ߛ٫6Wz٫6Wz٫6Wz6Wz٫6Wz`1ߛه`1ߛ62zz6Wzه`1ߛ٫6Wz٫6Wz`1ߛ٫6Wz6Wz2zWohb-*'-*'ohb׫6Vy׫6Vy6Vy1Yׇ1V6Vy`6y6Vy׫6Vy`1ޚYV6Vy׫6Vy׫6Vyׇ`1ޚYV`1ޚ`6y6Vy׫6Vy`1ޚYV6Vy׫6Vyׇ`1ޚ`6y6Vy6Vy1}1׫6Vyׇ21޹׫6Vy6Vy׫6Vyׇ`1ޚׇ1Y6Vy׫6Vy׫6Vy6Vy׫6Vy`1ޚ`6y6Vyׇ1Y׫6Vy׫6Vy1Y6Vy6VyYVohb-*'-*'ohb֪VV5Vy5Vy5Vy`}12yV֪5Vy֪5Vy5Vy֪5VyVVֆ51yVY``ݙ֪5Vy֪VVֆ51y2y}1֪5Vy5Vy֪5VyVVֆ51yVY``ݙֆֆ21ݸ֪5Vy5Vy5Vy`֪Y֪5VyVV5}5yVY``ݙֆֆ21ݸ֪5Vy`}1V}1֪5Vy֪5Vy5Vy֪5Vy2y}1֪5Vy5Vy֪5Vy`}1֪V5y5Vy`}15VyV2ݸ51yohb-*'-*'ohbԪ5UwԪ5Uw5UwԆ0_ۗԪU{0ԪUXXXUX5UwԆ0UԪ5U_{w{0Ԫ5UwԆ0U1wUXXUX5UwԆ0UԪ5U_{w{0Ԇ_0ۗXXԪ5Uw5Uw1wU5UwԆ0{05Uw5U_{w{0Ԇ_0ۗԆ0_ۗ5U5XUX5UwU{05Uw1wUXXUXԆ0_ۗԪ5UwԪ5UwԆ0_ۗ5Uw5Uw0{0ohb-*'-*'ohbԩ5Uwԩ5Uw_ԅ1۶ԩ5Uwԩ5Uwԩ5Uwԩ5Uw1wUԩ5Uw5Uw1wUԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwohb-*'-*'ohb8\ɀ8\ɀb38\ɀ8\ɀ8\ɀ8\ɀ3\8\ɀ8\ɀ3\8\ɀ\\8\ɀ8\ɀ8\ɀ8\ɀohb-*'-*'ohb]ӄ484ʂ8]ʂbb84ʂ8]ʂ84ʂ558]ʂ8]ʂ84ʂ5584ʂb584ʂ8]ʂ8]ʂ8]ʂohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'몦rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻ˼˼˼˽˽˽˼˼˼̽̽;;;̾̾̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;̽˼˼ʻʻ˼˼˼˽˽˽˼˼˼˼̽;;;̾̾̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿͿ̾̽̽˼˼˼˼˼˽˽˼˼˼˼˼̽̽;;̾̾̾ͿͿοͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽;̽̽˼˽˽˼˼˼˼˼̽̽̽̽̾̾̾ͿͿο;Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̾;;̽̽˽˽˼˼˼˼˼̽̽̽̽˽̾̾Ϳοο;Ϳ-*'-*' οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;;̾̾˽˽˼˼˼˼̽̽̽̽˽˽̾Ϳοο;Ϳ-*'-*'aV  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿͿ̾̽˼˼˼˼̽̽̽˽˽˽˽̾οο;ͿͿ-*'-*'HwX οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾;;̽̽˼̽̽̽̽̽˽˽˽̾;;;ͿͿͿο-*'-*' %XksbPοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾Ϳ;;̽̽˼̽̽̽˽˽˽˽̾;̽̽ͿͿοफ़vqkZVQZVQZVRZVR[VR[VR[VR[VR[WR[WS[WR[WS[WS[WS[WS\XS\XT\XS\XS\XS\XT\XT\XT\XT\XT\XU\XU\XU\XU^ZW^ZW^ZW^ZW^ZW^ZW^ZW]YU_[W_[W]YU\XU\XU\XU^[W^[W^[W_[X_[X_[X_[X_[X&b&S&S&S'T(T (V!)V!*W"+X$-X%-Y%.Z'/Z'0[(0])1])1])1])1^)1])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fXa-*'-*'Cxe #PNդM۩N}ņοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾Ϳ;;̽;̽̽̽˽˽˽̾̾;;̽̾Ϳο^ZUz.<꯵ܯޮ߮୵୵⭵䭷孷嫹髹髹뫹쫹쫹쬻뫺髺髹譸孵孵䭵᭵᳹᭱͐*.O-*'-*'-.fvh#(ڧJR‚QOئKƒ}οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿο;ο;;̽˽˽˽̾̾;̽̽̾ͿͿͿο坖ƼŻŻżŻƼƽƼƽƽƽƽƽǾǾǾǾǾȿǾǾǾǾԀwqȿȿ(5r|r}p}p~p~ppppooonnlllllllllllllllllnnooopppp~p~t~ȞԘW[-*'-*' 6~je #QÂRӬOMܫO~οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾οοο;̾˽˽̾̾;̽̽̾ͿͿ̾Ϳοpjeļ;;;;ͿͿͿ¹{smºººººººûûûºººûûûûûûûüüüû#.}dpdpdqdqcrcrcrbtbvbv`v`x`y`y`z`z`z`z`z`z`z`z`z`{`{`{`{`{`{`{`{`z`y`ybwbvbvbtcrcrcrdqdqpz!&O-*'-*'-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞ A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*%%%C0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'olj(,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝omiya@=4$ .+(.,*cbadmBFZ/-+.+(544uTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'D1P:EDDtqsl-2.0/apps/help/tqslapp/renewing.htm0000664000076400007640000002066012231073120020250 0ustar rmurphyrmurphyRenewing a Callsign Certificate

Renewing a Callsign Certificate

These instructions assume that
  • your Callsign Certificates reside in the folder C:\MyLoTWCertificates (if you've stored them in a different folder, adjust the instructions accordingly)
  • you are renewing a Callsign Certificate before it expires
  • the Callsign Certificate to be renewed is named YourCallsign.tq6, e.g. K1MU.tq6

To initiate the renewal of your certificate,
1.Delete the Callsign Certificate Request file C:\MyLoTWCertificates\YourCallsign.tq5 if it's present; this original certificate request is no longer needed.
2.Navigate to C:\MyLoTWCertificates and create a subfolder there named Obsolete, if this subfolder has not previously been created.
3.Move the Callsign Certificate file YourCallsign.tq6 from the folder C:\MyLoTWCertificates to its subfolder C:\MyLoTWCertificates\Obsolete, replacing any existing file in that subfolder with the same name.
4.Move the Certificate Container file YourCallsign.p12 from the folder C:\MyLoTWCertificates to its subfolder C:\MyLoTWCertificates\Obsolete, replacing any existing file in that subfolder with the same name.
5.Start TQSL and select the Callsign Certificates tab, which lists your Callsign Certificates.
6.In the Callsign Certificates tab, click on the certificate to be renewed:
 
  and then click the Renew the Callsign Certificate button.
7.The Request a New Callsign Certificate window will appear, showing that you are creating a new Callsign Certificate Request file; click the Next button.
8.The Request a New Callsign Certificate window will now show your Callsign and DXCC entity (both grayed out because they can't be changed):
 
   8.athe QSO begin date should already be set to the begin date specified on your current certificate
   8.bfor an active callsign, the QSO end date should be remain blank; for an inactive callsign, the QSO end date should already be set to the end date specified on your current certificate
   8.cclick the Next button
9.The Request a New Callsign Certificate window will now show your name and address; make any necessary corrections, and click the Next button.
10.The Request a New Callsign Certificate window will now show your email address; make any necessary corrections, and click the Next button.
11.The Request a New Callsign Certificate window will now prompt you to specify a password; leave both password boxes empty, and click the Finish button.
12.A Save request window will appear, with the File name set to YourCallsign.tq5; navigate to C:\MyLoTWCertificates, and then click the Save button to save your new Callsign Certificate Request file.
13.A window will appear displaying text that explains how to convey your new Callsign Certificate Request file to the ARRL; click this window's OK button.
14.TQSL's Callsign Certificates tab will display an entry for your new certificate request with a pending icon:  
15.Upload your certificate request to the ARRL via https://p1k.arrl.org/lotw/upload ; use the web page's Choose File button to navigate to the folder C:\MyLoTWCertificates and select the YourCallsign.tq5 file you find there; then click the Upload file button.
16.Retain the YourCallsign.tq5 file; its presence in C:\MyLoTWCertificates will be required when you accept the certificate that the ARRL will send you, so don't delete it!
17.You can terminate TQSL by opening its File menu and selecting the Exit command (on OS X, by selecting the Application menu's Quit tqsl command).

 

When you receive email from the ARRL message with an attached file named YourCallsign.tq6,
18.Save the attached file into the folder C:\MyLoTWCertificates.
19.Start TQSL and select the Callsign Certificates tab, which lists your Callsign Certificates; in the Alert window that asks if you are ready to load your new certificate, click Yes button.
   19.athe Load Certificate File window will appear; in this window, set the type of certificate to TQSL (.tq6), and click the Next button; the Select Certificate File window will appear
   19.bin the Select Certificate File window, select the file C:\MyLoTWCertificates\YourCallsign.tq6 and click the Open button; a small Install Certificate window will appear
   19.cin the Install Certificate window, click the Finish button
   19.dthe tQSL Certificates tab will now show
       19.d.1.an entry for your renewed Callsign Certificate with a yellow medal valid icon:  
       19.d.2.an entry for your now obsolete Callsign Certificate with either a replaced icon   or an expired icon   either way, delete this obsolete Callsign Certificate by clicking it's entry and then selecting the Callsign Certificate menu's Delete Callsign Certificate command.
   19.eif you received more than one certificate file from the ARRL, then click the Load a new Callsign Certificate button and proceed to step 19a above; after all received certificate files have been processed, you can terminate TQSL by opening the File menu and selecting the Exit command (on OS X, by selecting the Application menu's Quit tqsl command).
20.To protect your renewed Callsign Certificate(s), direct TQSL to create a Backup File.

tqsl-2.0/apps/help/tqslapp/qsodata.htm0000664000076400007640000001030212231073120020056 0ustar rmurphyrmurphyTQSL Creating and Editing an ADIF File

Creating and Editing an ADIF File

TQSL includes a simple QSO Data Editor that can be used to create and edit small log files in the ADIF format. This Editor is rudimentary, intended only as a means for those who do not have access to a logging application create and edit log files. The Editor provides access to only the most critical QSO data fields:

  • Callsign
  • Date
  • Time
  • Band
  • RX Band
  • Frequency
  • RX Frequency
  • Mode
  • Propagation Mode
  • Satellite

If you use the Editor to make changes in an existing ADIF file that contains fields other than those listed above, the data from those fields could be lost. Thus you should only use TQSL's Editor to create and edit new ADIF files.

To activate the Editor, select the File menu's Create New ADIF file command to display the QSO Data dialog:

After setting each field to the desired value, click the Add QSO button to add another QSO. When more than one QSO record is present, you can use the arrow buttons to step through the records - though you will not be permitted to step away from a record that contains an error or whose critical fields have not yet been specified. This includes the blank record at the end if you have just clicked Add QSO.

You can delete the currently-displayed QSO by clicking the Delete button.

After all QSO records have been entered, click the Ok button to save them to an ADIF file of your choice.

To edit an existing ADIF file, select the File menu's Edit existing ADIF file command. After you choose the file to edit, the QSO Data dialog will display the first QSO in the file.

Required QSO Fields

Call Sign

The call sign of the station worked.

UTC Date (YYYY-MM-DD)

The QSO date in Coordinated Universal Time (UTC, sometimes called GMT) must be entered in YYYY-MM-DD format(e.g., 2002-08-11 for August 11, 2002).

UTC Time (HHMM)

The QSO time in Coordinated Universal Time can be entered in HHMMSS or HH:MM:SS format. Seconds may be omitted (HHMM or HH:MM).

Mode

The Mode selector is populated with the modes recognized by LoTW. You can create a mapping for modes not present in the selector.

Band

The Band selector specifies the band on which the QSO took place. In the case of crossband QSOs where you transmit on one band and receive on another, select the band on which your station transmitted. All amateur bands from 137 kHz (2190 meters) through the millimeter waves are supported by LoTW.

Optional QSO Fields

RX Band

Leave this field blank unless you are logging a crossband QSO, in which case you should select the band on which your station received.

Frequency

Record the frequency in megahertz on which the QSO took place; this frequency should be consistent with the selected Band field. In cross-band QSOs, specify the frequency on which your station transmitted.

RX Frequency

Leave this field blank unless you are logging a crossband QSO, in which case you should specify the frequency in megahertz on which your station received.

Propagation Mode

Select the propagation mode used to make the QSO, if known. LoTW uses this field to distinguish among the various VHF/UHF propagation modes for those awards that require this information. It is also required to designate Satellite QSOs for DXCC, WAS, VUCC and other awards or endorsements available for contacts made via amateur satellites.

Satellite

If you have set the Propagation Mode selector to Satellite, set this selector to the name of the amateur satellite used to make the QSO. tqsl-2.0/apps/help/tqslapp/qsodata.bmp0000664000076400007640000170341612231073120020064 0ustar rmurphyrmurphyBM6(s؆gJ\BQ:<+2$/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)CCCPPPkkkwww]CP:=,/,)1/-񢟝1/-/,)JJJgggtttQ:;+οοοοοοοοοͿͿͿͿͿͿͿͿͿͿ⢟HHHfff?--*'οοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοע-*'JJJ3%0.,οοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοο0.,;;;οοοοοοοοͿͿͿͿͿͿ̾ͿͿͿοοοοʡ&&&-*'οοͿͿ-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbοͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿ̾̾-*'-*'ohbohbͿͿ̾̾-*'-*'ohbohbͿͿ̾̾-*'-*'ohbohbͿ̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb̾̾̾̾-*'-*'ohb䏏䏏䏏ohb̾̾̾̾-*'-*'ohbuuuuuuuuuuuuuuuuuuohb̾̾̾̾-*'-*'ohbppppppppppppppppppohb̾̾̾̾-*'-*'ohbpppvv00Ҵpppppppppppppppohb̾̾̾̾-*'-*'ohbpppww00Զpppppppppppppppohb̾̾̾̾-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙pppppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppppp1y֙Vyy11ָVy1pppohb̾̾̾̾-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عpppppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppppp1zz1عؚWz1zz11عWz1pppohb̾̾̾̾-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{ppppppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻppppppڜ1Wڻ{{{11{{111{Wpppohb̾̾̾̾-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{pppppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppppp{{11ۼۜXX{1Xۜpppohb̾̾̾̾-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝpppppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppppp}}22ݾݝYY}}22}Y2ݝpppohb̾̾̾̾-*'-*'ohbppp5555Ʉ55Ʉ55^555^^pppppp55Ʉ55Ʉ55^^^^55Ʉ55pppppp5^Ʉ55Ʉ55^5Ʉpppohb̾̾̾̾-*'-*'ohbppp555555pppppp5^^^55pppppp5ʄ5^ʄ555pppohb̾̾̾̾-*'-*'ohbppp555555pppppp__55pppppp5̅555pppohb̾̾̾˽-*'-*'ohbppp55pppppp55pppppp55pppohb̾̾˽˽-*'-*'ohbppppppppppppppppppohb̾̾˽˽-*'-*'ohbppppppppppppppppppohb̾̾˽˽-*'-*'ohbppppppppppppppppppohb̾˽˽˽-*'-*'ohbuuuuuuuuuuuuuuuuuuohb˽˽˽˽-*'-*'ohb葑葑葑ohb˽˽˽˽-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˼-*'-*'ohbohb˽˽˼˼-*'-*'ohbohb˽˽˼˼-*'-*'ohbohb˽˽˼˼-*'-*'ohbohb˽˼˼˼-*'-*'ohbohb˼˼˼˼-*'-*'ohb𠠠ohb˼˼˼˼-*'-*'ohbohb˼˼˼˼-*'-*'ohbohb˼˼˼ʻ-*'-*'ohbohb˼˼ʻʻ-*'-*'ohbohb˼˼ʻʻ-*'-*'ohbohb˼˼ʻʻ-*'-*'ohbohb˼ʻʻʻ-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbʻʻʻʻ-*'-*'ohb䏏䏏ohbʻʻʻʻ-*'-*'ohbuuuuuuuuuuuuohbʻʻʻʻ-*'-*'ohbppppppppppppohbʻʻʻʻ-*'-*'ohbpppT0Ҵvpppppppppohbʻʻʻʻ-*'-*'ohbpppww00Զpppppppppohbʻʻʻʻ-*'-*'ohbpppyy11ָ֙1VָyVVV1y11ָVVV1y11ָ1y֙Vָ1y1ָy1y֙Vppppppy11ָyy1y1yy11ָy1y1ָVy1y1y1ָpppohbʻʻʻʻ-*'-*'ohbpppع1zؚWWz1ع1Wعz1zz1ع1Wعz1zz1ع1zz1عؚWؚWzؚW1zz11ع1zz1عؚWz1ppppppzz11عؚWؚWWؚWzz11عWؚWzW1ؚWؚWpppohbʻʻʻʻ-*'-*'ohbppp1{{1{{11ڻ{{11{{11ڻ{{11ڻڜ1Wڻ{{{11ڻڜWWڜ1Wڻ{{{11ڻpppppp{{11ڻ{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohbʻʻʻʻ-*'-*'ohbppp{{11ۼ1Xۼ{{{11ۼ{{11{{11ۼ{{11ۼ{{11ۼۜXXۜXX{{11ۼۜXXۜpppppp{{11ۼۜXX{1X{{11{1Xۜ{{11ۼ{1Xۜpppohbʻʻʻʻ-*'-*'ohbpppݾ22}ݾ}Y}2ݾYݝY}}22ݾYݝY}}22ݾ}}22ݾݝYYݝYY}}22ݾݝYYݝpppppp}}22ݾݝYYݝYYݝ}}22}}22ݾYYݝ}}22ݾ}}22ݾYYݝ}}22ݾpppohbʻʻʻʻ-*'-*'ohbppp5Ʉ5^Ʉ555Ʉ555^Ʉ55^^5^Ʉ55pppppp5555Ʉ55Ʉ55Ʉ55Ʉ5Ʉ555Ʉpppohbʻʻʻɻ-*'-*'ohbppp^5555^ʄ55555ʄ5^ʄ55^ʄ^^5ʄ5^ʄ5pppppp555^5555pppohbʻʻɻɻ-*'-*'ohbppp5555555̅55̅55̅5pppppp5_5555pppohbʻʻɻɻ-*'-*'ohbppp5555pppppp55pppohbʻʻɻɻ-*'-*'ohbppppppppppppohbʻɻɻɻ-*'-*'ohbppppppppppppohbɻɻɻɻ-*'-*'ohbppppppppppppohbɻɻɻɻ-*'-*'ohbuuuuuuuuuuuuohbɻɻɻɻ-*'-*'ohb葑葑ohbɻɻɻɻ-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohbɻɻɻɻ-*'-*'ohbohbɻɻɻȺ-*'-*'ohbohbɻɻȺȺ-*'-*'ohbohbɻȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺǹ-*'-*'ohbүohbȺȺǹǹ-*'-*'ohb𯯯㯯ohbȺǹǹǹ-*'-*'ohb𯯯ohbǹǹǹǹ-*'-*'ohb𯯯ohbǹǹǹǹ-*'-*'ohb𸵰𸵰𯯯𸵰𸵰ohbǹǹǹǹ-*'-*'ohb𹶱𹶱𯯯𹶱𹶱ohbǹǹǹǹ-*'-*'ohb𶳮򶳮𶳮򶳮𯯯𶳮򶳮𶳮򶳮ohbǹǹǹǹ-*'-*'ohb𵲭𵲭𯯯mmmmmmmmmǛ𵲭𵲭ohbǹǹǹǹ-*'-*'ohb𵲭YXY𵲭YXY𯯯𱄄𵲭656𵲭656ohbǹǹǹǹ-*'-*'ohb𵲭ihi 𵲭ihi 𯯯𱄄𵲭LJL𵲭LJLohbǹǹǹǹ-*'-*'ohb𵲭ywy𵲭ywy𯯯𱄄𵲭 a`a𵲭 a`aohbǹǹǹǹ-*'-*'ohb𵲭! !𵲭􋉋! !𯯯𱄄𵲭wuw𵲭wuwohbǹǹǹǹ-*'-*'ohb𵲭rqr𵲭rqr𯯯𱄄𵲭  𵲭  ohbǹǹǹǹ-*'-*'ohb𵲭][]𵲭][]𯯯mmmm𵲭xvx¿𵲭xvx¿ohbǹǹǹǹ-*'-*'ohb𵲭GFG𵲭GFG𯯯𱄛𵲭 hfh𵲭 hfhohbǹǹǹǹ-*'-*'ohb𵲭212𵲭212𯯯𵲭XWX𵲭XWXohbǹǹǹǹ-*'-*'ohb𵲭􊈊𵲭􊈊𯯯𵲭𵲭ohbǹǹǹǹ-*'-*'ohb𶳮򶳮𶳮򶳮𯯯𶳮򶳮𶳮򶳮ohbǹǹǹǹ-*'-*'ohb𸵱𸵱𯯯𸵱𸵱ohbǹǹǹǹ-*'-*'ohb𾻷𾻷𯯯㯯𾻷𾻷ohbǹǹǹȺ-*'-*'ohbүohbǹǹȺȺ-*'-*'ohbohbǹȺȺǹ-*'-*'ohbohbȺȺǹȺ-*'-*'ohbohbȺȺǹȺ-*'-*'ohbohbȺȺȺɻ-*'-*'ohbohbȺȺȺɻ-*'-*'ohbohbȺȺɻʼ-*'-*'ohbohbȺȺɻʼ-*'-*'ohbohbȺɻʼ˽-*'-*'ohbohbȺɻʼ˽-*'-*'ohbohbɻʼ˽̾-*'-*'ohb`6·ohbɻʼ˽̾-*'-*'ohb66ohbʼ˽̾̾-*'-*'ohb6`6`66·6`6666·66·6`6`66```666ohbʼ̾̾Ϳ-*'-*'ohb666·6```6666·6`·666````6```6Ϋ`666`·6·6ohb˽̾Ϳ-*'-*'ohb666`·66``6`·6666·`6666666`6Ϋ666666ohb̾̾-*'-*'ohb6666````66``666`Ϋ6666`6Ϋ666666ohb̾Ϳ-*'-*'ohb6666````66``66`6Ϋ``666```6Ϋ`6```66ohb̾Ϳ-*'-*'ohb666`·66``6`·6666``66·``6`66``66ohbͿ-*'-*'ohb666·6`·66`·``6·6`·666`666ohb-*'-*'ohb6`6·66·66·666·66ohb-*'-*'ohb66ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𠠠ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbpppy11ָVy1ָ1y֙Vyy11ָVy1y11ָypppohb-*'-*'ohbpppz11عؚWz1ع1zz1عؚWz1zz11عؚWz1zz11عpppohb-*'-*'ohbppp{11ڻ1{{{W{11ڻ1Wڻ{{{11{{11ڻ1{{{W{11{{11ڻpppohb-*'-*'ohbppp{11ۼ{{11{{11{{11ۼۜXX{{11ۼ{{11{{11{{11ۼpppohb-*'-*'ohb66·```666`·666·66·66·66`·666·66·ppp}22ݾYݝY}}22}}22ݾݝYY}}22ݾYݝY}}22}2}2ݾpppohb-*'-*'ohb`666·666·6·`6``66·66·66·`6``66·ppp55^ɨ^555^Ʉ55Ʉ55^ɨ^55Ʉ55pppohb-*'-*'ohb``Ϋ66·66·66·6666·66·66·66·66ppp^5555^ʄ555ʄ5^ʄ5^5555^ʄ55ʄ55pppohb-*'-*'ohb``66·66·6`Ϋ66·66·66·66·6`ppp5̅5555̅55̅55555̅pppohb-*'-*'ohb````66Ϋ``66·66·66·66·66Ϋ``66·66·ppppppohb-*'-*'ohb``66·6·666·66·66·666·666·66·ppppppohb-*'-*'ohb6`·``6666·6666ppppppohb-*'-*'ohb6·66666·66·66·66ppppppohb-*'-*'ohb66·66uuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbpppy11ָVy1ָ1y֙Vyy11ָVy1y11ָypppohb-*'-*'ohbpppz11عؚWz1ع1zz1عؚWz1zz11عؚWz1zz11عpppohb-*'-*'ohb66``ppp{11ڻ1{{{W{11ڻ1Wڻ{{{11{{11ڻ1{{{W{11{{11ڻpppohb-*'-*'ohb66``ppp{11ۼ{{11{{11{{11ۼۜXX{{11ۼ{{11{{11{{11ۼpppohb-*'-*'ohb66666`6````666`6```666```666·6`66666666·6````666·66·66·ppp}22ݾYݝY}}22}}22ݾݝYY}}22ݾYݝY}}22}2}2ݾpppohb-*'-*'ohb6666``6Ϋ`66`6·666·66`·66·666·6·`666``6Ϋ`66666666``6Ϋ`6`·6·6``66·ppp55^ɨ^555^Ʉ55Ʉ55^ɨ^55Ʉ55pppohb-*'-*'ohb666666`6Ϋ666`66·66`·66666·66·66·66·66`6Ϋ666666·`666·66`6Ϋ6666·66ppp^5555^ʄ555ʄ5^ʄ5^5555^ʄ55ʄ55pppohb-*'-*'ohb66·6666`6Ϋ666`·66·6666·66·66·66·66`6Ϋ666666``66·66`6Ϋ66666`ppp5̅5555̅55̅55555̅pppohb-*'-*'ohb666·66```6Ϋ`66·``````66``66·66``6Ϋ`6``666``Ϋ66·66``6Ϋ```66``66·66·ppppppohb-*'-*'ohb66``Ϋ66``6``666``66·6666·6``666·6`66``666·6``66·6`66·66·66·ppppppohb-*'-*'ohb66`666`6666`·6666666ppppppohb-*'-*'ohb6`66·666``666ppppppohb-*'-*'ohb66uuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb66``6``6·ohb-*'-*'ohb66`66Ϋ``6ohb-*'-*'ohb6666`6`6666666·666``666·66·6666·6`66·6`·6666·6666``6`66·ohb-*'-*'ohb66``6`6`6666``6`66`66·6``66666`6·6`6·6666·66666Ϋ`6·666·ohb-*'-*'ohb66·`6```6666666``66·6666·666666·66````6·666·`666·66666```ohb-*'-*'ohb66`6·66666```66·66666`Ϋ6666·66````6·666``66·666666·66ohb-*'-*'ohb66`666·6`Ϋ6```666`66·6666``666``66`````6·666``Ϋ66·6666`6``66·ohb-*'-*'ohb66``6`666666``66·`6·6666·66·66```Ϋ`6`6`·`6·666·6``66·66666`6·666·ohb-*'-*'ohb66`6`·66`666`·`6666`·66666·66666`ohb-*'-*'ohb66·````6`6Ϋ`6``6·6666`6ohb-*'-*'ohb6``6·ohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb66``6``6·ohb-*'-*'ohb66`66Ϋ``6ohb-*'-*'ohb666666·666``666·66·6666·6`66·6`·6666·6666``6`66·ohb-*'-*'ohb6666``6`66`66·6``66666`6·6`6·6666·66666Ϋ`6·666·ohb-*'-*'ohb666666``66·6666·666666·66````6·666·`666·66666```ohb-*'-*'ohb66666```66·66666`Ϋ6666·66````6·666``66·666666·66ohb-*'-*'ohb6`Ϋ6```666`66·6666``666``66`````6·666``Ϋ66·6666`6``66·ohb-*'-*'ohb6666``66·`6·6666·66·66```Ϋ`6`6`·`6·666·6``66·66666`6·666·ohb-*'-*'ohb666`·`6666`·66666·66666`ohb-*'-*'ohb6`6Ϋ`6``6·6666`6ohb-*'-*'ohb6``6·ohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbpppy11ָVy1ָ1y֙Vyy11ָVy1y11ָypppohb-*'-*'ohbpppz11عؚWz1ع1zz1عؚWz1zz11عؚWz1zz11عpppohb-*'-*'ohbppp{11ڻ1{{{W{11ڻ1Wڻ{{{11{{11ڻ1{{{W{11{{11ڻpppohb-*'-*'ohbppp{11ۼ{{11{{11{{11ۼۜXX{{11ۼ{{11{{11{{11ۼpppohb-*'-*'ohb6666`6`66````666·6666```666·66·ppp}22ݾYݝY}}22}}22ݾݝYY}}22ݾYݝY}}22}2}2ݾpppohb-*'-*'ohb66``6`6`66`6·666·6·66666`·6·6·66·ppp55^ɨ^555^Ʉ55Ʉ55^ɨ^55Ʉ55pppohb-*'-*'ohb66·`6```666``Ϋ66·66·6666·6666ppp^5555^ʄ555ʄ5^ʄ5^5555^ʄ55ʄ55pppohb-*'-*'ohb66`6·6666·66·6666·6666ppp5̅5555̅55̅55555̅pppohb-*'-*'ohb66`666·66·``6``6``66·66·ppppppohb-*'-*'ohb66``6`6666``66·66``66·66·ppppppohb-*'-*'ohb66`6`·66`666666ppppppohb-*'-*'ohb66·````6`66ppppppohb-*'-*'ohb66uuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppҴ0vTT0Ҵvpppohb-*'-*'ohbppp0wUUw0Զpppohb-*'-*'ohbppp1y֙V1y1ָy֙VV֙yy11ָyy11ָ֙1Vָy1y֙VyV1֙y11ָy1yy1yy11ָyy11yy11ָyy11ָVV֙1y֙Vpppohb-*'-*'ohbpppzz11عWz1zW1ؚWؚW1zWzz11عzz11عWz1عzz11عzW1ؚWؚWzW1ؚz11عzzz11عzz11zz11عzz11ع1zW1zz1pppohb-*'-*'ohbppp{{11ڻWWڜڻ11{{WWڜ{{11{{11ڻ{W1ڜ{{11ڻ1{{1{{11ڻ{{11ڻڻ11{ڻ{ڜ1Wڻ{{{11ڻ{W1ڜ{{11{{11ڻ{{11ڻ1{ڜWWڜWpppohb-*'-*'ohbppp{{11ۼXXۜ{X1ۜXXۜۜXX{{11ۼXۜX{{11ۼ1{{1{{11ۼXۜX1{X1{{1ۜ1Xۼ{{{11ۼXۜX{{11{{11ۼ{{11ۼ{11ۼ{{{11ۼpppohb-*'-*'ohb6````666·6666```666·66·ppp}}22ݾYݝYYYݝݝYY}}22ݾYY}}22}}22ݾ2}}2}}22ݾݝY2ݾ}}}22ݾ}}22ݾYY}}22}}22}2}2ݾY}2ݾYݝYpppohb-*'-*'ohb66`6·666·6·66666`·6·6·66·ppp555^Ʉ^^55Ʉ555Ʉ5^^55^55555Ʉ5555Ʉ555Ʉ5^^55Ʉ55555^5Ʉ5pppohb-*'-*'ohb66``Ϋ66·66·6666·6666ppp55^^^^5ʨ^^5555^ʄ555555^ʄ5555ʄ^5^^5^ʄ^5555^ʄ55555ʄ55555^pppohb-*'-*'ohb6666·66·6666·6666ppp5__̅5__5__55̩_5_55̅5̅55__5̅5555_5pppohb-*'-*'ohb66·``6``6``66·66·ppp5``5Άpppohb-*'-*'ohb66``66·66``66·66·ppppppohb-*'-*'ohb666666ppppppohb-*'-*'ohb6`66ppppppohb-*'-*'ohb66uuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppp1yV1yy1ָy1֙Vpppohb-*'-*'ohbppp1zWؚWWؚ1W111عzW111z1pppohb-*'-*'ohbppp1Wڻ{ڜWWWڜWW{{{1Wڻpppohb-*'-*'ohbppp{11ۼ{ۜX1{ۜX1X1{ۜX1{ۜpppohb-*'-*'ohb6666·6````666·66·66·pppY2ݝ2}}2}Y}ݾ}2YݾYݝYpppohb-*'-*'ohb6666``6Ϋ`6`·6·6``66·ppp55Ʉ5^Ʉ^^^Ʉ5^Ʉ5pppohb-*'-*'ohb66·`666·66`6Ϋ6666·66ppp5^^^^^5555^55pppohb-*'-*'ohb66``66·66`6Ϋ66666`ppp__5555̅__pppohb-*'-*'ohb66``Ϋ66·66``6Ϋ```66``66·66·ppppppohb-*'-*'ohb666·6``66·6`66·66·66·ppppppohb-*'-*'ohb`6666`·6666666ppppppohb-*'-*'ohb6``666ppppppohb-*'-*'ohb66uuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb6``6·ohb-*'-*'ohb6Ϋ``6ohb-*'-*'ohb66666`6666·66·66·66·666`·6666·6666·6666·66666`66·ohb-*'-*'ohb6`·6Ϋ`666```6666·66·66·66```6·6666·6666·6666·66666·666·ohb-*'-*'ohb6666666`·6666·66·66·66·666·66666·6666·66·`666·66·`666``ohb-*'-*'ohb666666666666·66·66·666`6·66666·6666·66``66·66``6666ohb-*'-*'ohb666666`6666666·`6·`6``666·66666·66``Ϋ66·66·66``Ϋ66·66``66·ohb-*'-*'ohb66666666·6666`666`Ϋ`6`66·`6·6666·6666·666·6``66·666·6``666·666·ohb-*'-*'ohb6666666```666`·6666·6666`6666`·66666`6666`·666666`ohb-*'-*'ohb66`666`·6``6``6666Ϋ`6666·66666``66``6`6ohb-*'-*'ohb6``6·ohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb6``6·ohb-*'-*'ohb6Ϋ``6ohb-*'-*'ohb66666`66·```666`·6666`·666666666666·666666·66·6`66·ohb-*'-*'ohb6`·6Ϋ`666```66``666·6·`6```6666666666666·666666``66``6·666·ohb-*'-*'ohb6666666`·666666·66·66·666·66666666666·`666·66·`6666666·6666``ohb-*'-*'ohb6666666666``66·66·6`6·6666666666``666``66·66``666``666``Ϋ66``66ohb-*'-*'ohb666666`666````66Ϋ``666·6`666``666``666``666`66``Ϋ66·66·66``Ϋ66·6666``Ϋ66````66·ohb-*'-*'ohb66666666·666666·6·666·`666`666`666`666`6666·6``66·666·6``666666·66666·666·ohb-*'-*'ohb6666666```666`666`·```·6```·6```·6```·6`6666`·66666`6666`·66666666`666`6`ohb-*'-*'ohb66`666`·6``6`666Ϋ``666`666`666`666·6``66``66`6``6ohb-*'-*'ohb6``6·ohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohb``ϵɤohb-*'-*'ohb``ϵɤohb-*'-*'ohb6````666·66·6666·66`6·6666·66·ϵɤohb-*'-*'ohb6```Ϋ666·6·66·66`666·666`·66·6666·66·ϵɤohb-*'-*'ohb6`·66·66·66·66``Ϋ66`·666·6666ϵɤohb-*'-*'ohb6666·66·66``66·6666·6666ϵɤohb-*'-*'ohb`6``66·66``66``666``6·66·ϵɤohb-*'-*'ohb66·66·66·66``66·66·66``66·ϵɤohb-*'-*'ohb6```66·666`·``ϵɤohb-*'-*'ohb``66·666·666ϵɤohb-*'-*'ohb66·66ϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbĭ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\ĭohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'ͿͿͿͿͿ̿̾̾̾˽˽˽˽˼˼˼˼ʻ˼˼˼˼˼˼˼˼˼ʼʼʼʼɻɻɻɻɻɻȺȺȺȺȺȺȺȺȺȺɻɻȺȺɻɻʼ˽˽̾Ϳ-*'-*'ͿͿͿͿ̾̿̿̿̾̾̾˽˼˼˼˼˼ʻʻʻ˼˼˼˼˼˼ʼʼʼʼʼɻɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻɻȺɻɻʼɻ˽̾̾-*'-*'̾̾̾̾̾̿̿̾̽̽˼˼˼˼ʻʻʻʻʻʻ˼˼ʼʼʼʼʼʼɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺȺɻɻɻȺɻɻʼ̾̾Ϳ-*'-*'ͿͿ̾̾̾̾̾̿̾̽̽̽̽ʻʻʻʻʻʻʻʻʻʼʼʼʼʼɻɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻɻǹȺȺɻʼ˽̾̾-*'-*'ͿͿͿͿ̾̾̾̾̽̾̾̽˼˼˼ʻʻʻʻʻʻʻɻɻɻʼɻɻɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺȺǹǹȺɻʼ˽̾̾-*'-*'̿̿̿ͿͿͿͿ̾̽̽̽̾˽˽˽˼˼˼ʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺǹǹȺȺǹȺȺɻʼ˽Ϳ-*'-*'̿̿̿̿Ϳ;;̽̽˼˼˼˽˽˽˼˼˼˼ɻɻɻɻȺȺȺȺȺɻȺȺȺȺȺȺȺȺǹǹǹǹȺȺȺȺɻ˽̾ͿͿ-*'-*' Ϳ̿̿̿;;;;̽˼˼˼˼˼˽˽˼˼ʼʼɻɻȺȺȺȺȺȺǹȺȺȺȺȺǹǹǹǹǹȺȺȺȺʼʼ˽̾-*'-*'UͿͿ̿̾̾̾;̽̽˼˼˼˼˼˽˽˽ʽʼʼʼȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺɻʼʼ˾̿V_*4f(P(P!)Q"*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fW_-*'-*'XKYMפ }WULբYJVؤGͿοͿͿ̾˽˽̽̽̽̽˼˼˼˼ʼʽʽʽɻɻɻȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺɻɻɻʽʽ˾̾Ϳ)-Ny}̲ଵଵ୵㭵䭷䫸竹諹諹꫹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹뫹꫹諹諸筷䭵䭵㭵୵೹ୱy})-N-*'-*' LգWPVY׃Vƀ ۨJWۧI Mפ |YLգ | ~S٤HͿ;;ο̾̾˽˽˽̽̽̽̽˼ʼʼʼʼɼɼɼɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʽ˽̾ͿͿVZ}so~p~pppooonnlllllllllllllllllnnooopppp~p~t~ǞӄWZ-*'-*'U|WڧILU֤ īK WڦI ëKWLUբ |YԁVؤGͿ;̽;̾̾˽˽˽̽̽˽˽ʼʼʼɻɻɼɼɼɼȺȺȺǹǹǹǹǹȺȺȺɼɼɼɼʼʼ˽ͿͿ &Nozcqdqcrcrcrbtbvbvbv`x`x`y`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`y`x`xbvbvbvbtcrcrcrdqdqpz &O-*'-*'YԂYŀWƀ ܨJL פWۧI L֤ | ؤGͿͿ̾̾̽;̾̾˽˽ʽ˽˽˽˽˽ɻɻɻɻɼɼȻȻȺȺȺȺȺȺȺȻɼɼɼɻʼʼ˽Ϳ>WfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiRiShSfSfSfTeTeTdTbTbXf>-*'-*'YԪJY׫K ۨJ ~ ~WۧILU֤L ֤ | ؤGοͿ̾ͿͿ̾̾̽;;̾ʽʽʽʽ˽ʼʼʼɻɻɻȺȺȻȻȻȺȺȺȻȻȻɻɻɻɻʼ˽Ϳ;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*' êK ÂWۨJV}WڦILUգ  J Ϳ̾̾ͿͿ̾̾̽;̾˾˾ʽɼɼʼʼʼʼȺȺȺȺȺȻȻȻȻȻȺȺɻɻɻʼ˽̾Ϳ 9̿˾˾̿̾˽ʽ˾˾ʽ˾˽˾˽̿̿?DY꫰૱㫲䫲䫲櫲課課몲쪲者者쪲쪲髲髲竲嫲嫱䫰?DYꠝF2X?oPaFW?/,)0.,BFZBFZ/-+.+(H4Y@eI}ZrRfJZAK6-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'D1P:`EiLqRtqsl-2.0/apps/help/tqslapp/primary.htm0000664000076400007640000000140512231073120020111 0ustar rmurphyrmurphyTQSL Primary Operations

Primary Operations

tqsl-2.0/apps/help/tqslapp/pref-opt.htm0000664000076400007640000000620512231073120020165 0ustar rmurphyrmurphySetting TQSL Options

Setting TQSL Options

To inspect or change TQSL's options, select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display its Preferences dialog; this dialog's Options tab provides control over several settings that govern TQSL's operation:

Specify ADIF and Cabrillo File Extensions
Because there are no standard file extensions (.XXX) consistently used for ADIF AND Cabrillo files, TQSL lets you specify the extensions used on your system for each file types. The Select File to Sign and Upload and Select File to Sign and Save dialogs set their Files of type selectors based on the extensions specified on this tab:

In the example shown above, files whose names end in .log or .cab will be treated as Cabrillo files, while those with names ending in .adi or .ADI are ADIF files. When using an operating system like Windows that doesn't distinguish case in file names, the two ADIF entries shown in this example would be unneccessary.

Enable automatic Backup File creation on termination
If you want TQSL to automatically create a Backup File when it terminates, check the Allow automatic configuration backup box, click the Browse button to the right of the Backup File Folder textbox, and use the Browse For Folder dialog that appears to select the folder in which Backup Files will automatically be created when terminating.

Allow Nonamateur Callsigns
The Allow nonamateur call signs checkbox lets you to choose whether TQSL should treat a nonamateur call-worked as an error. LoTW does not accept nonamateur callsigns, so this option is disabled by default.

Prompt for QSO Date Range
This checkbox determines whether TQSL will display the QSO Date Range dialog when Submitting a Log File to LoTW via the Internet or when Submitting a Log File from a Computer without Internet Access.

The QSO Date Range dialog can be used to prevent QSOs already submitted to LoTW that haven't been subsequently modified from being submitted again, sparing LoTW from processing QSOs that have already been processed.

tqsl-2.0/apps/help/tqslapp/pref-opt.bmp0000664000076400007640000154506612231073120020171 0ustar rmurphyrmurphyBM66(<fffWWW/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}hhh/,)1/-󢟝1/-/,)OOOooo}}}hhhοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺɻʼ˽̾̾Ϳ碟PPPrrrrrr-*'οοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳޢ-*'WWWaaa0.,οοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾.,*III222οοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿӠ222-*'-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫ohb-*'-*'ohb䏏𫫫䏏𫫫䏏𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppvv00Ҵppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppww00Զppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙ppp𫫫ppp1y֙Vyy11ָ֙Vy1ppp𫫫ppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָppp𫫫ohb-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عppp𫫫ppp1zz1عؚWz1zz11ع1zz1ppp𫫫ppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عppp𫫫ohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{ppp𫫫pppڜ1Wڻ{{{11{{11ڻ1{Wppp𫫫pppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻppp𫫫ohb-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{ppp𫫫ppp{{11ۼۜXX{11X{{{1ۼppp𫫫ppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼppp𫫫ohb-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝppp𫫫ppp}}22ݾݝYY}22222ݾ}ppp𫫫ppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾppp𫫫ohb-*'-*'ohbppp5555Ʉ55Ʉ55^555^^ppp𫫫ppp5^Ʉ55Ʉ5555Ʉppp𫫫ppp55Ʉ55Ʉ55^^^^55Ʉ55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5ʄ5^ʄ555ʄ55ʄppp𫫫ppp5^^^55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5̅555__ppp𫫫ppp__55ppp𫫫ohb-*'-*'ohbppp55ppp𫫫pppppp𫫫ppp55ppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohb葑𫫫葑𫫫葑𫫫ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫ohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb::f:ېffffffohb-*'-*'ohb􏏎::::ffffffohb-*'-*'ohb􏏎:::::f::ې::ې:::ffې::::f:::f::ې:f::ېfff:::fې:::::fff:::ې::::f:ې:::fېf:ې::::ې::ې::::fې:::f:ې::::ې::ې::::f:ohb-*'-*'ohb􏏎::::ff:۶f::ې::ې::ې::f:ېf:::۶ff:۶f:::ې:fff::::ې:fې:::ff:::ې:ېf:ff:::::ې:ې:::::fې::ff::fې:ffffې::::ff::::ېf:::::fې::ې::::ې::ې:::::fې::ohb-*'-*'ohb¿􏏎::::::f:۶::ې::ې::ې:::fې::::ې::f:۶:::fې::ff:fې::::::::ې::ې::ې::::::ې::ې::::fې:::ې:::۶f:ff:ff::::ې::::::ff۶::fې:::ې::::ې::ې::::fې:::ohb-*'-*'ohb􏏎::ې::::f:۶::ې::ې::ې:::fې::::ې::f:۶::::ffff::ff::ff::ې::ې:f::::ې::::ې:::::f:fېff۶f:f::::::f۶::::ff::ې::::ې::::ې::ې::::ې::::ohb-*'-*'ohb􏏎:::ې::fff:۶f::ېf:ېf:::ېff::::۶ff:۶f:f::ffff::ff::ffff::۶ff:::fff:ff:ff::ff::ff:ffff:f:ff:ff:::ff:f:ff۶::ff:::ff:ې:::ff:ff::ohb-*'-*'ohb􏏎::ff۶::ff:ff:::f۶f:ff:::ff:ې:f::f::ff:fې::ff:fې::::::::ې:ې:::ې::ff::ې::ff::ې::ې::ېf:f:۶::ff::ې::ff::ې::ې::ې::ff::ې::ff::ohb-*'-*'ohb􏏎::f:::f::ې:fې::fېff:ې:fې::::f::::ohb-*'-*'ohb􏏎:f:::fې:ې::ې::ې::f::::::::ohb-*'-*'ohb􏏎ff::ohb-*'-*'ohb􏏎ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbffohb-*'-*'ohb􏏎ffohb-*'-*'ohb􏏎:::f::ې::ې:f:fېf:::::ې:f::::fff:::ې::ې::ې::fff:::fې::::ff:::ې:::ffff:::ې::ې::fې:::f:ې::::fې:ohb-*'-*'ohb􏏎:ff:ې::ې::ff:۶f::fې:ffffې::::ff:۶f::::ې:::ې:ې::ې::ې::ې:::ې:ېf:fff::ې:ې:::f:::ې:ې::ې::ېf:::::fې::ې::::ېf::ېohb-*'-*'ohb¿􏏎:ې:::ې::ې::f::۶f:ff:ff::::ې::f:۶::::::ې::ې::ې::ې::::ې::ې::ې::::::ې::::::ې::ې::ې::ff۶::fې:::ې::::ffohb-*'-*'ohb􏏎::۶:fې::ې::ې::f::fېff۶f:f:::::ې::f:۶::::ې::ې::ې::ې::ې::ې::ې:f۶::::ې::::::ې::ې::ff::ې::::ې::::ffohb-*'-*'ohb􏏎::ېf:ې::ې::ff:۶fff:ffff:f:ff:ff:۶f:ff:ff::ېf:ېf:ff::۶ff::ې:::::f:fff::ې::f:ff۶::ff:::ff:f:ffohb-*'-*'ohb􏏎:ې:fې:::ې::ې:f::ېf:f:::ff:f::ff::ېf:::f۶f:f::ې:ې:::ې::::ې::ffff::ې::ې::::ې::ې::ې::ff::ohb-*'-*'ohb􏏎f::::fې::ې::::::ې::ohb-*'-*'ohb􏏎::::ې::::::ې::::ohb-*'-*'ohb􏏎::ې::::ې::ohb-*'-*'ohb􏏎ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohbϵɤ䏏ohb-*'-*'ohbϵɤuuuuuuohb-*'-*'ohbϵɤppppppohb-*'-*'ohbϵɤppppppohb-*'-*'ohbϵ:fې:fې:fېff:fېff:::fېɤppppppohb-*'-*'ohbϵfffffff:fff:::ffɤpppy1V֙yy11ָy1V֙֙1VָyVy1ָVy1y1y1ָpppohb-*'-*'ohbϵ:f::ېff::۶fې:::ې::fې:f::::fې::f:ې::::ې::f::ېf::::::::ې::ې:f:f:ff:::ې::ې::ې::ې::ې::::f:fې:f::::::::ې::ې:::f:f:::fffffffɤpppzz11عWz1zz11عؚWؚW1zWz11Wz1WzWWWعzzعzWع11zzWؚWpppohb-*'-*'ohbϵ:fff::ېff:fې:۶fېf::ېff::ېf::ېff:::ې::fff::ې:::f:::ېf:::ې:::ff:::::ې:::ffff:۶f:ff::ې:ې::ې::ې::ff::::ېf:ېf::ېff:::::ې:::ff::ff:۶f::f:ې:::۶fff:۶fff:fېffɤppp{{11ڻڜWW{{11ڻ{{11ڻ{W1ڜ1{W{1WڻW1{WڜWڜWW{{11ڻpppohb-*'-*'ohbϵ:fې::::::ff۶::::ff:::::۶f:fې:fې::fffff۶ې:fې::::::ېf:::ffff::::ې::f:۶::::::ې::ې::ې::ې::::::ې::ff::::ېf:::ffff::::ې::::f:۶:::f::f:۶::f:fې:::ېɤppp{{11ۼ{{11{{11ۼ{{11ۼ{X1ۜ1Xۼ{XX{X1{ۜX1XXۜ{1Xۜpppohb-*'-*'ohbϵ::::ې::::ff:f۶::ff::::f::::fې::f:f:f:f:::::ې::ff::۶ffff::ff۶::f:۶::::::ې::ې::ې:::f۶::::ې::۶ff::ې::ff::۶ffff::ff۶::::f:۶:::f::f:۶::f::ې:::ɤppp}22ݾ}}2ݝYݝYݝY2}YYYݝ2}YYYݝY}2Y}Y2ݝYYݝYYݝ}}22ݾpppohb-*'-*'ohbϵf:::ې:ې:::::f:ffff:::ff:ff:ې::::::ېf:::f:::f:ې:fې:fff:::ې:::ff۶::ې::ffff::ffff:۶f:f::::::ېf:ېf:ff:::ff:ې::ېf:ff:ې:::ff۶::ې::ffff::ff۶:fff:۶f::ېff۶::ې:ې:ff:۶ff:::ې:ې:ɤppp55^^55^^먄5^먄55Ʉ^5^555Ʉ55Ʉpppohb-*'-*'ohbϵ::ې::ېff::::::ې::ې::ff::ff::::ې::ې::ې::f::fېfffې:fې:::ff:::ې:ff:::f:fې::::ې:fff::::f:::f۶f:f::ې::ff:ې:::ff:::ې:ff:::f:fې::::ې::ff:ff:::fff:::f:ې:ffې:::ېffɤppp5555pppohb-*'-*'ohbϵ:fffff::::ff::ې::ې:fffff:fېfffې:ff::::f::ې::Ifff::::fې::::::::f::fff::::fې::::::::f::ffɤppp5_pppohb-*'-*'ohbϵffff::::ff::ffff:ې:f:::::::ېff۶::ېIf:ff::f::ff:ff::f::ffɤppppppohb-*'-*'ohbϵ:ې::ې:o$ې::ې::::ې:ɤppppppohb-*'-*'ohbϵɤppppppohb-*'-*'ohbϵɤppppppohb-*'-*'ohbϵɤuuuuuuohb-*'-*'ohbϵɤ葑ohb-*'-*'ohbͶ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\Ͷwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohb::ohb-*'-*'ohb::ohb-*'-*'ohb:ffff:::ې:f::۶fې::ff::::f::::ې::ې:::::f::fff:::ې::ې::::ېohb-*'-*'ohb::f:ې:::ې::f::fې:f::ې:ې::f:::::ې::ff::ff:۶f:::fې:ې:ff::::ېohb-*'-*'ohb::ff۶::ې::ې:::::f::::ې:::fې::::ې::ې::::::f:۶::ې::::ې::::ohb-*'-*'ohb::::ې::ې:::f::::ې:::fې::::ې:::f::::f:۶::ې:::::f۶::ohb-*'-*'ohb::ېff:f::f:::::::ېff:f۶::ې::ff:::fff:۶f::ff::ff:::f::ېohb-*'-*'ohb::ff::ېff::f:::::f:::ff::::ې::ې::ې:::f::ې::ې::ې::ff::ېohb-*'-*'ohb::::::::::::::::ohb-*'-*'ohb:f:::f۶::ې:::f::::ohb-*'-*'ohb::::::::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohbͿ-*'-*'ohbff::ohbͿ-*'-*'ohb􏏎ff::ohbο-*'-*'ohbߺ􏏎:::f::ې::ې:f:fېf:fff::::ff:::fې::f::ې::ې::fff:::fff:::ې:f:f:f::::ې::ې::f::ff:::ې::fff:::fff:::ې:f::::::fff:::ې:f::۶fې::ff::::fohbͿ;-*'-*'ohb껙_JaLѹ􏏎:ff:ې::ې::ff:۶f::fې:ffffې:::ې:f::ې:ېf:ff:۶f::ې::ې::ې:::ې:ېf::::f:fff:۶f::::ې::ې:::fې::f::ې:ې:::::ې:ېf:::ff:۶f:::::::۶f:::ې::f::fې:f::ې:ې::f:ohbͿͿ;-*'-*'ohbޕ]H_I`Ksa􏏎:ې:::ې::ې::f::۶f:ff:ff::ې::ې::::ې::ې::f:۶::ې::ې::::ې::ې::ې::ې::::::f:۶::::ې::ې::fې:::ې::::ې::::ې::ې::ې::ې::f:۶::::::f:۶::ې::ې:::::f::::ې:::fېohbͿͿ;;-*'-*'ohbުn\Gϧxg`Kտ􏏎::۶:fې::ې::ې::f::fېff۶f:f:::ې::::ې::ې::f:۶::ې::ې::ې::ې::ې::ې::::::f:۶::::ې::ې::ې::::ې::::ې::::ې::ې::ې::f:۶::::::f:::ې:::f::::ې:::fېohbͿ;;̽-*'-*'ohbȮ^Ivd􏏎::ېf:ې::ې::ff:۶fff:ffff:fff::::ې::۶ff:۶f::ېf:ېf:ff::ې:::f:fff:۶f:ff:ې::ې::ff::ې:::::fff::ې::ff:۶f:ff:::ې:ې:ff:f::f:::::::ېffohbͿ;;˼-*'-*'ohbq^\Gü􏏎:ې:fې:::ې::ې:f::ېf:f:::ې:::::ې::ff:::f۶f:f::ې:ff:::۶ffff:f::fff:ې::ې::::ې::ff::ې:ff:::ې:f::fff:::f:ې::ېff::f:::::f:::ffohbͿ;̽˼-*'-*'ohbϸZEwe􏏎f::::fې::ې::::::f:::::::ohb;̽˼˼-*'-*'ohbjWZDп::::ې::::::ې:::fې::::ې::::::ohb;˼˼ʻ-*'-*'ohbw::ې::ff::::ohb̽˼˼ʻ-*'-*'ohb􏏎ohb̽˼˼˼-*'-*'ohbohb˼˼˼˼-*'-*'ohbohb˼˼˼˽-*'-*'ohbohb˼˼˽˽-*'-*'ohbohb̽˽˽˼-*'-*'ohbohb˼˽˼˼-*'-*'ohbohb˽˼˼̽-*'-*'ohbohb˽˼˼̽-*'-*'ohbohb˼˼̽̽-*'-*'ohbohb˼̽̽˽-*'-*'ohbohb̽̽˽˽-*'-*'ohbohb̽̽˽̾-*'-*'ohbohb̽˽̾;-*'-*'ohbohb˽˽;̽-*'-*'ohbohb˽̾̽̾-*'-*'ohbohb̾;̾Ϳ-*'-*'ohbohb;̾ͿͿ-*'-*'ohbohb̽̾ͿͿ-*'-*'ohbohb̾ͿͿ-*'-*'ohbohbͿ̾-*'-*'ohbohb̾Ϳ-*'-*'ohbohbͿ-*'-*'ohbfff:::fff:::ې::ohb-*'-*'ohb:::ې::fې:ې:ې::ohbͿ-*'-*'ohb::ې::ې::::ې::ohb-*'-*'ohb::ې::::ې::ohb-*'-*'ohbffff::ې::ohb-*'-*'ohb::ې::ې::ohb-*'-*'ohb::ohb-*'-*'ohb::ې::ohb-*'-*'ohb::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb:::f::ې:f۶::::ې::ې::ې::::fffffې:::ې::::fې:::ې:f::::fې:::ېohb-*'-*'ohb:ff:ې::ff::ې::::ې::ې::ffffff:fېf:ff::::ېf::::ff:۶f::::ېf::ې::ېohb-*'-*'ohb:ې:::::ې::ې::::ې::ې::ې::::fې:::ې::::::ff۶::ې::f:۶::::ffohb-*'-*'ohb::۶:fې::ff::ې::::ې::ې:::f:f:ې:::ې:f۶::::ff::ې::f:۶::::ffohb-*'-*'ohb::ېf:ې::ff::ې:f::ې::ې::ff::ff::ېf:::ې::۶ff:::ff:f:ff۶::ff:۶f:ff:f:ff::ېohb-*'-*'ohb:ې:fې:::::ې::ې::f:ې::ې::ې::ېfې:::ې:ې:::ې::ff::ې::ې:f::ff::ې::ېohb-*'-*'ohbf::::fې:::f::ې::f:::::ohb-*'-*'ohb:::f:f۶:f:fې::ې::::::ohb-*'-*'ohbff::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbffohb-*'-*'ohbffohb-*'-*'ohb::ې:ff::f::ې::ohb-*'-*'ohb::ff:۶f:fې:::f:::۶f::ohb-*'-*'ohb::ې::f:f:::::::f:۶::ohb-*'-*'ohb::ې::f:۶::::::::f:۶::ohb-*'-*'ohb::ff:۶fff:::f::ې:ې::fohb-*'-*'ohb::ې:f::fff:::f:ې::ffohb-*'-*'ohb::::ohb-*'-*'ohb::::ohb-*'-*'ohb::::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb½½ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb:ffff:::::ې::::ې::ې::ې:f::ې::ې::ې::::fffffې:::ې::::fې:::ې:f::::fې:::ېohb-*'-*'ohb:fff۶:::ې:ې:::۶f::::ې::ې::ff:۶f::ې::ې::ffffff:fېf:ff::::ېf::::ff:۶f::::ېf::ې::ېohb-*'-*'ohb:fې::ې::ې::f:۶::::ې::ې::ې::f:::ې::ې::ې::::fې:::ې::::::ff۶::ې::f:۶::::ffohb-*'-*'ohb::::ې::f:۶::::ې::ې::ې::f:::ې::ې:::f:f:ې:::ې:f۶::::ff::ې::f:۶::::ffohb-*'-*'ohbf:ff::ې:ې::f::ې::ې::ff:۶f::ې::ې::ff::ff::ېf:::ې::۶ff:::ff:f:ff۶::ff:۶f:ff:f:ff::ېohb-*'-*'ohb::ې::ېf:::f:ې::ff۶::ې::ې::ې:ff:ې::ې::ې::ېfې:::ې:ې:::ې::ff::ې::ې:f::ff::ې::ېohb-*'-*'ohb:fff::::ې::f:::::ohb-*'-*'ohbff::::ې::ې:::fې::ې::::::ohb-*'-*'ohb::::ې::ff::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb󕌉󕌉󕌉𫫫ohb-*'-*'ohb󕌉󕌉󕌉𫫫ohb-*'-*'ohbvv00ҴTҖT𫫫ohb-*'-*'ohbww00ԶUw0Զ𫫫ohb-*'-*'ohb::z11عؚ1Wzz11عzz1Wzz11عzz11عzz11عz1WؚWWW1z11عz1z1عWz11zWWWW1z11z1z1عzz11عzz11zz11zz11عz1Wؚع1z1عzz1Wؚz1z1عz1WWz1z11عWz1عz1z1عWz11WعzWz1عz1Wؚzz11عzz11عWz1zz11عzz11عz1WؚWؚWWWؚع11zعz𫫫ohb-*'-*'ohb::1{ڜWW{1{{11ڻڜWڜW{{11ڻ{{11ڻ{{11ڻ{{11ڻWڜW1{W1Wڻ{1{{1ڻWڜW{ڻ{Wڻ11{ڻ{1{WڜWW{{11ڻ1{{1{{11ڻ1{W{{11ڻ{{11{{11{{11ڻWڜW1{W{ڜW1{{11{{11ڻW{1ڻWڜWڻ1{ڜW{ڻ{Wڻ11{ڻ{{11ڻڜW{1ڻWڜW{W1ڜ{11W{1W{WWWڻ{WڜW1{W{{11ڻ{{11ڻW{1{{11ڻ{{11ڻڜWڜW1{WڜWWڜ1Wڻ{{1{1𫫫ohb-*'-*'ohb:f:ffff:::ې:f::::fې:1{{1{{11ۼ{{11ۼ{{11ۼ{{11ۼ{{11ۼ{X1ۜ{{11{{11ۼ{X1{{11ۼ{{11{{11ۼۜXXۜ1Xۼ{{11ۼ{{{11{{11ۼ{X1{{11ۼ{{11{{11{{11{{11ۼ{X1ۜۜXX{{11ۼۜ1X{{{11ۼ{{11ۼۜXXۜ{11ۼ1{{{X{11{{11ۼ{{11ۼ1{X{1XۼX1{XۜX{{11ۼ{X1{{11ۼ{{111{X{{11ۼ{{11ۼ{{11ۼ{X1ۜX{1XXXXۜ𫫫ohb-*'-*'ohb:ې:fې:::f:ېf:::ff:۶f::::ېf::ې}}22ݾ2Yݾ}}}22ݾݝYYݝ}}22ݾ}}22ݾ}}22ݾYݝY}}22}}22ݾ}Y2}}22ݾ}}22}2YݝYYݝ}22ݾ}2}2}}22ݾ}Y2}}22ݾ}}22}}22}}22}}22ݾ}Y2ݝYY}}22ݾݝ2Y}}2Y}}22ݾݝYYݝ}22ݾ}}22}}22}2Yݝ}}22ݾ2Yݾ}YY}Y2}ݝY2}}22ݾ}Y2}}22ݾ}2Yݝ}2}2ݾ}}22ݾ}}22ݾ}Y2ݝ2}}2ݝYYݝYݝY𫫫ohb-*'-*'ohb:fې::ې:::fې::ې::ې::f:۶::::ff55Ʉ^5Ʉ55^^먄55Ʉ5^55^^ɨ55Ʉ55^^5ɨ^^^55^^55^5^^^5^^55Ʉ5Ʉ55^55Ʉ55Ʉ55^^5ɨ^^^55Ʉ^^^^555^^5^^55^^55^^55Ʉ55ɨ^^5^^^^5^^^5ɨ^5^55^5555Ʉ55^^^5ɨ^^555Ʉ^^^^𫫫ohb-*'-*'ohb::ff۶:::fې::ې::ې::f:۶::::ff5ʄ5^ʄ55555ʄ55ʄ55555ʄ5^^55ʄ5^55ʄ55ʄ5555ʄ55ʄ^555^5ʄ55^^ʨ55ʄ55ʄ55ʄ5^^^^555^^55ʄ^^5555^ʨ^55ʄ55ʄ5^^555ʄ^5^5쨄5^쨄55^^ʨ55^5ʄ55^^ʨ55^^쨄5^쨨^ʄ555ʄ5^5^ʄ𫫫ohb-*'-*'ohb::ff۶::ېff::ې::ff:۶f:ff:f:ff_5555_̅555_55̅55_5555_̅55555555___5555̅555_̅___5555_̅55555555_5𫫫ohb-*'-*'ohb:fې::f:::ff:ff:::ې:f::ff::555`5`Ϊ5`5``555``5555Ά55Ά555Ά55Ά55555555`𫫫ohb-*'-*'ohb:ې:fې:::666666·6666𫫫ohb-*'-*'ohb:ې:::ې::𫫫ohb-*'-*'ohb𫫫ohb-*'-*'ohb𫫫ohb-*'-*'ohb𫫫ohb-*'-*'ohb𫫫ohb-*'-*'ohb𫫫ohb-*'-*'ohb𫫫ohb-*'-*'멥rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺɻȺɻɻʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹɻɻɻɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹȺȺɻɻɻɻʼʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹȺȺȺȺȺȺȺɻɻɻɻʼ˽̾ͿͿ-*'-*'ذ¿¿¿¿¿¿¿¿¿¿¿¿οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'¿οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾ͿͿ㪣zuo]YT]YT^YU^YU^ZU^ZU^ZU]YU^YU]YU\XT]YT]YT\XT\XT\XT\XT[WS[WS[WS[WS[WS[WSZWR[WT[WT[WT[WT]YV]YV]YV]YV]YV]YV]YV]YV[WT[XT]ZV[XT[WT[WT[WT[WT]YV]YV^ZW^ZW^ZW^ZW^ZW&b&S&S&S'T(T (V!)V!*W"+X$-X%-Y%.Z'/Z'0[(0])1])1])1])1^)1])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fX`-*'-*'Ӫ¿U֣GKTӡXJΌ XԩJVڦI | |YLբULӡ IοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾̾a]Y߅}y.<꯵ܯޮ߮୵୵⭵㭷䭷䫹諹諹꫹뫹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쬺쬺쬺쬺쬺묺꫹諹諸筷䭵䭵㭵୵೹ୱ̏*.O-*'-*'وTX[{_vb¿UפHKTӢTإH ~XԪJYLԢ } | }WK }οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ顛ȿȿǾƾƾƾƽƽƽƼ~upżƽƽƽƾƾƽƾƾƾǾƾƾƾƾƾƾǾǿǿȿȿȿȿ(5r|r}p}p~p~ppppooonnlllllllllllllllllnnooopppp~p~t~ǞӗWZ-*'-*'ٍOSVZ|^¿U֤HKTӡWӨJ 麌 XԩJV٦I | | LUԢVyοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻɻɻɻɻɻ˽̾̾sniûĻĻûļļļżļûûººûͿͿͿzqk#.|dpdpdqdqcrcrcrbtbvbv`v`x`y`y`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`y`x`xbvbvbvbtcrcrcrdqdqpz &O-*'-*'ؿْKNQUX¿U{KTӢXKӢ 껎 |XԩJWK } } ŀUڦI ٤HοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺɻɻȺȺɻɻʼ̾̾Ϳfa\̿̾˾˾̾;̾Ϳ̾˾ʽʼʽʽɼȻɼȻǺǹǺǺǻǺǹunhǺǺǺǺǺǺǺǺǺǺǺǺǺǺǺȻȻȻȼȼȼȻȻȻ)|TbTbTbTbTdTeTeSfSfSfSiRiPiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiRiShSfSfSfTeTeTdTbTbXf>-*'-*'ٿٝTIMPSӮױ¿UإHKTӢTJϰKTӢ 껍 {LUԢX٦IYժK ŀ L פL ֤WۧI | οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻǹȺȺɻɻ˽̾̾]YUǼƻǼǼǼǼȼrnhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~pl÷øøø¶¶smh·····÷~xfVSfVSfVSfVSfVSfVSfVSfVSfVSfVS~yøøøøøø%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'ٿٺ}j]YZã˨¿V֤HVפHKTS~{ { إHTإHXԄJQ |  Lգ ~VzͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺǹǹǹǹȺȺɻʼ˽Ϳ^ZUùĺĺĺĻĻĻfVSfVSrlg׾fVSfVS"yHxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvvxxxxʭ'-J-*'-*'οοοοͿͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺȺȺǹǹǹǹǹǹǹǹɻɻȺɻɼʽ˽̾Ϳ^ZVჀ}fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk|||||||||||||~~~~Ͱ*0L-*'-*'οοοοͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʼ˽̾ͿͿ^ZV⅂fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރႏ₏傏恏恏聏omhYVfVShYVom聏肏悏傏₏⃏ރ݃ۃكׄքӄӄѴ.3N-*'-*'οοοͿͿͿͿ̾ͿͿͿͿͿͿͿͿͿͿͿ˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻ˼ʼʼʼʼɻɻɻɻɻɻǹǹǹǹǹǹǹǹȺȺȺɼɼɼɻʼʼ˽̾^ZV艆fVSfVSOW琙֐אؐؐܐܐߐ㐚䐚揚菚ꏚ뎚쎚쎚fVSfVSurfVSfVS쎚쏚쏚ꏚ菚琚䐚吚㐚ᐚߐݐܐِِػ49Q-*'///οͿͿͿͿ̾̾̾̾ͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻ˼˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹǹȺȺȺȻɼɼɻɻʼʼ˽Ϳ^ZVꋈ㛑fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST]蘠ؘژܘܘߘ☢䘢䘢蘢蘢뗢엢yufWUfWUfWUyuyufWUfWUfWUyu옢옢꘢阢蘢嘢嘢㘢ᘢߘݘݘ8=Sߠ///ddd.,*ͿͿ̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻ˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹȺȺȺȻȻȻɻɻɻɻʼ˽̾Ϳ^ZV퍊Zbꠦܠܠߠࠨ⠨㠨䠨矩蟩꟩쟩쟪ퟩ쟩韩頨蠩堩䠧㠧ᠧࠧ;@U.,*MMM.+(ͿͿ̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹȺȺȺȺȻȻȻȺȺɻɻɻʼ˽̾Ϳ^ZV폍_f즬ববব⦭䤭䤭礭褭꤮줮줮冷줭뤭餮礮妭䦭㦭᦭?BV硟-*'kkkͿͿ̾̾̾̾̾̾̾̾Ϳ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼ʼʼʼʼʼȺȺȺȺȺȺǹǹȺȺȻȻȻȻȺȺȺɻʼʼʼ˽˽˾̿^ZV퐍`i쬱଱ଲ㬳䬳䬳笳諳諳쪲쪲﫳쪲髳髳竳嫳嫲䫱?DYꠝkkk.+(.,*dcbdmBFZ/-+.+(lllppp-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'eeewwwtqsl-2.0/apps/help/tqslapp/pref-cab3.bmp0000664000076400007640000154506612231073120020177 0ustar rmurphyrmurphyBM66(<yyql\VRNIF/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)?;8LGCe^Zpid|tn|yql]WS/,)1/-󢟝1/-/,)GB?d]Yphdvq]WSοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺɻʼ˽̾̾Ϳ碟HC@f_[f_[-*'οοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳޢ-*'NIFWQN0.,οοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾.,*A=:-*(οοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿӠ-*(-*'-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫ohb-*'-*'ohb䏏𫫫䏏𫫫䏏𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppvv00Ҵppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppww00Զppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙ppp𫫫ppp1y֙Vyy11ָ֙Vy1ppp𫫫ppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָppp𫫫ohb-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عppp𫫫ppp1zz1عؚWz1zz11ع1zz1ppp𫫫ppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عppp𫫫ohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{ppp𫫫pppڜ1Wڻ{{{11{{11ڻ1{Wppp𫫫pppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻppp𫫫ohb-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{ppp𫫫ppp{{11ۼۜXX{11X{{{1ۼppp𫫫ppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼppp𫫫ohb-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝppp𫫫ppp}}22ݾݝYY}22222ݾ}ppp𫫫ppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾppp𫫫ohb-*'-*'ohbppp5555Ʉ55Ʉ55^555^^ppp𫫫ppp5^Ʉ55Ʉ5555Ʉppp𫫫ppp55Ʉ55Ʉ55^^^^55Ʉ55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5ʄ5^ʄ555ʄ55ʄppp𫫫ppp5^^^55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5̅555__ppp𫫫ppp__55ppp𫫫ohb-*'-*'ohbppp55ppp𫫫pppppp𫫫ppp55ppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohb葑𫫫葑𫫫葑𫫫ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫ohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohbͿ-*'-*'ohbohbͿ-*'-*'ohbohbο-*'-*'ohbohbͿ;-*'-*'ohbohbͿͿ;-*'-*'ohbohbͿͿ;;-*'-*'ohbohbͿ;;̽-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿ;;˼-*'-*'ohb䏏ohbͿ;̽˼-*'-*'ohbuuuuuuohb;̽˼˼-*'-*'ohbppppppohb;˼˼ʻ-*'-*'ohbppppppohb̽˼˼ʻ-*'-*'ohbppppppohb̽˼˼˼-*'-*'ohbpppy11ָyy1y1yy11ָy1y1ָVy1y1y1ָpppohb˼˼˼˼-*'-*'ohbpppzz11عؚWؚWWؚWzz11عWؚWzW1ؚWؚWpppohb˼˼˼˽-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb˼˼˽˽-*'-*'ohbppp{{11ۼۜXX{1X{{11{1Xۜ{{11ۼ{1Xۜpppohb̽˽˽˼-*'-*'ohbppp}}22ݾݝYYݝYYݝ}}22}}22ݾYYݝ}}22ݾ}}22ݾYYݝ}}22ݾpppohb˼˽˼˼-*'-*'ohbppp5555Ʉ55Ʉ55Ʉ55Ʉ5Ʉ555Ʉpppohb˽˼˼̽-*'-*'ohbppp555^5555pppohb˽˼˼̽-*'-*'ohbppp5_5555pppohb˼˼̽̽-*'-*'ohbppp55pppohb˼̽̽˽-*'-*'ohbppppppohb̽̽˽˽-*'-*'ohbppppppohb̽̽˽̾-*'-*'ohbppppppohb̽˽̾;-*'-*'ohbuuuuuuohb˽˽;̽-*'-*'ohb葑ohb˽̾̽̾-*'-*'ohbwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾;̾Ϳ-*'-*'ohbohb;̾ͿͿ-*'-*'ohbohb̽̾ͿͿ-*'-*'ohbohb̾ͿͿ-*'-*'ohbohbͿ̾-*'-*'ohbohb̾Ϳ-*'-*'ohbohbͿ-*'-*'ohbohb-*'-*'ohbohbͿ-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohbf:ې:f۶::ېf:f::f:ې::f::::ې::::ې䏏ohb-*'-*'ohbf:ې::ې::ff:f:f:fff:f:::ېf:::ې:::::ې::fff:uuuuuuohb-*'-*'ohb::ې::ې::::۶fff::fېfffff۶ې:f::::ې::::::ېppppppohb-*'-*'ohb::ې::ې::fff:ې:ff:::f:f:f:f:::::ې::ff:fppppppohb-*'-*'ohb::ې::ې::ff::ېf::ې:fې:fff:::ff:ېppppppohb-*'-*'ohb::ې::ې::::۶:f::::ې:fېfffې:fې:::::ې::::ې::pppy11ָyVVV1y11yy11ָVy1yV1֙yV1֙yV1֙pppohb-*'-*'ohb::ې::ې:::ffې::f:fffff::::f::::::ې::::ېf:pppzz11عؚ1Wعz1zz1zz11عzW1ؚzW1ؚzW1ؚzW1ؚpppohb-*'-*'ohb:::f۶:fffffff::::ېff:::::f::ېppp{{11ڻ{{11ڻ{{11{{11ڻ{{11ڻpppohb-*'-*'ohbppp{{11ۼ{{11ۼ{{11{{11ۼ{{11ۼpppohb-*'-*'ohbppp}2}2ݾYݝY}}22}}22ݾ}}22ݾpppohb-*'-*'ohbppp5555Ʉ555Ʉ5pppohb-*'-*'ohbppp555555pppohb-*'-*'ohbppp55̅55̅55̅55pppohb-*'-*'ohbppp55pppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohb::ې:f::ېf:f:::::ې::::::::::ې::::ېuuuuuuohb-*'-*'ohb::ff::::ff:f:f::ff::::::::::ې::fff:葑ohb-*'-*'ohb::::ې::::::۶fff:::ېf:::::::::::ې::::::ېwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb::ff۶:::ff:::fff:ې:ff:::::::::::::ې::ff:fohb-*'-*'ohb::ff۶::::ff::ې::f:::::f:::f:::ff:ېohb-*'-*'ohb::::ې::::::۶:f::::ff::::::f:::::ې::::ې::ohb-*'-*'ohb:::f:::::ffې::f::f:::::fffې:::::ې::::ېf:ohb-*'-*'ohb:f:::fffff::ې:::::::ې:::::f::ېohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𠠠𠠠𠠠ohb-*'-*'ohb𠠠𠠠𠠠ãS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<6φ4_φ445Lj45><..>> / />>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>9“9Ħohb-*'-*'ohbƨX<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-*'-*'ٿٝTIMPSӮױ¿UإHKTӢTJϰKTӢ 껍 {LUԢX٦IYժK ŀ L פL ֤WۧI | οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻǹȺȺɻɻ˽̾̾]YUǼƻǼǼǼǼȼrnhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~pl÷øøø¶¶smh·····÷~xfVSfVSfVSfVSfVSfVSfVSfVSfVSfVS~yøøøøøø%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'ٿٺ}j]YZã˨¿V֤HVפHKTS~{ { إHTإHXԄJQ |  Lգ ~VzͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺǹǹǹǹȺȺɻʼ˽Ϳ^ZUùĺĺĺĻĻĻfVSfVSrlg׾fVSfVS"yHxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvvxxxxʭ'-J-*'-*'οοοοͿͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺȺȺǹǹǹǹǹǹǹǹɻɻȺɻɼʽ˽̾Ϳ^ZVჀ}fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk|||||||||||||~~~~Ͱ*0L-*'-*'οοοοͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʼ˽̾ͿͿ^ZV⅂fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރႏ₏傏恏恏聏omhYVfVShYVom聏肏悏傏₏⃏ރ݃ۃكׄքӄӄѴ.3N-*'-*'οοοͿͿͿͿ̾ͿͿͿͿͿͿͿͿͿͿͿ˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻ˼ʼʼʼʼɻɻɻɻɻɻǹǹǹǹǹǹǹǹȺȺȺɼɼɼɻʼʼ˽̾^ZV艆fVSfVSOW琙֐אؐؐܐܐߐ㐚䐚揚菚ꏚ뎚쎚쎚fVSfVSurfVSfVS쎚쏚쏚ꏚ菚琚䐚吚㐚ᐚߐݐܐِِػ49Q-*'1,$οͿͿͿͿ̾̾̾̾ͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻ˼˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹǹȺȺȺȻɼɼɻɻʼʼ˽Ϳ^ZVꋈ㛑fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST]蘠ؘژܘܘߘ☢䘢䘢蘢蘢뗢엢yufWUfWUfWUyuyufWUfWUfWUyu옢옢꘢阢蘢嘢嘢㘢ᘢߘݘݘ8=Sߠ20.g\K.,*ͿͿ̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻ˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹȺȺȺȻȻȻɻɻɻɻʼ˽̾Ϳ^ZV퍊Zbꠦܠܠߠࠨ⠨㠨䠨矩蟩꟩쟩쟪ퟩ쟩韩頨蠩堩䠧㠧ᠧࠧ;@U.,*QNKw_.+(ͿͿ̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹȺȺȺȺȻȻȻȺȺɻɻɻʼ˽̾Ϳ^ZV폍_f즬ববব⦭䤭䤭礭褭꤮줮줮冷줭뤭餮礮妭䦭㦭᦭?BV硟-*'qmiiyYͿͿ̾̾̾̾̾̾̾̾Ϳ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼ʼʼʼʼʼȺȺȺȺȺȺǹǹȺȺȻȻȻȻȺȺȺɻʼʼʼ˽˽˾̿^ZV퐍`i쬱଱ଲ㬳䬳䬳笳諳諳쪲쪲﫳쪲髳髳竳嫳嫲䫱?DYꠝqmix'duV.+(.,*dcbdmBFZ/-+.+(rnj}'q$c rVdQ,-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'jgc}yutqsl-2.0/apps/help/tqslapp/pref-cab2.bmp0000664000076400007640000047527612231073120020202 0ustar rmurphyrmurphyBMz6(zAct1*@@/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)" HH>```kkkBfv/,)1/-򢟝1/-/,)EEE```Mll```οοοοοοοοͿͿͿͿͿͿ̾̾ͿͿ梟iK*jjj-*'οοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿܢ-*'QQQZZZ0.,οοοοοοοͿͿͿͿͿͿͿͿͿͿͿͿ.,*DDD///οοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿѠ///-*'-*'-*'ࣝohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏䏏ohb-*'-*'ohbuuuuuuuuuuuuohb-*'-*'ohbppppppppppppohb-*'-*'ohbppppppppppppohb-*'-*'ohbppppppppppppohb-*'-*'ohbppp1y֙Vyy11ָ֙Vy1pppppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppohb-*'-*'ohbppp1zz1عؚWz1zz11ع1zz1pppppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppohb-*'-*'ohbpppڜ1Wڻ{{{11{{11ڻ1{Wppppppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb-*'-*'ohbppp{{11ۼۜXX{11X{{{1ۼpppppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppohb-*'-*'ohbppp}}22ݾݝYY}22222ݾ}pppppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppohb-*'-*'ohbppp5^Ʉ55Ʉ5555Ʉpppppp55Ʉ55Ʉ55^^^^55Ʉ55pppohb-*'-*'ohbppp5ʄ5^ʄ555ʄ55ʄpppppp5^^^55pppohb-*'-*'ohbppp5̅555__pppppp__55pppohb-*'-*'ohbppppppppp55pppohb-*'-*'ohbppppppppppppohb-*'-*'ohbppppppppppppohb-*'-*'ohbppppppppppppohb-*'-*'ohbuuuuuuuuuuuuohb-*'-*'ohb葑葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohbο-*'-*'ohbohbοο-*'-*'ohbohbοοο-*'-*'ohbohbοοο-*'-*'ohbohbοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοͿ-*'-*'ohbohbοοοͿ-*'-*'ohbohbοοοͿ-*'-*'ohbohbοοͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿͿ̾-*'-*'ohb::ېohbͿͿ̾̾-*'-*'ohbfff:ohbͿ̾̾̾-*'-*'ohb::::ېohbͿ̾̾̾-*'-*'ohbff:fohbͿ̾̾̾-*'-*'ohbf:ېohb̾̾̾̾-*'-*'ohb::ې::ohb̾̾̾̾-*'-*'ohb::ېf:ohb̾̾̾̾-*'-*'ohb::ېohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb½½ohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb6````666·66·666·66`6`6666Ϋ`·666```6666666·66·66```66666`66``666·66·66·666666·6666·ohb̾̾̾̾-*'-*'ohb6```Ϋ666·6·66·666`666·`666·6``6Ϋ`6666`·6``6`·6·66666``666`·6·666`6`66·6·66·66·66·666Ϋ```6666·ohb̾̾̾Ϳ-*'-*'ohb6`·66·66·66·66`````Ϋ·6`·66`6Ϋ66666`6666666666·6666·6666666·`66·6666·66·66·66·66`6Ϋ6666ohb̾̾̾Ϳ-*'-*'οohb6666·66·666·6`6`6`6`666`6Ϋ666`6`Ϋ666666666`Ϋ66·666666·66·66·6666·66·66·66·66`6Ϋ6`Ϋ66ohb̾ͿͿ̾-*'-*'οohb`6``66·666·6`·6`````6Ϋ`6`66`6``66``666`Ϋ66``66·66``6666``66·666666·`6·`666·6·6``666`66·ohb̾ͿͿ̾-*'-*'ohb66·66·66·666`·```·6`·66`66``Ϋ66`6·66·666666·66·66·6666`Ϋ`66·6666`666`Ϋ`6``666`6·66·66``66·ohbͿͿͿ̾-*'-*'ohb6```66·66``6666`666666666666`6666`·6666ohbͿͿ̾̾-*'-*'ohb``66·666666·``66666`Ϋ6666666·66666ohbͿ̾̾̾-*'-*'ohb66·666666666666ohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'οohbohb̾̾̾˽-*'-*'οοohbohb̾̾˽˽-*'-*'οοοohbohb̾˽˽˽-*'-*'οοοohbohb̾˽˽˽-*'-*'οοοοohbohb˽˽˽˽-*'-*'οοοohbohb˽˽˽̽-*'-*'οοohbohb˽˽̾̽-*'-*'Ϳohbohb˽̾̾̾-*'-*'Ϳohbohb˽̾̾̾-*'-*'ohbohb̾̾̾̽-*'-*'ohbohb̽̾̽̽-*'-*'ohbohb̾̽̽;-*'-*'ohbohb̾̽̽;-*'-*'ohbohb̽̽;̽-*'-*'ohbohb̽;̽˽-*'-*'ohbohb;̽˽˽-*'-*'ohbohb;̽˽̾-*'-*'ohbohb;˽̾;-*'-*'ohbƧƧohb˽˽;̽-*'-*'ohb栠ܻ栠ܻohb˽̾̽̾-*'-*'ohbѹà6666·66à``6666·66ohb̾;̾Ϳ-*'-*'ohbƻ쫣W>J5J4W>򻻺6666·66ƻ򻻺``6666·66ohb;̾ͿͿ-*'-*'ohb𥥤W?]?ǃǂ ]= X?ݥ6666·66𥥤ݥ6``66666·66ohb̽̾ͿͿ-*'-*'ohb𒒑򜐂G3Ə"ѝ јƄH36666·66𒒑¾```66666·66ohb̾ͿͿ-*'-*'ohb𒒑}_K0Ր]Ѣ(NJH3򒒑666`𒒑򽹴򒒑````666`ohbͿ̾-*'-*'ohb𥥥ľ]D$Ʋi\@W?ܥ6666·66𥥥þܥ6·6`·66666·66ohb̾ͿͿ-*'-*'ohbƺ颗`G'xcHfQ6X@ 뺺6666·66ƺ齸½뺺66·66·6666·66ohbͿͿ-*'-*'ohbſà66666`ƿà666666666`ohbͿ-*'-*'ohb桡ۺ桡ۺohbͿ-*'-*'ohbƧƧohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb``66ohb-*'-*'ohb`666ohb-*'-*'ohb6`6`6666`·666`·6`·6`·666·6`66ohb-*'-*'ohb6`````6Ϋ`6666·`6``·`66·`6`66·666`6``ohb-*'-*'ohb6`·66`6Ϋ6666·66·66``6666````666`66ohb-*'-*'ohb6666`6Ϋ6666·66·6```6666````666`6`ohb-*'-*'ohb`6``6Ϋ`6``6·66Ϋ``66`6``6666````66·````66ohb-*'-*'ohb66·6`66``6·666·666·6666`6``666``66·ohb-*'-*'ohb6```666666ohb-*'-*'ohb``666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵf:ې:f۶::ېf:f::f:ې::fɤohb-*'-*'ohbϵf:ې::ې::ff:f:f:fff:f:::ېf:::ې:ɤohb-*'-*'ohbϵ::ې::ې::::۶fff::fېfffff۶ې:fɤohb-*'-*'ohbϵ::ې::ې::fff:ې:ff:::f:f:f:f:ɤohb-*'-*'ohbϵ::ې::ې::ff::ېf::ې:fې:fffɤohb-*'-*'ohbϵ::ې::ې::::۶:f::::ې:fېfffې:fې:ɤohb-*'-*'ohbϵ::ې::ې:::ffې::f:fffff::::f::ɤohb-*'-*'ohbϵ:::f۶:fffffff::::ېffɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbĭ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\ĭohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb6`6`66`66666·66·6666`6```666·66·66·66·66·66·ohb-*'-*'ohb6```6·6`·666`66666`6666666`6·666·6·66·66·66``66·ohb-*'-*'ohb6`·6`·66·666·`666666``66666·`6666·66·66·66·66·66ohb-*'-*'ohb6666``Ϋ66·66·666666``6666·66·66·66·66·66·666`ohb-*'-*'ohb`666``Ϋ66``666666``6666``66``66·`6·`6``66·66·ohb-*'-*'ohb66·6`·66·66`Ϋ`666666``6666`Ϋ`6666·`666`Ϋ`6`66·66·ohb-*'-*'ohb6```6·6`·6`6666`·6666666`·``66`6666`·66ohb-*'-*'ohb``6·66·6`666```666·666·66·666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb666`·```666```6666````66666·6666·66·66·6`6`6`66`66666·66·66ohb-*'-*'ohb6``66`·6·66`·6·66```Ϋ666·6·666Ϋ`6666·66·66``6Ϋ`6```6·6`·666`66666`66666ohb-*'-*'ohb6·66666·66666`·66·66·66`6Ϋ6666·66·66·66`66`·6`·66·666·`666666``66ohb-*'-*'ohb66Ϋ6`·6666·66666666·66`6Ϋ6666·66·66·66`66666``Ϋ66·66·666666``66ohb-*'-*'ohb66·`6Ϋ``66``66`6``66·6·66`66·66·66``6Ϋ``666``Ϋ66``666666``66ohb-*'-*'ohb6·6`·666·6666·66·`666`6·66``Ϋ66·66·66·6`66·6`·66·66`Ϋ`666666``66ohb-*'-*'ohb`6666`·66666```6666·666```6·6`·6`6666`·6666666`·``66ohb-*'-*'ohb666666``6666·66·66``6·66·6`666```666·666·6ohb-*'-*'ohb66666666·66ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'V_*3f(P(P!)Q"*S#+T$-U$-V&.W'/X(0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])2])2])2[)2[)2Z)1Y(0X'/W%.V%.U$,T#+S")Q (P (P+4gX`-*'-*'  ƂKNQפTOئȆăăNRެSȈ',Mx|˳߬߬߬⬴䬶䪷窸誹諹꫹뫹쫹쫹쫹쫹쬻ꬻꬺ鮹殶殶家⮶ⴺ⮲y}).N-*'-*' UXNץNץ€R€ODŽDžONެNޫNĄĄNެOKޭP~ĆXJ֦VY}so}o}ooonnnnnllllllmmmmmmmmmmmoopppqqqqquɟՄX[-*'-*' ƂNT֤XլL€MQԯOQԯOăăMޫONӰRJXJا &Noycpcpbqbqbqasauavav`x_x`y`z`z`z`z`{a{a{a{a{a{a{a|a|a|a|a|a|a{azazcxcwcwcudsdsdsererq{!&O-*'-*' ŀ ŀƂNTץX֬MÁQԯPQկPńńNެONTڨX٩WJا>WeSaSaScSdSdReReRfRhQiRiPjPjPjPjPkPkQkQkQkQkQkQkQlQlQlQlQlQlQlSkSjTiTgTgTgUfUfUeUcUcYg>-*'-*' L ֤NץNץQTÁNăެNSڧNެOTKکŇWJا;GUGUGUGUFUFUEWCXCZCZCZD\D\D\D\D\D]WYhXUhXUhXUWYE]WYhXUhXUhXUWYE^E^E^E]E[E[E[EZGYHWHWIWIWIWIW;-*'-*'V|K XQLNN֤QLN€QܩKȆȇMąKտJȉ 9;K;K;K;L;M;M;M;N;M;N[[>Uohb-*'-*'ohb𠠠𠠠𠠠<>>-*'-*'ٿٝTIMPSӮױ¿UإHKTӢTJϰKTӢ 껍 {LUԢX٦IYժK ŀ L פL ֤WۧI | οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻǹȺȺɻɻ˽̾̾]YUǼƻǼǼǼǼȼrnhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~pl÷øøø¶¶smh·····÷~xfVSfVSfVSfVSfVSfVSfVSfVSfVSfVS~yøøøøøø%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'ٿٺ}j]YZã˨¿V֤HVפHKTS~{ { إHTإHXԄJQ |  Lգ ~VzͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺǹǹǹǹȺȺɻʼ˽Ϳ^ZUùĺĺĺĻĻĻfVSfVSrlg׾fVSfVS"yHxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvvxxxxʭ'-J-*'-*'οοοοͿͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺȺȺǹǹǹǹǹǹǹǹɻɻȺɻɼʽ˽̾Ϳ^ZVჀ}fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk|||||||||||||~~~~Ͱ*0L-*'-*'οοοοͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʼ˽̾ͿͿ^ZV⅂fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރႏ₏傏恏恏聏omhYVfVShYVom聏肏悏傏₏⃏ރ݃ۃكׄքӄӄѴ.3N-*'-*'οοοͿͿͿͿ̾ͿͿͿͿͿͿͿͿͿͿͿ˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻ˼ʼʼʼʼɻɻɻɻɻɻǹǹǹǹǹǹǹǹȺȺȺɼɼɼɻʼʼ˽̾^ZV艆fVSfVSOW琙֐אؐؐܐܐߐ㐚䐚揚菚ꏚ뎚쎚쎚fVSfVSurfVSfVS쎚쏚쏚ꏚ菚琚䐚吚㐚ᐚߐݐܐِِػ49Q-*'///οͿͿͿͿ̾̾̾̾ͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻ˼˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹǹȺȺȺȻɼɼɻɻʼʼ˽Ϳ^ZVꋈ㛑fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST]蘠ؘژܘܘߘ☢䘢䘢蘢蘢뗢엢yufWUfWUfWUyuyufWUfWUfWUyu옢옢꘢阢蘢嘢嘢㘢ᘢߘݘݘ8=Sߠ///ddd.,*ͿͿ̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻ˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹȺȺȺȻȻȻɻɻɻɻʼ˽̾Ϳ^ZV퍊Zbꠦܠܠߠࠨ⠨㠨䠨矩蟩꟩쟩쟪ퟩ쟩韩頨蠩堩䠧㠧ᠧࠧ;@U.,*MMM.+(ͿͿ̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹȺȺȺȺȻȻȻȺȺɻɻɻʼ˽̾Ϳ^ZV폍_f즬ববব⦭䤭䤭礭褭꤮줮줮冷줭뤭餮礮妭䦭㦭᦭?BV硟-*'kkkͿͿ̾̾̾̾̾̾̾̾Ϳ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼ʼʼʼʼʼȺȺȺȺȺȺǹǹȺȺȻȻȻȻȺȺȺɻʼʼʼ˽˽˾̿^ZV퐍`i쬱଱ଲ㬳䬳䬳笳諳諳쪲쪲﫳쪲髳髳竳嫳嫲䫱?DYꠝkkk.+(.,*dcbdmBFZ/-+.+(lllppp-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'eeewwwtqsl-2.0/apps/help/tqslapp/pref-cab.htm0000664000076400007640000001130412231073120020104 0ustar rmurphyrmurphyAdding and Deleting Cabrillo Contest Definitions

Adding and Deleting Cabrillo Contest Definitions

TQSL can digitally sign and submit Cabrillo logs for the set of contests described in the Configuration Data file. When directed to digitally sign a Cabrillo log for a contest that is not in this set, TQSL will attempt to extract the necessary information from each QSO by searching for valid callsigns. If this process succeeds, the log will be digitally signed; if this process fails, you will be prompted to define a Contest Definition that specifies

  • the contest's Type: HF, or VHF (and above)
  • the contest's Field: the numeric designator of the field of a QSO line in a Cabrillo log file that contains the callsign of the station that was worked

The Cabrillo contest log file format varies depending on the particular contest; details of the Cabrillo format can be found at http://www.kkn.net/~trey/cabrillo/ .

Note that Cabrillo fields are numbered with 1 being the first field after the "QSO:" line tag. For example:

QSO: 21042 CW 1997-11-01 2101 N5KO     1 B 74 SCV WA2VRR   1 A 74 VA
In the ARRL Sweepstakes Cabrillo log line immediately above, the callsign worked (WA2VRR) appears in field 10.

Use the Preferences dialog's Cabrillo Specs tab to specify the required information.

Adding a Cabrillo Contest Definition
To specify Type and Field information for a contest,
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display TQSL's Preferences dialog.
2.In the Preferences dialog, select the Cabrillo Specs tab; TQSL will display any Cabrillo information you've already defined.
  

In the above example, a Cabrillo file that contains DL-DX-RTTY in the CONTEST line will be treated as an HF contest that contains the callsign worked in field 8 of each QSO line.

3.Click the Add button, and the Add Contest dialog will appear.
4.In the Add Contest dialog,

   4.aType the CONTEST Name as it will appear in the CONTEST line of the Cabrillo log file.
   4.bCheck HF or VHF box as appropriate (VHF includes UHF and microwave contests).
   4.cType the field number of the callsign worked field.
    
   4.dClick the OK button:
    
    Now, a Cabrillo file with a contest name of JIDX-CW will also be treated as an HF contest that contains the callsign worked in field 8 of each QSO line.

Deleting a Cabrillo Definition
To delete a Cabrillo contest definition, select it by clicking on the entry in the list, then click the Delete button.
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display TQSL's Preferences dialog.
2.In the Preferences dialog, select the Cabrillo Specs tab; TQSL will display the Cabrillo information you've already defined.
3.Select the definition you wish to delete, and click the Delete button.

tqsl-2.0/apps/help/tqslapp/pref-adi3.bmp0000664000076400007640000154506612231073120020207 0ustar rmurphyrmurphyBM66(<yyql\VRNIF/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)?;8LGCe^Zpid|tn|yql]WS/,)1/-󢟝1/-/,)GB?d]Yphdvq]WSοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺɻʼ˽̾̾Ϳ碟HC@f_[f_[-*'οοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳޢ-*'NIFWQN0.,οοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾.,*A=:-*(οοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿӠ-*(-*'-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuu𫫫ohb-*'-*'ohb䏏𫫫䏏𫫫䏏𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppvv00Ҵppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppww00Զppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙ppp𫫫ppp1y֙Vyy11ָ֙Vy1ppp𫫫ppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָppp𫫫ohb-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عppp𫫫ppp1zz1عؚWz1zz11ع1zz1ppp𫫫ppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عppp𫫫ohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{ppp𫫫pppڜ1Wڻ{{{11{{11ڻ1{Wppp𫫫pppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻppp𫫫ohb-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{ppp𫫫ppp{{11ۼۜXX{11X{{{1ۼppp𫫫ppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼppp𫫫ohb-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝppp𫫫ppp}}22ݾݝYY}22222ݾ}ppp𫫫ppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾppp𫫫ohb-*'-*'ohbppp5555Ʉ55Ʉ55^555^^ppp𫫫ppp5^Ʉ55Ʉ5555Ʉppp𫫫ppp55Ʉ55Ʉ55^^^^55Ʉ55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5ʄ5^ʄ555ʄ55ʄppp𫫫ppp5^^^55ppp𫫫ohb-*'-*'ohbppp555555ppp𫫫ppp5̅555__ppp𫫫ppp__55ppp𫫫ohb-*'-*'ohbppp55ppp𫫫pppppp𫫫ppp55ppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbpppppp𫫫pppppp𫫫pppppp𫫫ohb-*'-*'ohbuuuuuu𫫫uuuuuu𫫫uuuuuu𫫫ohb-*'-*'ohb葑𫫫葑𫫫葑𫫫ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𫫫ohb-*'-*'ohb𫫫𫫫𫫫ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohbͿ-*'-*'ohbohbͿ-*'-*'ohbohbο-*'-*'ohbohbͿ;-*'-*'ohbohbͿͿ;-*'-*'ohbohbͿͿ;;-*'-*'ohbohbͿ;;̽-*'-*'ohbohbͿ;;˼-*'-*'ohbohbͿ;̽˼-*'-*'ohbohb;̽˼˼-*'-*'ohbohb;˼˼ʻ-*'-*'ohbohb̽˼˼ʻ-*'-*'ohbohb̽˼˼˼-*'-*'ohbohb˼˼˼˼-*'-*'ohbohb˼˼˼˽-*'-*'ohbohb˼˼˽˽-*'-*'ohbohb̽˽˽˼-*'-*'ohbohb˼˽˼˼-*'-*'ohbohb˽˼˼̽-*'-*'ohbohb˽˼˼̽-*'-*'ohbohb˼˼̽̽-*'-*'ohbohb˼̽̽˽-*'-*'ohbohb̽̽˽˽-*'-*'ohbohb̽̽˽̾-*'-*'ohbohb̽˽̾;-*'-*'ohbohb˽˽;̽-*'-*'ohbohb˽̾̽̾-*'-*'ohbohb̾;̾Ϳ-*'-*'ohbohb;̾ͿͿ-*'-*'ohbohb̽̾ͿͿ-*'-*'ohbohb̾ͿͿ-*'-*'ohbohbͿ̾-*'-*'ohbohb̾Ϳ-*'-*'ohbohbͿ-*'-*'ohbohb-*'-*'ohbohbͿ-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbpppy11ָyy1y1yy11ָy1y1ָVy1y1y1ָpppohb-*'-*'ohbpppzz11عؚWؚWWؚWzz11عWؚWzW1ؚWؚWpppohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb-*'-*'ohbppp{{11ۼۜXX{1X{{11{1Xۜ{{11ۼ{1Xۜpppohb-*'-*'ohbppp}}22ݾݝYYݝYYݝ}}22}}22ݾYYݝ}}22ݾ}}22ݾYYݝ}}22ݾpppohb-*'-*'ohbppp5555Ʉ55Ʉ55Ʉ55Ʉ5Ʉ555Ʉpppohb-*'-*'ohbppp555^5555pppohb-*'-*'ohbppp5_5555pppohb-*'-*'ohbppp55pppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohbwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbf3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3ohb-*'-*'ohb3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fohb-*'-*'ohbf3Z3333Z3Z33ZZ333333333333333333333Z33ZZ3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333ohb-*'-*'ohb33Z3333ZZ3333333333333333Z333333Z333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fohb-*'-*'ohbf3Z33Z3333333ZZ333333333333333333333333ZZ3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333ohb-*'-*'ohb33Z3ZZ333333333333Z333333333Z33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fohb-*'-*'ohbf3ZZZ33333Z3ޠZZ3333333333333333333333Z3ޠZZ3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb333Z333333333333333333Z33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333f䏏ohb-*'-*'ohbf333ZZ333Z33Z3333333333333333Z333Z33Z333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333uuuuuuohb-*'-*'ohb33333Z333Z3333333333333333333333333Z333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fppppppohb-*'-*'ohbf3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333ppppppohb-*'-*'ohb3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333fppppppohb-*'-*'ohbf3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3f3pppyy11ָ֙1VָyVVV1y11ָVVV1y11ָyV1֙yV1֙yV1֙pppohb-*'-*'ohbpppع1zؚWWz1ع1Wعz1zz1ع1Wعz1zz1عzW1ؚzW1ؚzW1ؚpppohb-*'-*'ohbppp1{{1{{11ڻ{{11{{11ڻ{{11ڻpppohb-*'-*'ohb:f::::ې::fې:f:::::ې::fې:ff:fppp{{11ۼ1Xۼ{{{11ۼ{{11{{11ۼ{{11ۼpppohb-*'-*'ohb::f:ې::f:::ې:::ې:f:::f:::ې:::ې:fې:fې::pppݾ22}ݾ}Y}2ݾYݝY}}22ݾYݝY}}22ݾpppohb-*'-*'ohb::ff۶::ff۶:::۶f:f::ff۶:::۶fff::ppp5Ʉ5^Ʉ555Ʉ55pppohb-*'-*'ohb::::::ff::f::ې:ff::ff::f::fې::ppp^5555^ʄ5555pppohb-*'-*'ohb::ې:::ې:ff:::::ې:f:::ې:ff:::::ې:f::ppp555555pppohb-*'-*'ohb::ff::ffff::::ېf:::ffff::::ېff::ppp5555pppohb-*'-*'ohb::::ې::f::fېff::ې::ېf:::f::fېff::ې::ېff::ې::ppppppohb-*'-*'ohb:f:f:ې:::ff:f:ې:::ffff:fppppppohb-*'-*'ohbppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohbwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohb::::ffohb-*'-*'ohb::::ffohb-*'-*'ohb:f:ff:::fې:fې::f::ې::ې:::::f::ې:f۶::::ې::ې::ې:ffff:::ې::::ې::ې::fff::::f:f::ې::::f:fې:::ېohb-*'-*'ohb:fff۶f::ې:ېf::ېf:ff:۶f::ې::ې:::ff:ې::ff::ې::::ې::ې::ff:۶f:fې:ې:ff::ې::ې::ې:::ې:ې::f:ې::f:ې::ې:::::fې::ېf::ې::ېohb-*'-*'ohb:fې::::ff::ې::f:۶::ې::ې:::ې:::::ې::ې::::ې::ې::ې::f:۶::::ې::::ې::ې::::ې::ې:::f:::f::ې::::fې:::ffohb-*'-*'ohb::::::ff::ې::f:۶::ې::ې::::۶:fې::ff::ې::::ې::ې::ې::f:۶:::::f::ې::ې::ې::ې:::f:::f::ې::::ې::::ffohb-*'-*'ohbf:::::f:ff::۶ff:۶f::ېf:ېf:::ېf:ې::ff::ې:f::ېf:ېf:ff:۶fff::ff::::ېf:ېf:ff::ېff۶::ېff۶:::ff:ff::f:ff::ېohb-*'-*'ohb::ې:::::::ې::ff:::f۶f:f:ې:fې:::::ې::ې::f:::f۶f:f:f::ې::ېf:::f۶f:f::ېf:::fff:::ff::ې::ff::::ې::ېohb-*'-*'ohb:fff::f::::fې:::f::ې::::ohb-*'-*'ohbff:::::f:f۶:f::::ohb-*'-*'ohb::ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ϕ󕌉󕌉𫫫ohb-*'-*'ohb𕌉ѕ󕌉󕌉𫫫ohb-*'-*'ohb𕌉vv00Ҵҕvv00ҴTҖT𫫫ohb-*'-*'ohb𕌉ww00Զԕww00ԶUw0Զ𫫫ohb-*'-*'ohb𕌉1zؚWz1WؚWWW1z11عz1Wؚzz11عzz11عWz1ؕ1zWWWW1z11z1z1عzz11عzz11zz11zz11عz1Wؚع1z1عzz1Wؚz1z1عz1WWz1z11عWz1عz1z1عWz11WعzWz1عz1Wؚzz11عzz11عWz1zz11عzz11عz1WؚWؚWWWؚع11zعz𫫫ohb-*'-*'ohb𕌉1{{1ڻڜW{1{{11ڻW{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڕ1{WڜWW{{11ڻ1{{1{{11ڻ1{W{{11ڻ{{11{{11{{11ڻWڜW1{W{ڜW1{{11{{11ڻW{1ڻWڜWڻ1{ڜW{ڻ{Wڻ11{ڻ{{11ڻڜW{1ڻWڜW{W1ڜ{11W{1W{WWWڻ{WڜW1{W{{11ڻ{{11ڻW{1{{11ڻ{{11ڻڜWڜW1{WڜWWڜ1Wڻ{{1{1𫫫ohb-*'-*'ohb𕌉1Xۼ{{{11{{11ۼۜ1Xۼ{{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜە:::f::ې:f۶::::::ې:ffff:::ې::fې:1Xۼ{{11ۼ{{{11{{11ۼ{X1{{11ۼ{{11{{11{{11{{11ۼ{X1ۜۜXX{{11ۼۜ1X{{{11ۼ{{11ۼۜXXۜ{11ۼ1{{{X{11{{11ۼ{{11ۼ1{X{1XۼX1{XۜX{{11ۼ{X1{{11ۼ{{111{X{{11ۼ{{11ۼ{{11ۼ{X1ۜX{1XXXXۜ𫫫ohb-*'-*'ohb𕌉}22ݾݝYY}}22ݾݝ2Yݾ}}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝݕ:ff:ې::ff::ې::::::ff:۶f:fې:ې:ffېf::ې}22ݾ}2}2}}22ݾ}Y2}}22ݾ}}22}}22}}22}}22ݾ}Y2ݝYY}}22ݾݝ2Y}}2Y}}22ݾݝYYݝ}22ݾ}}22}}22}2Yݝ}}22ݾ2Yݾ}YY}Y2}ݝY2}}22ݾ}Y2}}22ݾ}2Yݝ}2}2ݾ}}22ݾ}}22ݾ}Y2ݝ2}}2ݝYYݝYݝY𫫫ohb-*'-*'ohb𕌉55^^ɨ55Ʉ^^먄55Ʉ55^^5ɨ^5^^5^5^^때:ې:::::ې::ې::::ېf:::ې::f:۶::::ې::ff^5^^55Ʉ5Ʉ55^55Ʉ55Ʉ55^^5ɨ^^^55Ʉ^^^^555^^5^^55^^55^^55Ʉ55ɨ^^5^^^^5^^^5ɨ^5^55^5555Ʉ55^^^5ɨ^^555Ʉ^^^^𫫫ohb-*'-*'ohb𕌉5^ʄ55^555^^5^^555ʄ5^쨄55^^55알::۶:fې::ff::ې::::ff::ې::f:۶:::::fff55ʄ55ʄ^555^5ʄ55^^ʨ55ʄ55ʄ55ʄ5^^^^555^^55ʄ^^5555^ʨ^55ʄ55ʄ5^^555ʄ^5^5쨄5^쨄55^^ʨ55^5ʄ55^^ʨ55^^쨄5^쨨^ʄ555ʄ5^5^ʄ𫫫ohb-*'-*'ohb𕌉5̅5_̅555핌::ېf:ې::ff::ې:f::ff۶::ې::ff:۶fff::ff::f:ff5___5555̅555_̅___5555_̅55555555_5𫫫ohb-*'-*'ohb𕌉5Ά555Ά55:ې:fې:::::ې::ې:::::ې:ff::ې:f::ې::ې::``5555Ά55Ά555Ά55Ά55555555`𫫫ohb-*'-*'ohb𕌉𕌉f::::fې:::f::ې::f::::fې:::::::6666·6666𫫫ohb-*'-*'ohb𕌉񕌉:::f:f۶:f:ff:::𫫫ohb-*'-*'ohb𕌉򕌉::𫫫ohb-*'-*'ohb𕌉򕌉𫫫ohb-*'-*'ohb𕌉𫫫ohb-*'-*'ohb𕌉𫫫ohb-*'-*'ohb𕌉𫫫ohb-*'-*'ohb𕌉𫫫ohb-*'-*'멥rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺɻȺɻɻʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹɻɻɻɻʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹȺȺɻɻɻɻʼʼ˽̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹȺȺȺȺȺȺȺɻɻɻɻʼ˽̾ͿͿ-*'-*'ذ¿¿¿¿¿¿¿¿¿¿¿¿οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ-*'-*'¿οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾ͿͿ㪣zuo]YT]YT^YU^YU^ZU^ZU^ZU]YU^YU]YU\XT]YT]YT\XT\XT\XT\XT[WS[WS[WS[WS[WS[WSZWR[WT[WT[WT[WT]YV]YV]YV]YV]YV]YV]YV]YV[WT[XT]ZV[XT[WT[WT[WT[WT]YV]YV^ZW^ZW^ZW^ZW^ZW&b&S&S&S'T(T (V!)V!*W"+X$-X%-Y%.Z'/Z'0[(0])1])1])1])1^)1])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fX`-*'-*'Ӫ¿U֣GKTӡXJΌ XԩJVڦI | |YLբULӡ IοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾̾a]Y߅}y.<꯵ܯޮ߮୵୵⭵㭷䭷䫹諹諹꫹뫹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쬺쬺쬺쬺쬺묺꫹諹諸筷䭵䭵㭵୵೹ୱ̏*.O-*'-*'وTX[{_vb¿UפHKTӢTإH ~XԪJYLԢ } | }WK }οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹȺȺȺȺȺȺȺȺȺȺȺɻɻɻɻʼʼ˽̾Ϳ顛ȿȿǾƾƾƾƽƽƽƼ~upżƽƽƽƾƾƽƾƾƾǾƾƾƾƾƾƾǾǿǿȿȿȿȿ(5r|r}p}p~p~ppppooonnlllllllllllllllllnnooopppp~p~t~ǞӗWZ-*'-*'ٍOSVZ|^¿U֤HKTӡWӨJ 麌 XԩJV٦I | | LUԢVyοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻɻɻɻɻɻ˽̾̾sniûĻĻûļļļżļûûººûͿͿͿzqk#.|dpdpdqdqcrcrcrbtbvbv`v`x`y`y`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`z`y`x`xbvbvbvbtcrcrcrdqdqpz &O-*'-*'ؿْKNQUX¿U{KTӢXKӢ 껎 |XԩJWK } } ŀUڦI ٤HοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺɻɻȺȺɻɻʼ̾̾Ϳfa\̿̾˾˾̾;̾Ϳ̾˾ʽʼʽʽɼȻɼȻǺǹǺǺǻǺǹunhǺǺǺǺǺǺǺǺǺǺǺǺǺǺǺȻȻȻȼȼȼȻȻȻ)|TbTbTbTbTdTeTeSfSfSfSiRiPiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiRiShSfSfSfTeTeTdTbTbXf>-*'-*'ٿٝTIMPSӮױ¿UإHKTӢTJϰKTӢ 껍 {LUԢX٦IYժK ŀ L פL ֤WۧI | οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻǹȺȺɻɻ˽̾̾]YUǼƻǼǼǼǼȼrnhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~pl÷øøø¶¶smh·····÷~xfVSfVSfVSfVSfVSfVSfVSfVSfVSfVS~yøøøøøø%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'ٿٺ}j]YZã˨¿V֤HVפHKTS~{ { إHTإHXԄJQ |  Lգ ~VzͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺǹǹǹǹȺȺɻʼ˽Ϳ^ZUùĺĺĺĻĻĻfVSfVSrlg׾fVSfVS"yHxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvvxxxxʭ'-J-*'-*'οοοοͿͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺȺȺǹǹǹǹǹǹǹǹɻɻȺɻɼʽ˽̾Ϳ^ZVჀ}fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk|||||||||||||~~~~Ͱ*0L-*'-*'οοοοͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʼ˽̾ͿͿ^ZV⅂fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރႏ₏傏恏恏聏omhYVfVShYVom聏肏悏傏₏⃏ރ݃ۃكׄքӄӄѴ.3N-*'-*'οοοͿͿͿͿ̾ͿͿͿͿͿͿͿͿͿͿͿ˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻ˼ʼʼʼʼɻɻɻɻɻɻǹǹǹǹǹǹǹǹȺȺȺɼɼɼɻʼʼ˽̾^ZV艆fVSfVSOW琙֐אؐؐܐܐߐ㐚䐚揚菚ꏚ뎚쎚쎚fVSfVSurfVSfVS쎚쏚쏚ꏚ菚琚䐚吚㐚ᐚߐݐܐِِػ49Q-*'1,$οͿͿͿͿ̾̾̾̾ͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻ˼˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹǹȺȺȺȻɼɼɻɻʼʼ˽Ϳ^ZVꋈ㛑fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST]蘠ؘژܘܘߘ☢䘢䘢蘢蘢뗢엢yufWUfWUfWUyuyufWUfWUfWUyu옢옢꘢阢蘢嘢嘢㘢ᘢߘݘݘ8=Sߠ20.g\K.,*ͿͿ̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻ˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹȺȺȺȻȻȻɻɻɻɻʼ˽̾Ϳ^ZV퍊Zbꠦܠܠߠࠨ⠨㠨䠨矩蟩꟩쟩쟪ퟩ쟩韩頨蠩堩䠧㠧ᠧࠧ;@U.,*QNKw_.+(ͿͿ̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹȺȺȺȺȻȻȻȺȺɻɻɻʼ˽̾Ϳ^ZV폍_f즬ববব⦭䤭䤭礭褭꤮줮줮冷줭뤭餮礮妭䦭㦭᦭?BV硟-*'qmiiyYͿͿ̾̾̾̾̾̾̾̾Ϳ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼ʼʼʼʼʼȺȺȺȺȺȺǹǹȺȺȻȻȻȻȺȺȺɻʼʼʼ˽˽˾̿^ZV퐍`i쬱଱ଲ㬳䬳䬳笳諳諳쪲쪲﫳쪲髳髳竳嫳嫲䫱?DYꠝqmix'duV.+(.,*dcbdmBFZ/-+.+(rnj}'q$c rVdQ,-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'jgc}yutqsl-2.0/apps/help/tqslapp/pref-adi2.bmp0000664000076400007640000077625612231073120020214 0ustar rmurphyrmurphyBM6(7xxur[YVNLJ/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)=;9HFE`^[khfvspxur][X/,)1/-򢟝1/-/,)DBA_][khfba_οοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿ㢟JIIjhg00.-*'οοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿآ-*'%$#AAA0.,οοοοοοοοͿͿͿͿͿͿͿͿͿͿ.,*111"""οοοοοοοοͿͿͿͿͿͿͿͿͿͿˡ"""-*'-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohbο-*'-*'ohbohbοο-*'-*'ohbohbοο-*'-*'ohbohbοο-*'-*'ohbohbοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<YgUcUcUeUfUgTgTgTgTiSjSjQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkSjSjTiTgTgTgUfUfUeUcUcYg>-*'-*' M פM פ MإV}Y}WۧIYŀYիKWۧILUգWڦIWL֣ | «KYՂ «K KYԩJ };IWIWIWIWHXHWGYEZE[E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE]WYhXUhXUhXUWYE]E]E]E]E[E[E[EZGYHWHWIWIWIWIW;-*'-*'W|K YQKLNפ QKN}K W|XԩKWڦILUգV٦IWIP ٦IWLբWQOIK 9=M=M=M=O=O=O=O=O=O=O=Q=Q-*'-*'ٿٝTIMPSӮױ¿UإHKTӢTJϰKTӢ 껍 {LUԢX٦IYժK ŀ L פL ֤WۧI | οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺȺɻǹȺȺɻɻ˽̾̾]YUǼƻǼǼǼǼȼrnhXUhXUhXUhXUhXUhXUhXUhXUhXUhXU~pl÷øøø¶¶smh·····÷~xfVSfVSfVSfVSfVSfVSfVSfVSfVSfVS~yøøøøøø%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\D\D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'ٿٺ}j]YZã˨¿V֤HVפHKTS~{ { إHTإHXԄJQ |  Lգ ~VzͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺɻɻɻɻȺȺȺȺȺȺȺȺȺȺǹǹǹǹȺȺɻʼ˽Ϳ^ZUùĺĺĺĻĻĻfVSfVSrlg׾fVSfVS"yHxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvvxxxxʭ'-J-*'-*'οοοοͿͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺȺȺǹǹǹǹǹǹǹǹɻɻȺɻɼʽ˽̾Ϳ^ZVჀ}fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk|||||||||||||~~~~Ͱ*0L-*'-*'οοοοͿͿͿͿͿͿͿͿͿͿͿͿͿͿͿ̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻʼʼʼʼɻɻɻɻɻɻȺǹǹǹǹǹǹǹǹǹȺȺɻɻɼɼʼ˽̾ͿͿ^ZV⅂fVSfVSFOㄌ΄Є҄҄Ճփ؃ڃ݃ރႏ₏傏恏恏聏omhYVfVShYVom聏肏悏傏₏⃏ރ݃ۃكׄքӄӄѴ.3N-*'-*'οοοͿͿͿͿ̾ͿͿͿͿͿͿͿͿͿͿͿ˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻ˼ʼʼʼʼɻɻɻɻɻɻǹǹǹǹǹǹǹǹȺȺȺɼɼɼɻʼʼ˽̾^ZV艆fVSfVSOW琙֐אؐؐܐܐߐ㐚䐚揚菚ꏚ뎚쎚쎚fVSfVSurfVSfVS쎚쏚쏚ꏚ菚琚䐚吚㐚ᐚߐݐܐِِػ49Q-*'1,$οͿͿͿͿ̾̾̾̾ͿͿͿͿͿͿͿͿ̾̾̾˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻ˼˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹǹȺȺȺȻɼɼɻɻʼʼ˽Ϳ^ZVꋈ㛑fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST]蘠ؘژܘܘߘ☢䘢䘢蘢蘢뗢엢yufWUfWUfWUyuyufWUfWUfWUyu옢옢꘢阢蘢嘢嘢㘢ᘢߘݘݘ8=Sߠ20.g\K.,*ͿͿ̾̾̾̾̾̾ͿͿͿͿͿͿ̾̾̾̾˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻ˼˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹǹǹȺȺȺȻȻȻɻɻɻɻʼ˽̾Ϳ^ZV퍊Zbꠦܠܠߠࠨ⠨㠨䠨矩蟩꟩쟩쟪ퟩ쟩韩頨蠩堩䠧㠧ᠧࠧ;@U.,*QNKw_.+(ͿͿ̾̾̾̾̾̾ͿͿͿͿ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼˼ʼʼʼʼɻɻɻȺȺȺǹǹǹȺȺȺȺȻȻȻȺȺɻɻɻʼ˽̾Ϳ^ZV폍_f즬ববব⦭䤭䤭礭褭꤮줮줮冷줭뤭餮礮妭䦭㦭᦭?BV硟-*'qmiiyYͿͿ̾̾̾̾̾̾̾̾Ϳ̾̾̾̾̾˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻ˼ʼʼʼʼʼȺȺȺȺȺȺǹǹȺȺȻȻȻȻȺȺȺɻʼʼʼ˽˽˾̿^ZV퐍`i쬱଱ଲ㬳䬳䬳笳諳諳쪲쪲﫳쪲髳髳竳嫳嫲䫱?DYꠝqmix'duV.+(.,*dcbdmBFZ/-+.+(rnj}'q$c rVdQ,-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'jgc}yutqsl-2.0/apps/help/tqslapp/pref-adi.htm0000664000076400007640000000711212231073120020116 0ustar rmurphyrmurphyAdding and Deleting ADIF Mode Mappings

Adding and Deleting ADIF Mode Mappings

Because new modes may not yet be specified in ADIF, and because LoTW may not accept all modes specified in ADIF, TQSL enables you to "map" a new mode to a mode or mode group recognized by LoTW. This most often takes the form of mapping a new digital mode CoolNewDigitalMode to the DATA mode group. Note that TQSL will refuse to map a mode that is accepted by LoTW.

Adding ADIF Mode Mappings
To create a mapping from a new mode to an existing mode or mode group,
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display TQSL's Preferences dialog.
2.In the Preferences dialog, select the ADIF Modes tab; TQSL will display any mappings you've already defined.
  

In the example shown above, when BPSK appears in the MODE field of an ADIF record during digital signing, the QSO will specify PSK31 in the digitally signed log file.

3.Click the Add... button.
4.In the Add ADIF mode dialog,
   4.aType the mode to be mapped into the ADIF Mode box.
   4.bSelect the mode to which the specified mode should be mapped in the Resulting TQSL mode list.
     

   4.cClick the OK button.
    
    Now, when MCW appears in the MODE field of an ADIF record during digital signing, the QSO will specify CW in the digitally signed log file. Were MCW a mode accepted by LoTW, TQSL would refuse to add the mapping when the OK button was clicked.

Deleting ADIF Mode Mappings
To delete a mapping that you've already specified, click on the list entry to select it, then choose Delete.
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display TQSL's Preferences dialog.
2.In the Preferences dialog, select the ADIF Modes tab; TQSL will display the mappings you've already defined.
3.Click on the entry for the mapping you wish to delete, and then click the Delete button.

tqsl-2.0/apps/help/tqslapp/newpw.bmp0000664000076400007640000004416012231073120017561 0ustar rmurphyrmurphyBMpH&(4JF  ||bbb&&ZZBBvvjj66JJffRR¾²..bb~~rr>>vzVVnr^^NN ""**::22ºFFnnzzfjz~¶jn~RVZ^JNbfrvVZ^bBF¶>BNR*."6:FJ:>.226"&&&>>22JJbbVVzznn¾ºƾ5H3HH1HHH1HHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH ?P?P?P ?HHHHH ??M??M??M ?HHHHH ?M??M??M? ?HHHHH ?M??M??M? ?HHHHH ?M??M??.?? ?HHHHH ?M??M??.?? ?HHHHH ?M??M??.?? ?HHHHH ?"??????????????????????? ?HHHHH ?!?????????????????????????????? ??????? ?HHHHH ? ????? ??????????????????????? ?HHHHH ? ????!??? ????????????????????? ?HHHHH ? ????!??? ?????????????????????? ?HHHHH ? ????? ????? ??????????????????? ??????? ?HHHHH ? ????????? ???????????????? ?HHHHH ?!???"????????? ?!? ?HHHHH ?"??"???????? ?!? ?HHHHH ?M??M??M? ?HHHHH ?M??M??M? ?HHHHH ?M??M??M? ?HHHHH ?M??M??M? ?HHHHH ?N??N??N? ?HHHHH ?O?O?O ?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH?-?HHHHH4??HHHHH3???HHHHH7??HHHHH ??????????????????????????? ??????? ???????HHHHH ???????????? ???????????????????????? ????????????HHHHH ??????????????????????????????? ????????????HHHHH ????????????????????????????? ????????????HHHHH ??????????? ???????????????????? ????????????HHHHH ?? ??????????? ??????? ????????????????????????????????HHHHH ???????????????????????????????????HHHHH ??4?"??HHHHH ? ?&? ?#??HHHHH?-?HHHHH?-?HHHHH?-?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH ? ?HHHHH?-?HHHHH(???HHHHH(???HHHHH(???HHHHH ?????????????????????HHHHH ????????????? ??????????????????HHHHH ???????????????? ?????????????HHHHH ????? ???????????? ????????????HHHHH ? ??????? ????????????? ????????????HHHHH ?????????????????????????????????????HHHHH ???????????????????? ?????HHHHH ??H??HHHHH ??H??HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH*?)??HHHHH)??)??HHHHH-?*??HHHHH ?????????????????????HHHHH ???????????????????????????????HHHHH??????????????????? ??????HHHHH ????????????????????????HHHHH ? ??????????????????????????HHHHH ???????????????????? ???????????????HHHHH ???? ??????????????????HHHHH4?????HHHHH??????HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH ?R?`??R?HHHHH ?R?^????Q?HHHHH ?R?a??Q?HHHHH ?????????????????????? ????????????????????????????????????? ?HHHHH ??????????????????????????????????????????? ?????????????????????????????????????????????????????????? ?HHHHH ???????????? ?????? ?????????? ?????????????? ?????? ?????????????????????? ?????????? ?HHHHH ?????????????????????????????? ???????????????????????????????????????? ???????????? ?HHHHH ??????????????????????????????????? ???????? ????????????????????????????????? ????????????? ?HHHHH ?????????? ???????? ?????????????????????????????????????????????????&????????????????????????????? ?????????? ?HHHHH ????????????????????????????????????????? ?????????????????????!?HHHHH???????? ???? ???%?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH,?J?6?}?HHHHH,?J?7?|?HHHHH,?J?8?{?HHHHH ?????????????????????????????????????????v?HHHHH ???????????????? ?????????????????????????????????????????????z?HHHHH ??????????????? ??????????????????????????????? ?????z?HHHHH ??????????????? ???????????????????????????????????z?HHHHH ?????????????????? ?????????????????????????????????????y?HHHHH ?? ???????????????????????????? ?????????????????????????????????????y?HHHHH ????????????????????? ????????????????????????????y?HHHHH ??C??-? ??HHHHH ? ?C???? ??HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHHH?-?HHHH1HHHH zz4Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II];xw{yyHHHH Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II];xw{yyHHHH   Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]yHHHH    Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]yHHHH   Zl99e' ga6mm77f:: 888d%%^  \\<<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]] yHHHH   Zl 999' ga6mm77`:pp888d%oo  \\<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]] yHHHH   Zl99 e''na6 mm77`:p$b8d%oo  \\<<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]iiiiyHHHH  Zl9 ''na6mm7`f:"b8d%oo  \\<<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]((((yHHHH   Zl999''na6m7`f:phb8d%oo \\<<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]yHHHH   Zl999'nna6%77`:ppb88%oo <qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]yHHHH  Zl99 e'nna677`f::b88%%^  <<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]&&yHHHH   Zl9e'nnga67`f:pphb8d%oo^^ \\<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]kkkkyHHHH   Zl9e'nnga6m7`f:pphb8d%oo^^ \\<qqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]))))yHHHH   Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]] yHHHH   Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]] yHHHH   Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II]]yHHHH Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II];xw{yyHHHH zz4Zll9e'nnga6jmm7`f:pphb8d%oo^^ \\<ccqqSS3_PP--ssWW QQ1XX!!rrUUDK>vv0#VV **BuG"ML J=/EAA,R2O$N.FCC+t@@Y  T55[II];xw{yyHHH1HHH1HH2H4Htqsl-2.0/apps/help/tqslapp/newp12pw.bmp0000664000076400007640000004520612231073120020106 0ustar rmurphyrmurphyBMJ*(6\H  }}bbb>>^^**RRnn66FFjj¾²zz~~ffvvZZJJ22""rvbb::..&&BBVVºNNrrjnz~¶nr~vz^bfjbfZ^FJ6:¶RVJN:>NRVZ26"&BF.2&* >B*.22bb>>&&¾ºVVJJzznnƾ7_5__3___3____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____ APAPAP A_____ AAMAAMAAM A_____ AMAAMAAMA A_____ AMAAMAAMA A_____ AMAAMAA.AA A_____ AMAAMAA.AA A_____ AMAAMAA.AA A_____ A"AAAAAAAAAAAAAAAAAAAAAAA A_____ A!AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAA A_____ A AAAAA AAAAAAAAAAAAAAAAAAAAAAA A_____ A AAAA!AAA AAAAAAAAAAAAAAAAAAAAA A_____ A AAAA!AAA AAAAAAAAAAAAAAAAAAAAAA A_____ A AAAAA AAAAA AAAAAAAAAAAAAAAAAAA AAAAAAA A_____ A AAAAAAAAA AAAAAAAAAAAAAAAA A_____ A!AAA"AAAAAAAAA A!A A_____ A"AA"AAAAAAAA A!A A_____ AMAAMAAMA A_____ AMAAMAAMA A_____ AMAAMAAMA A_____ AMAAMAAMA A_____ ANAANAANA A_____ AOAOAO A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____A/A_____4AA_____3AAA_____7AA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAA AAAAAAA_____ AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA_____ AAAAAAAAAAA AAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA_____ AA AAAAAAAAAAA AAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AA4A"AA_____ A A&A A#AA_____A/A_____A/A_____A/A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____ A A_____A/A_____(AAA_____(AAA_____(AAA_____ AAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAA AAAAAAAAAAAAA_____ AAAAA AAAAAAAAAAAA AAAAAAAAAAAA_____ A AAAAAAA AAAAAAAAAAAAA AAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAA AAAAA_____ AAHAA_____ AAHAA_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____"ANAA_____"AOAA_____"AOAA_____ AAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAA AAAAAAAAA AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAA_____ AAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA AAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____)AAAAAAA_____)AAAAAAA_____A/A_____A/A_____A/A_____A/A_____AAiA_____A AhA_____A!AgA_____ AAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAA A_____ AAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAA A AAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAA_____ AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAA AAAAA A_____ AAAAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA AAAA A_____ AAAAAAAAAAAAAAA AAAAAAA AAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A_____ AAAAAAAAAAAAAAAAA AA1AAAAAAAAAAAAAAAAAA A_____ AAAAAAAA A A AAAAAAA0AAAAAAAA AA A_____A/A_____A/A_____A/A_____A/A_____AFA$A A_____AGA$AA_____AHA$AA_____AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA AAAAA_____AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA_____AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAA AAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAA_____ AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAA AAAAAAAAAAAAA_____ AA AAAAAAAAAEAA:A_____ AAAAAAAAAAAAAA>AAAA7A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____,AAAA_____,AAAA_____,AAAA_____ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWA_____ AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA A AAAAAAAZA_____ AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAA A AAAAAA^A_____ AAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAA A AAAAAAZA_____ AAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAA AAAAAAAZA_____ AA AAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAA AAAAAAAAAAAAA AAAAA AAAAAAAZA_____ AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[A_____ AACAAAAAAAAAAAAAAAAAAAAAAaA_____ A ACAAAAAAAAAA AAAAAaA_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A_____A/A____3____ {{gmm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHY;;sr|zz____ mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHY;;sr|zz____    mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY____      mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY____     m(`8iy'b77qf 6nnaXX5p99c WW%u[<]Z:tt^$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY ____     m(`8 ' b77qf 6d&nnaXX5\p999WW%u[<Z:tt$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY ____    m(`88e'b 6d&nnaXX5 \pph99c!WWu[<<Z:tt$$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYYkkkk____   m(`8ie'b77qf 6&nnaXX5pph99c"WWu[<<Z:tt$$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY****____   m(`8ie'''b77qf 6&&nna55\\p9WWu[<<Z tt$$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY____   m(`8ie'b7 6d&nnaXX5%\p999W%u[<<Z$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY____   m( `8ie'b7q 6d&nnaXX55pp99cW%u[<<]Z:^$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY))____    m( `88 'b7q 6 d&nna XX55\\pph9cWW%%uu[[<]]ZZ::tt^^$$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYYllll____    m(`8y'b7qqf 6&nna55\\pph9cWW%%uu[[<]]ZZ::tt^^$$$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY++++____    mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY ____    mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY ____    mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHYY____ mm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHY;;sr|zz____ {{gmm(`8iye'b7qqf j6d&nnaXX5\\pph9cWW%%uu[[<]]ZZ::tt^^$VV NN22ooRR"PPDxxJ>/#MvF!L@1 I=.ECC,K?0 G--Q44TwBBUO33SHHY;;sr|zz___3___3__4_6_tqsl-2.0/apps/help/tqslapp/netproxy.htm0000664000076400007640000000312212231073120020314 0ustar rmurphyrmurphyConfiguring a Network Proxy for Internet Access

Configuring a Network Proxy for Internet Access

Some corporate or university networks may require TQSL to employ a Proxy Server to gain access to the Internet for submitting digitally signed QSOs or obtaining status information. If your organization's Network Administrator informs you that this is the case, he or she will provide you with an appropriate Proxy Address, Port Number, and Proxy Type; otherwise, you should not configure TQSL to employ a Proxy Server, as doing so could prevent TQSL from accessing the Internet. To configure TQSL to use a Proxy Server for Internet access,
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command) to display its Preferences dialog.
2.Select the Preferences dialog's Network Proxy tab.
3.Check the Enable a Network Proxy box.
4.Enter the Proxy Address specified by your Network Administrator.
5.Enter Port Number specified by your Network Administrator.
6.Select the Proxy Type specified by your Network Administrator.

tqsl-2.0/apps/help/tqslapp/moving.htm0000664000076400007640000001442412231073120017732 0ustar rmurphyrmurphyMoving Callsign Certificates and Station Locations from One Computer to Another

Moving Callsign Certificates and Station Locations from One Computer to Another

If you have TQSL running on one computer (the source) and wish to set it up on a second computer (the destination), you must

Moving All Callsign Certificates and Station Locations to Another Computer
You can move all of your Callsign Certificates and Station Locations at once by
1.Directing TQSL to create a Backup File.
2.Copying the Backup File from the source computer to the destination computer.
3.On the destination computer, directing TQSL to restore Callsign Certificates, Station Locations, and Preferences from the copied Backup File.

Moving One Callsign Certificate to Another Computer
A Callsign Certificate (.tq6) file cannot be copied from one computer to another. Only a Certificate Container (.p12) file can be copied in this manner.
1.If you have not created a Certificate Container file for the Callsign Certificate you wish to move,
   1.aStart TQSL on the source computer.
   1.bOn the Callsign Certificates tab, click on the Callsign Certificate you wish to move, and then click the Save callsign certificate button.
   1.cIn the Enter the name for the new Certificate Container file dialog,
       1.c.1.Set Save in to C:\MyLotWCertificates
       1.c.2.Note the File name specified.
       1.c.3.Click the Save button.
   1.dIn the Certificate Container Password dialog, leave the New password and Enter again to confirm boxes empty unless you are using a shared computer, in which case you should specify the same password in both boxes.
   1.eIn the Click the OK button
2.Copy the Certificate Container file from C:\MyLotWCertificates on the source computer to C:\MyLotWCertificates on the destination computer.
3.On the destination computer, startTQSL and select the Callsign Certificate tab, which lists your Callsign Certificates.
   3.aClick the Load a Callsign Certificate button; in the Select Certificate file dialog that appears,
       3.a.1.Set Look in to C:\MyLotWCertificates
       3.a.2.Set the Files of type selector (on OS X, set the Enable selector) to Callsign Certificate container files (*.p12)
       3.a.3.Click on the Certificate Container file you copied in step 2.
       3.a.3.Click the Open button.
   3.bIn the Load Certificate file dialog, enter the password you specified when you created the Certificate Container file (if any), and click the Next button; the New Password dialog will appear.
   3.cIn the New Password dialog,
       3.c.1.If your computer is shared, specify a password in both textboxes; otherwise leave these boxes blank.
       3.c.2.Click the Ok button; the Load Certificate file dialog will display Loading complete.
   3.dIn the Load Certificate file dialog, click the Finish button.
tqsl-2.0/apps/help/tqslapp/main.htm0000664000076400007640000000606612231073120017362 0ustar rmurphyrmurphyTQSL Introduction

Introduction

TQSL is an application used to digitally sign and upload QSOs to the ARRL's Logbook of the World (LoTW) online service, and to manage the Callsign Certificates used when digitally signing.

TQSL accepts QSOs in a log file whose format is either ADIF or Cabrillo, which many logging applications can export. TQSL also includes a simple QSO Data Editor that can be used to create and edit log files in ADIF format.

To digitally sign the QSOs in a log file, TQSL requires you to present a Callsign Certificate issued to you by the ARRL, and requires you to specify the location from which you operated when making every QSO in that log file. To make this easy, TQSL lets you define and name a Station Location that specifies:

  • a Callsign Certificate
  • a DXCC entity
  • a Primary Administrative Subdivison (e.g. an Oblast, Province, or State)
  • a Secondary Administrative Subdivison (e.g. a County)
  • a Grid Square
  • a CQ zone
  • an ITU zone
  • an IOTA Reference Number

This collection of information can be given a name that is presented to TQSL when uploading QSOs made with that callsign from that location. For an example, click here.

TQSL provides the ability to map modes not defined by the ADIF standard to modes that it can recognize, and the ability to specify information about less popular Cabrillo formats that it needs to properly interpret the QSO data in a Cabrillo-format log file.

When you start TQSL, it will inform you if

Getting Started with LoTW
Before you can submit QSOs to LoTW, you must first

Then you'll be able to submit a Log File to LoTW via the Internet . tqsl-2.0/apps/help/tqslapp/lotw.htm0000664000076400007640000000223512231073120017415 0ustar rmurphyrmurphyLogbook of the World

Logbook of the World

Logbook of the World (LoTW) is an online service that enables Radio Amateurs to confirm their two-way contacts, and submit these confirmations for credit toward various awards. Before submitting QSOs to LoTW, a user must obtain a unique Callsign Certificate from the ARRL.

To submit a QSO-bearing log file to LoTW, a user presents that file with his or her Callsign Certificate to an ARRL-supplied application called TQSL. TQSL generates a digitally signed file, and optionally submits it to LoTW by uploading it over the internet. The Callsign Certificate authenticates the source of each uploaded QSO. In combination with LoTW's double blind approach to QSO matching, which prevents users from seeing what other users have uploaded, this maintains the integrity of the QSO verification process that has long been the hallmark of ARRL awards.

tqsl-2.0/apps/help/tqslapp/logopstab.bmp0000664000076400007640000253226612231073120020426 0ustar rmurphyrmurphyBM 6(? (r h' S1#L>8/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)?;8LGDe^Zpid|to@'xZNb][/,)1/-󢟝1/-/,)GB@d]YpidghhͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾碟HC@f`\qqq-*'ͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;οοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳݢ-*'NIF```0.,ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳ.,*B=;222ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ҡ-*(-*'ͿͿͿͿ-*'-*'ͿͿͿͿޡohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohb뺺ohb-*'-*'̾̾̾̾ohb랞ohb-*'-*'̾̾̾̾ohb뎎ohb-*'-*'̾̾̾̾ohb|||vvvvvvxxxohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohb돏Ŀohb-*'-*'˼˼˼˼ohbuuuohb-*'-*'˼˼˼˼ohbsssohb-*'-*'˼˼˼˼ohb{{{ohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ohbͿ̾-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿ̾-*'-*'ohb𕌉䏏ohbͿ̾;-*'-*'ohb𕌉uuuuuuohbͿ;;-*'-*'ohb𕌉ppp                     pppohbͿ̾;̽-*'-*'ohb𕌉ppp                        pppohbͿ̾̽̽-*'-*'ohb𕌉ppp               )          pppohb̾̽̽˼-*'-*'ohb𕌉ppp           )) * * * * * * *     pppohb;̽˼˼-*'-*'ohb𕌉ppp            * *((0((01-/1-/1-/1-/1-/1-/((0'#&     pppohb̽̽˼˼-*'-*'ohb𕌉ppp           * *((01-/738?;B?;BDBHDBHDBHDBHDBH?;B?;B7381-/1-/'#&   pppohb̽̽˼˼-*'-*'ohb𕌉ppp          * *((0*1:?;BDBHCHTTKQZSXZSXeVXeVXeVX`NOTKQYECR?=F76=/.2(''#&  pppohb̽˼˼ʻ-*'-*'ohb𕌉ppp        ) *((0*1:738DBHTKQZSXi\bZSXe`]e`]e`]e`]e`]e`]eVXTKQ`NOTKQR?=F761-/'#&  pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp         *((0*1:?;BTKQZSXTYfe`]hegnonlqunonnonnonnonhege`]e`]DBHTKQ`NOYEC?;B=/.'#&   pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp        *((0*1:?;BTKQeVXe`]hegheguwxuwxuwxuwxuwxuwxuwxe`]none`]ZSXeVXCHT738aKH?;B=/.'#& pppohb˼˼ʻʻ-*'-*'ohb𕌉ppp        *((0*1:?;BTKQi\be`]nonuwxuwxlqu{{{uwxnonheg?;BZSXeVXhegheg?;B((0((0`NOR?==/.'#& pppohb˼ʻʻʻ-*'-*'ohb𕌉ppp      ) **1:?;BTKQeVXe`]lquuwx{e`]?;BgguvgguhegTYfDBH*1:*1:ZSXCHT((0((0aKHR?=1-/(  pppohbʻʻʻʻ-*'-*'ohb𕌉ppp       *((0738DBHZSXe`]TYfnonhegTYf/CHTTYfJP\uwxJP\TYfgguCHTCHT?;BDBHnonnone`]738'#&YEC=/.2(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp     ) **1:?;BTKQeVXZSXuwxlquuwx  ?;B{KervlquTYfCHT*1:ZSX{e`]e`]e`]((0((0((0R?==/.(  pppohbʻʻʻʻ-*'-*'ohb𕌉ppp      *((0738DBHeVXZSXuwx{TYfDBH//CHT{TYfTYfnonCHTTKQZSXnonheg?;B738heg7381-/?;BaKHR?=F762('2(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp      **1:?;BTKQe`]{hegJP\gguSa//'#&oZZoZZoZZhQOhQOaKH܇sthQOܨaKHYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp     **1:DBHZSXnonuwxgguJP\p//JP\stxegoUQoZZhQOYEChQOaKHR?=aKHYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp    )((0738DBHi\bxegCHTlqu/ TYf{}nkxegoZZoUQoUQhQOhQOoUQxegoZZaKHYECaKHaKHoUQhQOYECaKH=/.uwxpppohbʻʻʻʻ-*'-*'ohb𕌉ppp     *((0738DBH}nkhegi\buwxJP\prZSXp/SavCHTCHTDBH?;BCHT?;B?;BZSXDBH738((01-/'#&'#&aKHF762(' pppohbʻʻʻʻ-*'-*'ohb𕌉ppp   *((01-/?;BDBHTKQxstlqu*1:'#&TYfJP\JP\JP\DBH?;B?;B?;BTKQDBH7381-/1-/1-/738TKQhQOF76F762('( pppohbʻʻʻʻ-*'-*'ohb𕌉ppp 1-/KerCHTCHTJP\TYfi\bststpTYf{hegheg*1:Saggu{gguKerJP\CHTi\beVXTKQeVXpJP\eVXDBHTKQhQOTYfSaoZZaKHJP\DBH*1:R?=1-/*1:YECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp  YEC`NOeVXLoZZpxegVSai\bxegstgguhegxjrhegi\bSai\bi\boZZeVXpeVXhQOe`]hQOoUQaKHaKHYECYECF76pppohbʻʻʻʻ-*'-*'ohb𕌉ppp  R?='`NO738eVXi\bxegxegxegxegsToLgguggu'i\bxegxeg/xjrTKQeVX'JP\oUQoZZF76oUQaKHYECF76pppohbʻʻʻʻ-*'-*'ohb𕌉ppp R?='`NO'#&?;BoZZ}nkstLxeggguNmpr{'xjrheg'st'oZZDBHTKQl/paKH2('oUQ'aKH'pYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp R?='`NO *738oZZ'}nke{'lqu{xjrexjrYR}nk'eVXDBH`NOYLY`NO2('oUQ'aKHLYEC2('pppohbʻʻʻʻ-*'-*'ohb𕌉pppR?='`NO ((0eVXest}nkxe}nklђprxjr{e{{LstqKereVXhQOe}nkhQO'hQOhQOoUQeYECYECYECpppohbʻʻʻʻ-*'-*'ohb𕌉ppp aKHeaKHF76'#&YECLstRlчststxjrъ{xjrst{LststLxegi\beeVX`NOQoUQeaKHaKHYECYECYEC=/.pppffffohbʻʻʻʻ-*'-*'ohb𕌉ppp2('aKHaKHaKHR?= ((0hQOoZZstst{ststxegxjr{stxegi\beVXZSXoZZi\bhQOR?=ZSXoZZaKHhQOR?=aKHYECYECYECYECYECR?=pppffffohbʻʻʻʻ-*'-*'ohb𕌉ppp 1-/R?=hQOɿÚuwxssgzpr?;BR?=DBH1-/1-/DBH aKHR?=2('ppp:f:ff:::ې::::fې::ffff:::::ې:::f:ff::::f:f::۶fې::f::fff:::::ې:::ې::f:f::::fff:::::ې::fې:::ohbʻʻʻ˼-*'-*'ohb𕌉ppp    ((0738R?=hQOȻɿ䶨ЌlquTYfTYfTYfgzBZNm?;B738YEC1-/2('2('aKHF762('  ppp::ff:۶f:fې::::ې::::f:ff:۶ff:::::ff::ff:۶f:fې::ې:::۶fff:۶fff:۶f::fې:ff:۶f::f:::::ff:f:::ېf:::ې:ff:۶f:::::fې:ې:f:::ې::ېf:ffohbʻʻ˼˼-*'-*'ohb𕌉ppp   2('738DBH`NO愆prU~prToTYfssgzTo1-/R?=?;BYECF761-/(  ppp::::f:f:::::ې::::::ې::f:::ې::::ې::::::f:f:::ې::f:۶::f:۶::f:۶:::f::f:::::ې::::ې::fffff۶ې:fې::f:۶::::ې::::ff۶::ې::ې::ohbʻʻ˼˼-*'-*'ohb𕌉ppp    2('F76R?=`NOllU~U~YECgzgzgzTKQZSXZSXYECF76=/.(  ppp::::f:۶::::::ې::::::ې::f:::ې:::::f::::f:۶::::ې::f:۶::f:۶::f:۶:f::f:::::ې:::::ff:f:f:f:::f:۶::::ې::::ff::ې::ې:fohbʻʻ˼˼-*'-*'ohb𕌉ppp   2('738R?=aKH擳撍sspr}nk`NOYECF76=/.(  ppp::ff:۶fff:::::ff:::۶ff:۶f::ې:ff:ff::::ff:۶fff::::ې:ې:ff:۶fff:۶f::f:ff:۶f::::ې:ff:ff:::ې:fې:fffff:۶f:f::ff::ff::ې::۶ff::ohbʻ˼˼˼-*'-*'ohb𕌉ppp  '#&1-/F76R?=YEC`NOȻɴݨxxxaKHYECF76=/.2('(  ppp:::f::::ې::ff:ې::f:ff:::ff::ې:::f::f:::f:ې:f:f::f:ې:ff::ff:::ff::ې:fېfffې:fې::f::ff۶::ې::ff:::ې:::ېohb˼˼˼˼-*'-*'ohb𕌉ppp  '#&2('=/.F76R?=R?=YECaKHaKHaKHaKHaKHYECR?=F76=/.2(''#&  ppp::::::ې::::::::f:::ې::ff::::f:::::::fېff::ohb˼˼˼˼-*'-*'ohb𕌉pppYECYEC2('YECYECYECYECYECYEC aKHF76aKHaKHhQOaKHhQOhQOaKHhQOhQOhQOR?==/.1-/2('(    ppp::::::::ې:::::::::fې::ې::::::ېff:::::ې:::ې::ohb˼˼˼˼-*'-*'ohb𕌉pppR?=YEC R?=YECYECYEC2('YECF76R?=}nkYECsthQOaKHaKHR?=(   ppp::::::ff::::::ohb˼˼˼˼-*'-*'ohb𕌉pppR?=YEC YECYECYEC=/.YECF76aKHF76aKHaKHaKH2('(   pppohb˼˼˼˼-*'-*'ohb𕌉pppYECR?=YECYECR?=YECYECYEC YECF76stF76stYECYEC pppohb˼˼˼˼-*'-*'ohb𕌉pppF76YECYECYECYECYECYECYECYECYECYEC2('YECYECYECYECYECYECYECYEC( pppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˼-*'-*'ohb𕌉ppppppohb˼˼˼˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˼˽˽-*'-*'ohb𕌉ppppppohb˼˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉葑ohb˽˽˽˽-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉ohb˽˽˽˽-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb˽˽˽˽-*'-*'ohb𕌉䏏ohb˽˽˽˽-*'-*'ohb𕌉uuuuuuohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉ppppppohb˽˽˽˽-*'-*'ohb𕌉pppTTT````````````````````````````````````````````````aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaUUUpppohb˽˽˽˽-*'-*'ohb𕌉pppSSSUUUpppohb˽˽˽˽-*'-*'ohb𕌉ppp]]]naaapppohb˽˽˽˽-*'-*'ohb𕌉ppp___TxE]6\ps___pppohb˽˽˽˽-*'-*'ohb𕌉pppaaa氽*Uk*21B*[tSv```pppohb˽˽˽˽-*'-*'ohb𕌉pppcccpCfxYdG)a}?iaaapppohb˽˽˽̾-*'-*'ohb𕌉pppeee8d{dވރ]XtX{aaapppohb˽˽̾̾-*'-*'ohb𕌉pppggg싢0hߝ"uNnDmaaapppohb˽˽̾̾-*'-*'ohb𕌉pppiiiBj~j["wQr2_vaaapppohb˽˽̾̾-*'-*'ohb𕌉pppkkk)]uׁR&"W{ Qk{aaapppohb˽̾̾̾-*'-*'ohb𕌉pppmmmWv,dgr\*!]Mha~aaapppohb̾̾̾̾-*'-*'ohb𕌉pppooo³e'\xare/" dKiMoaaapppohb̾̾̾̾-*'-*'ohb𕌉pppqqq扡(ZtVsk8"!mLkDkaaapppohb̾̾̾̾-*'-*'ohb𕌉pppsss윰1`xKrnA"!tQr6cyaaapppohb̾̾̾̾-*'-*'ohb𕌉pppttt3`v@~pqK#"|Ux&Voaaapppohb̾̾̾̾-*'-*'ohb𕌉pppwww黻ÿ:bv5qmsV&"\Ni}```pppohb̾̾̾̾-*'-*'ohb𕌉pppxxxÿJm+eir_+! bNkd```pppohb̾̾̾̾-*'-*'ohb𕌉pppzzz°^}&^{brf1"!jLkOt```pppohb̾̾̾̾-*'-*'ohb𕌉ppp|||&[vYrl:"!$q|Mx@^pppohb̾̾̾̾-*'-*'ohb𕌉ppp݀좳.\tAqqQk܉j  ?gpppohb̾̾̾̾-*'-*'ohb𕌉ppp݂ÿ5_t:u۔^~  :lpppohb̾̾̾̾-*'-*'ohb𕌉ppp݄¿Ch|Ltޝ9>  @]pppohb̾̾̾̾-*'-*'ohb𕌉ppp놆ÿ]~>h聁TT.. Aapppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp눈v0]}円__884 A\pppffff::ffohb̾̾̾̾-*'-*'ohb𕌉ppp뉉务2_|uN^Csppp:f::::fff:::fې:::fff:::ې:::::::f::ې:f۶::::ې::ې::ې:::::f::fې:::f:ې::::ې::ې::::f:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::ې::ې::::f:ohb̾̾̾̾-*'-*'ohb𕌉ppp싋游覷KqKhC^ppp:fff۶::ff:::ې:ېf:ff:::ې:ې:::::ff:ې::ff::ې::::ې::ې::ff::۶ff:۶f::ېf:::::fې::ې::::ې::ې:::::fې:::::ې:ې:::::fې:ې:f::ې:ې::f:ې::ff:۶f:::ې::fې:ې:ې::ې:::::fې::ohb̾̾̾̾-*'-*'ohb𕌉ppp썍⁂ppp:fې::::::ې::ې::ې::::ې::ې:::::ې:::::ې::ې::::ې::ې::ې::::ې::f:۶::ff۶::fې:::ې::::ې::ې::::fې:::::ې::ې::::ې::::::::ې:::f::ې::f:۶::ې::ې::::ې::ې::::fې:::ohb̾̾̾̾-*'-*'ohb𕌉ppp쏏ppp:::::f::ې::ې:f::ې::::::۶:fې::ff::ې::::ې::ې:::f::ې::f:۶::ff::ې::::ې::::ې::ې::::ې::::::ې::::ې::::::::ې:::f::ې::f:::ې::::ې::ې::::ې::::ohb̾̾̾̾-*'-*'ohb𕌉ppp쑑pppf::fff::ff::۶ff::ff:ff:::ېf:ې::ff::ې:f::ې::ې::ff::::۶ff:۶f:ff:ff۶::ff:::ff:ې:::ff:ff::ff:ff:ff::::::::ېff۶::ff:۶fffff::ې:::ff:ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp풒ppp::ې::ff::ې::ې:ې:::ې::ې::ff:ې:fې:::::ې::ې::f:ې::ې::ېf::f::ff::ې::ې::ې::ff::ې::ff::::ې::ff::::::f:::ff::ې:f::ې::ې::ې::ff::ohb̾̾̾̾-*'-*'ohb𕌉ppp픔ppp:fff::f::::fې:::f::ې::f:::f:::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp햖pppff:::::f:f۶:f:fې::ې:::fې::::::::::ې::ohb̾̾̾̾-*'-*'ohb𕌉ppp࿿pppff::ff::::::ohb̾̾̾̾-*'-*'ohb𕌉ppp߾pppohb̾̾̾̾-*'-*'ohb𕌉ppp߿pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppp𜜜텅pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp𝝝톆pppohb̾̾̾̾-*'-*'ohb𕌉ppp񙙙ကpppohb̾̾̾̾-*'-*'ohb𕌉ppp񞞞pppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉ppppppohb̾̾̾̾-*'-*'ohb𕌉uuuuuuohb̾̾̾̾-*'-*'ohb𕌉葑ohb̾̾̾̾-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾ͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿͿͿͿ-*'-*'ohb𕌉䏏ohbͿͿͿͿ-*'-*'ohb𕌉uuuuuuohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉ppppppohbͿͿͿͿ-*'-*'ohb𕌉pppҎpppohbͿͿͿͿ-*'-*'ohb𕌉pppҐyyypppohbͿͿͿͿ-*'-*'ohb𕌉pppxxxxxxxxxxxxxxxxxxxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԈxxxxxx000---555CCCxxxpppohbͿͿͿͿ-*'-*'ohb𕌉pppԃxxxxxxJJJJJJxxxpppohbͿͿͿο-*'-*'ohb𕌉pppԓxxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖¼xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖Ч˸xxxxxxJJJJJJxxxpppohbͿͿοο-*'-*'ohb𕌉ppp֖٣ʱxxxxxxJJJJJJxxxpppohbͿοοο-*'-*'ohb𕌉ppp֖ܿ«xxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖݦʻxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖޛɞxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppؖߝҟxxxxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ௯לyyyxxxJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږԠʫʓyyyyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږӳ󛛛zzzyyyJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppږ῿zzzzzzJJJJJJxxxpppohbοοοο-*'-*'ohb𕌉pppۖ⽽{{{zzzKKKKKKxxxpppohbοοοο-*'-*'ohb𕌉pppۖNo||||{{{KKKKKKyyypppohbοοοο-*'-*'ohb𕌉pppۖRw&V%S||||||LLLKKKyyypppohbοοοο-*'-*'ohb𕌉pppݖά2_rŐJq=_||||||LLLLLLzzzpppohbοοο-*'-*'ohb𕌉pppݖ&V^@jiŠ3_bt}}}|||LLLLLLzzzpppohbοο-*'-*'ohb𕌉pppݖ;eJrQwD0]d$T~}}}}}}MMMLLLzzzpppohbοο-*'-*'ohb𕌉pppݖxÕ:ehɊIDDMtNu5_~~~}}}))))))JJJMMM{{{pppohbο-*'-*'ohb𕌉ppp떖+Yn͎)XCDDIeŇ8dg~~~~~~111///111BBB|||pppffff::ffohbο-*'-*'ohb𕌉ppp덗*Y_ȂHqCCCCD)Ykȋ'V~~~~~~~~~}}}}}}|||pppffff::ffohb-*'-*'ohb𕌉ppp>>;;;???\\\pppohb-*'-*'ohb𕌉pppDOO? ? ? ?8d{{{JJJ;;;GGGpppohb-*'-*'ohb𕌉pppK @<<<<<<<<EDn>>??8d~ޜMpppohb-*'-*'ohb𕌉pppNF99999999 ?MM~Cm>>>H2_𜜜pppohb-*'-*'ohb𕌉pppNN 844444445L;f @=> A`̓N𛛛pppohb-*'-*'ohb𕌉pppNL 4...... 3M2_== B}ޙOpppohb-*'-*'ohb𕌉pppLM1^:++++ 5Lx==NߜOpppohb-*'-*'ohb𕌉pppdʆܰ%S@?F/\쭕 A B_c΅Mpppohb-*'-*'ohb𕌉pppMqΐˁ㝛p3`p̑4aNpppohb-*'-*'ohb𕌉ppp+[ަխvٔ8dNpppohb-*'-*'ohb𕌉pppLL Q(X)XPMpppohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉葑ohb-*'-*'ohb𕌉wwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ãS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<=????????????????????????????????????????????????????????????????????????[>Uohb-*'-*'ohb𕌉<>!!!>= """?$?GIHFDHMP R T V W S T UTPI@"?>EL T\ Ja'f+j.m0o1u7splgb] Z VN@>DL V_gVj1q5v9y;z<~A"{upic] Y T&&&@ D H J JO3-%zrib\ V ^9@̜4(r>QΥ;ŕ,!{q`***AjBpHa _i s }&.6+Σ'ӬJ׶dܿ{ȍЛצݫkմۛՉsܼ[ҬBǜ<\]+kE---B` zSyR[e o z%/ū9ʱAOʢҫ;׵ZܽrƅΕՠڨެߧܟؑh׵OͥCǝayEnGnFBc;iBkDpHxQZe p |(è4ʱ@йKԿT]eg`ŕ4ڻJܽgẏѐԖ֗֔Ӌmٺ]ԱmęA~g |U{SBxRvP{T^j u".Ȯ:ζFӽQ[dlrt|̤_cmx}zrqܿ|̪ŲJ2q `}XF<ffff::ffohb-*'-*'ohb𕌉!r ` F<::ې::f:ې::::fff:::::ې:ff:fff:::ې::::fff::::ff::::f::ې:ffff:::fff:::::fې:fff::::ff:::fې::f::ې::ې::fff:::fff:::ې:ffff:::ې::ې::::ېfې::f:f:f:::ې::fohb-*'-*'ohb𕌉Ϸ@ҼHQX_cfgfc_YRҽHՇqӾ[ȱL-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞+*)A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*GECC0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'b`](,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝b`]{xua@=4$ .+(.,*cbadmBFZ/-+.+(c`^{xuuTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'\ZWmjg{tqsl-2.0/apps/help/tqslapp/login.htm0000664000076400007640000000115512231073120017540 0ustar rmurphyrmurphyVisiting the LoTW web site to View QSOs and QSLs

Visiting the LoTW web site to View QSOs and QSLs

You can visit the Logbook of the World Web site to view your submitted QSOs and confirmed QSOs (QSLs), and to apply for award credits. If your computer has Internet access, TQSL can direct your web browser to navigate there: on the Main window's Log Operations tab, click the Log in to the Logbook of the World Site button. tqsl-2.0/apps/help/tqslapp/loadcert.htm0000664000076400007640000000203412231073120020222 0ustar rmurphyrmurphyLoad Certificate File

Loading a Certificate File

This File menu Load Certificate File command allows you to load in one of two kinds of files:

  • PKCS#12 (.p12) certificate file -- A file in which you saved existing certificates (via the Certificate menu Save command).

  • TQSL (.tq6) certificate file -- A file sent to you by a certificate issuer in response to a certificate request you generated and sent to the issuer.

Once you have made your selection and clicked Next, you will be presented with a file-selection dialog so you can select the certificate file to load.

If you are loading a TQSL (.tq6) file, once you've selected the file it is immediately loaded and the results are displayed.

If you are loading a PKCS#12 file, the next step after selecting the file is to supply the password used to access the file.

tqsl-2.0/apps/help/tqslapp/installation.htm0000664000076400007640000000264112231073120021132 0ustar rmurphyrmurphyInstalling TQSL

Installing TQSL

The TQSL application used by LoTW is free to download and use, and is available for Microsoft Windows and Apple OS X. If you are running anti-spyware or anti-malware applications such as Bit Defender, configure these applications to allow TQSL to run.

Installing TQSL on Microsoft Windows
TQSL will run on the following versions of Microsoft Windows:
  • Windows 2000
  • Windows NT
  • Windows XP (32-bit and 64-bit)
  • Windows Vista (32-bit and 64-bit)
  • Windows 7 (32-bit and 64-bit)
  • Windows 8 (32-bit and 64-bit)

Download TQSL for Windows here .

Installing TQSL on Apple OS X
TQSL will run on both PowerPC and Intel processors on OS X version 10.4 and later. Download TQSL for OS X here .

Building TQSL for Linux
Linux users can build the software from the source code for the tqsllib library, and the TQSL application. ARRL does not maintain packages for the many Linux distributions. For assistance with obtaining a packaged version for your Linux distribution, contact your distribution's maintainer. tqsl-2.0/apps/help/tqslapp/index.htm0000664000076400007640000001077412231073120017546 0ustar rmurphyrmurphyTQSL Introduction

Introduction

TQSL is an application used to digitally sign and upload QSOs to the ARRL's Logbook of the World (LoTW) online service, and to manage the Callsign Certificates used when digitally signing.

TQSL accepts QSOs in a log file whose format is either ADIF or Cabrillo, which many logging applications can export. TQSL also includes a simple QSO Data Editor that can be used to create and edit log files in ADIF format.

To digitally sign the QSOs in a log file, TQSL requires you to present a Callsign Certificate issued to you by the ARRL, and requires you to specify the location from which you operated when making every QSO in that log file. To make this easy, TQSL lets you define and name a Station Location that specifies your Callsign Certificate and operating location.

TQSL provides the ability to map modes not defined by the ADIF standard to modes that it can recognize, and the ability to specify information about less popular Cabrillo formats that it needs to properly interpret the QSO data in a Cabrillo-format log file.

When you start TQSL, it will inform you if

Getting Started with LoTW
Before you can submit QSOs to LoTW, you must first

Then you'll be able to

Secondary Callsign Certificate Operations

Configuration Operations

File Operations

Additional Information
tqsl-2.0/apps/help/tqslapp/glossary.htm0000664000076400007640000000412012231073120020266 0ustar rmurphyrmurphyTQSL Glossary of Terms

Glossary of Terms

ADIF (Amateur Data Interchange Format) -- A log file format that many logging applications can export. It is not necessary to view or modify ADIF files in order to use TQSL, but for more information, see http://adif.org.uk .

Cabrillo -- A log file format used for the submission of contest logs. It is not necessary to view or modify Cabrillo files in order to use TQSL, but for more information, see http://www.kkn.net/~trey/cabrillo .

Callsign Certificate -- A unique file issued by the ARRL to a user that is used to digitally sign a log file, thereby confirming its authenticity.

Digital Signature -- A cryptographic means of enabling a sender to convey information to a receiver in a manner that assures the receiver that

  • the information comes from the sender
  • the information has not been subsequently modified
      LoTW users employ the TQSL application to generate a digitally signed log file containing their QSOs for submission to LoTW.

Digital Signed Log File -- A log file that has been digitally signed by TQSL and can be submitted to LoTW.

Log File -- A file containing QSO records in either ADIF or Cabrillo format.

Station Location -- a collection of information specifying a Callsign Certificate and an operating location:

  • a DXCC entity
  • a State
  • a County
  • a Grid Square
  • a CQ zone
  • an ITU zone
  • an IOTA Reference Number

tqsl-2.0/apps/help/tqslapp/files-icons.htm0000664000076400007640000000327112231073120020644 0ustar rmurphyrmurphyTQSL LoTW Files and Icons

LoTW Files and Icons

LoTW uses four kinds of files, distinguished by Filename Extension.

  • on Windows, Windows Explorer displays these files with an Icon and Type:
    Filename ExtensionIconFile TypeCreated ByUsage
    .tq5 Callsign Certificate RequestTQSLCallsign Certificate Request File submitted to ARRL
    .tq6 Callsign CertificateARRLCallsign Certificate File referenced and managed by TQSL (cannot be backed-up, recovered, or moved to another PC)
    .tq8 Digitally Signed LogTQSL or logging applicationDigitally Signed Log File submitted to LoTW
    .p12 Personal Information ExchangeTQSLCertificate Container File managed by TQSL; can be backed-up, recovered, or moved to another PC
    .tbk TQSL BackupTQSLBackup File created by TQSL that contains all certificates, station locations, and preferences in a form that can be backed-up, recovered, or moved to another PC
tqsl-2.0/apps/help/tqslapp/fileops.htm0000664000076400007640000000065512231073120020075 0ustar rmurphyrmurphyTQSL File Operations

File Operations

tqsl-2.0/apps/help/tqslapp/expired.bmp0000664000076400007640000000206612231073120020060 0ustar rmurphyrmurphyBM66(   9999999999ssssss99999999ssssssOOOOOOOOOOsssTOddddddddggddTO?<?EA?AHPJGCELk~idTI^vtqsl-2.0/apps/help/tqslapp/expiration.htm0000664000076400007640000000263312231073120020614 0ustar rmurphyrmurphyDetermining When a Callsign Certificate Will Expire

Determining When a Callsign Certificate Will Expire

These instructions assume that your Callsign Certificates reside in the folder C:\MyLoTWCertificates .

Callsign Certificates are valid for 3 years. To determine when a Callsign Certificate will expire,
1.Start TQSL and select the Callsign Certificates tab, which lists your Callsign Certificates.
2.Click on the Callsign Certificate in question, and then click the Display Callsign Certificate button; a Certificate Properties window will display the Certificate's expiration date:
  

A Callsign Certificate that has already expired is shown on the Callsign Certificates tab with an expired icon:  .

Once a day on startup, TQSL will inform you if a Callsign Certificate will expire within 60 days, and you will typically receive an email notification from the ARRL a few weeks before a certificate expires. tqsl-2.0/apps/help/tqslapp/expiration.bmp0000664000076400007640000066440612231073120020616 0ustar rmurphyrmurphyBMi6( hzzsm\WSOJG/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)@<9LHDe_[qje}up~zsm^YT/,)1/-򢟝1/-/,)HC@e^Zqjexr^YTοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿ墟IDAga\ga\-*'οοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿۢ-*'OJGXRO0.,οοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿ.,*B>;.+)οοοοοοοοͿͿͿͿͿͿͿͿͿͿР.+)-*'-*'-*'㦠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<WfTbSbSdSeTeSfSfSfShQiQiOiOiOiOiOiOiOiOiOiOjOiOiOiOiOiOiOiOiOiQhQhRgReReReSdSeSdTbTbXf>-*'-*'WѧI ~V٦IUJ ~VئIXԨJ {U|L ֤ | Y֫K ŀ } ëKYւYۧIYL֣Y֫K ŀ YժK VڦI z };HVHVGVGVGVGVFXDYDZCZCZC[C[C[C[C[C[VXhXUhXUhXUVYC[VXhXUhXUhXUVXC[C[C[C[CYCYCYCXEWFVFVGVHVHVHV;-*'-*' VJΰKTSKӢVץHWž{ {T|  KYL֣ ˆ KWLգXՅKRڦI | | ~ ~Uw 9TQSL Station Locations: an Example

TQSL Station Locations: an Example

This example illustrates an operator with two Station Locations: one for his home QTH, and one for a holiday operation in another DXCC entity. Dave K1ZZ would be issued a Callsign Certificate for K1ZZ, and would define the following Station Location for his home QTH in Coventry, CT:
  • a Callsign Certificate: K1ZZ
  • a DXCC entity: Continental US
  • a State: CT
  • a County: Tolland
  • a Grid Square: FN31tt
  • a CQ zone: 5
  • an ITU zone: 8

Dave might name this Station Location K1ZZ-Coventry, incorporating both the callsign and the operating location for easy recall.

If Dave were to operate occasionally from the US Virgin Islands, he would obtain a Callsign Certificate for KP2/K1ZZ specifying the US Virgin Islands as its DXCC entity, and then define a second Station Location for a QTH in the town of Cruz Bay on the island of St. John:

  • a Callsign Certificate: KP2/K1ZZ
  • a DXCC entity: US Virgin Islands
  • a Grid Square: FK78oh
  • a CQ zone: 8
  • an ITU zone: 11
  • an IOTA Reference Number: NA-106

This Station Location might be named KP2/K1ZZ-CruzBay, again incorporating both the callsign and operating location.

When using TQSL to digitally sign a file of QSOs made from his home in Coventry, CT, Dave would select his K1ZZ-Coventry Station Location. When using TQSL to digitally sign a file of QSOs made from Cruz Bay, Dave would select his KP2/K1ZZ-CruzBay Station Location. TQSL would use this information to digitally sign the file and optionally upload it to LoTW.

tqsl-2.0/apps/help/tqslapp/duplicate.bmp0000664000076400007640000077041612231073120020405 0ustar rmurphyrmurphyBM6(2']/$R'"H 6,/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}#Y1L(:/,)1/-󢟝1/-/,)OOOooo}}}T4=$ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿ梟PPPrrrF,-*'ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿݢ-*'WWW:%0.,ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿͿͿͿ0.,III ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾ͿͿͿҡ222-*'-*'-*'ᣞohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbһQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ן2V޼y}20޼y}}10}}10ܹ}}10}}10ܹ}}10ܹ}}10ܹ>}}11ݺ}1}1}}11ݺ}}11}}11ݺ}1Y}}11ݺ>XfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjPjRiQiRhRfRfRfSeSeSdSbSbWe>-*'-*'V٦HLUգ  XիLWԪLLRłSԫLQڧJRӫMRҫL۩MăƄÂOѯQȇȇăTJצQɉ}ÅWIצTzSοοοοοοοοͿͿͿͿͿͿͿͿͿͿ;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD\WYhXUhXUhXUWYD\D\D\C\CZCZCZCYEXFVFVGVGVGUGU;-*'-*'VإHLUԢ ~ ~WԪLWԩLLQMգSāLNڧLLNńÂSצJܪOTW֦IܪRKMMJSοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿ 9Enabling and Disabling Diagnostic Mode

Enabling and Disabling Diagnostic Mode

When enabled, Diagnostic Mode configures TQSL to route information to a log file for use in diagnosing and correcting internet connectivity problems and latent defects.

  • To enable Diagnostic Mode, select the File menu's Diagnostic Mode command; a checkmark will appear to the left of the Diagnostic Mode command, and you'll be prompted to specify the name and location of the log file into which diagnostic information will be saved.
  • To terminate Diagnostic Mode, select the File menu's Diagnostic Mode command; a checkmark will no longer appear to the the left of the Diagnostic Mode command.

The default name of the log file is tqsldiag.log. On Windows, the log file's default location is My Documents; on OSX and Linux, the log file's default location is specified by $HOME.

tqsl-2.0/apps/help/tqslapp/deletecert.htm0000664000076400007640000000117412231073120020551 0ustar rmurphyrmurphyDeleting a Callsign Certificate

Deleting a Callsign Certificate

To delete a Callsign Certificate,
1.Select TQSL's Callsign Certificates tab.
2.Select the Callsign Certificate you wish to delete by clicking it.
3.Select the Callsign Certificate menu's Delete Callsign Certificate command.
tqsl-2.0/apps/help/tqslapp/daterng.htm0000664000076400007640000000311212231073120020047 0ustar rmurphyrmurphySetting a Date Range

Setting a Date Range

If the Prompt for QSO Date Range option is enabled, TQSL will display the QSO Date Range dialog to prompt you to specify a Start Date and an End Date when Submitting a Log File to LoTW via the Internet or Submitting a Log File from a Computer without Internet Access. Any QSOs in the log file outside of this range will be ignored.

Dates should be entered in YYYY-MM-DD format:

Either date can be left blank, in which case only the other date is checked.

The QSO Date Range dialog can be used to prevent QSOs already submitted to LoTW that haven't been subsequently modified from being submitted again, sparing LoTW from processing QSOs that have already been processed. For example, if the last log file submitted contained QSOs made between 2013-02-20 and 2013-02-27, set the Start Date to 2013-02-27 and leave the End Date blank.Only QSOs made on 2013-02-27 or later will be submitted.

Display of the QSO Date Range dialog can be suppressed, but this should only be done if you are certain that the QSOs being submitted have never been submitted before, or have been modified since they were last submitted.

tqsl-2.0/apps/help/tqslapp/daterng.bmp0000664000076400007640000076051612231073120020057 0ustar rmurphyrmurphyBMN6()fffWWW/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}hhh/,)1/-񢟝1/-/,)OOOooo}}}hhhοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿ⢟PPPrrrrrr-*'οοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοע-*'WWWaaa0.,οοοοοοοͿͿͿͿͿͿͿͿͿͿͿͿοο.,*III +οοοοοοοοͿͿͿͿͿͿͿ̾ͿͿͿοοοοʠ222-*'οοοͿ-*'-*'㥠ohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbοοοͿ-*'-*'ohbohbοοοͿ-*'-*'ohbohbοοͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbοͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿͿ̾-*'-*'ohbohbͿͿ̾̾-*'-*'ohbohbͿ̾̾̾-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohbͿ̾̾̾-*'-*'ohb䏏䏏ohbͿ̾̾̾-*'-*'ohbuuuuuuuuuuuuohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾̾-*'-*'ohbppp1y֙Vyy11ָVy1pppppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppohb̾̾̾̾-*'-*'ohbppp1zz1عؚWz1zz11عWz1pppppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppohb̾̾̾̾-*'-*'ohbpppڜ1Wڻ{{{11{{111{Wppppppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb̾̾̾̾-*'-*'ohbppp{{11ۼۜXX{1Xۜpppppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppohb̾̾̾̾-*'-*'ohbppp}}22ݾݝYY}}22}Y2ݝpppppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppohb̾̾̾̾-*'-*'ohbppp5^Ʉ55Ʉ55^5Ʉpppppp55Ʉ55Ʉ55^^^^55Ʉ55pppohb̾̾̾̾-*'-*'ohbppp5ʄ5^ʄ555pppppp5^^^55pppohb̾̾̾̾-*'-*'ohbppp5̅555pppppp__55pppohb̾̾̾̾-*'-*'ohbppp55pppppp55pppohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾̾-*'-*'ohbppppppppppppohb̾̾̾˽-*'-*'ohbuuuuuuuuuuuuohb̾̾̾˽-*'-*'ohb葑葑ohb̾̾̾˽-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwww𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾̾˽˽-*'-*'ohbohb̾˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˽-*'-*'ohbohb˽˽˽˼-*'-*'ohbohb˽˽˽˼-*'-*'ohbohb˽˽˽˼-*'-*'ohbohb˽˽˼˼-*'-*'ohbohb˽˼˼˼-*'-*'ohbohb˽˼˼˼-*'-*'ohbohb˽˼˼˼-*'-*'ohbohb˼˼˼˼-*'-*'ohbohb˼˼˼ʻ-*'-*'ohbohb˼˼ʻʻ-*'-*'ohbohb˼ʻʻʻ-*'-*'ohbohb˼ʻʻʻ-*'-*'ohbohb˼ʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻʻ-*'-*'ohbohbʻʻʻɻ-*'-*'ohbohbʻʻʻɻ-*'-*'ohbohbʻʻʻɻ-*'-*'ohbohbʻʻɻɻ-*'-*'ohbohbʻɻɻɻ-*'-*'ohbohbʻɻɻɻ-*'-*'ohbohbʻɻɻɻ-*'-*'ohbohbɻɻɻɻ-*'-*'ohbohbɻɻɻȺ-*'-*'ohbohbɻɻɻȺ-*'-*'ohbohbɻɻɻȺ-*'-*'ohbohbɻɻȺȺ-*'-*'ohbohbɻȺȺȺ-*'-*'ohbohbɻȺȺȺ-*'-*'ohbohbɻȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohb6``6·ohbȺȺȺǹ-*'-*'ohb6Ϋ``6ohbȺȺȺǹ-*'-*'ohb666666```66666·```666`·6666`·666666666666·666666·66·6`ohbȺȺȺǹ-*'-*'ohb6666666`·6·666``666·6·`6```6666666666666·666666``66``6·6ohbȺȺǹǹ-*'-*'ohb666666·6666666666·66·66·666·66666666666·`666·66·`6666666·6666``ohbȺǹǹǹ-*'-*'ohb666666·666666``66·66·6`6·6666666666``666``66·66``666``666``Ϋ66``66ohbȺǹǹǹ-*'-*'ohb666``6``6666````66Ϋ``666·6`666``666``666``666`66``Ϋ66·66·66``Ϋ66·6666``Ϋ66````ohbȺǹǹǹ-*'-*'ohb6666``66666666·6·666·`666`666`666`666`6666·6``66·666·6``666666·66666·6ohbǹǹǹǹ-*'-*'ohb6666666`666`·```·6```·6```·6```·6`6666`·66666`6666`·66666666`666`6`ohbǹǹǹǹ-*'-*'ohb66·666`666Ϋ``666`666`666`666·6``66``66`6``6ohbǹǹǹǹ-*'-*'ohb666``6·ohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohb½½ohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹǹ-*'-*'ohbohbǹǹǹȺ-*'-*'ohbohbǹǹǹȺ-*'-*'ohbohbǹǹǹȺ-*'-*'ohbohbǹǹȺȺ-*'-*'ohbohbǹȺȺȺ-*'-*'ohbohbǹȺȺȺ-*'-*'ohbohbǹȺȺȺ-*'-*'ohbohbȺȺȺȺ-*'-*'ohbohbȺȺȺɻ-*'-*'ohbohbȺȺȺɻ-*'-*'ohbohbȺȺɻʼ-*'-*'ohbohbȺȺɻ̾-*'-*'ohbohbȺɻʼ̾-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷohbȺʼ˽Ϳ-*'-*'ohbϵɤohbɻ˽̾Ϳ-*'-*'ohbϵɤohbʼ̾ͿͿ-*'-*'ohbϵɤohb˽̾Ϳ-*'-*'ohbϵɤohb̾ͿͿ-*'-*'ohbϵɤohbͿͿ-*'-*'ohbϵɤohbͿ-*'-*'ohbϵɤohbͿ-*'-*'ohb6``6·ϵɤohbͿ-*'-*'ohb6Ϋ``6ϵɤohb-*'-*'ohb66·`·6```666·66`·666·```666`·6666`·666666666666·666666·66·6`ϵɤohb-*'-*'ohb`666·`6666·6·66`666``666·6·`6```6666666666666·666666``66``6·6ϵɤohb-*'-*'ohb``66·66·66·6666666666·66·66·666·66666666666·`666·66·`6666666·6666``ϵɤohb-*'-*'ohb``6666·666666``66·66·6`6·6666666666``666``66·66``666``666``Ϋ66``66ϵɤohb-*'-*'ohb``66``6`6666````66Ϋ``666·6`666``666``666``666`66``Ϋ66·66·66``Ϋ66·6666``Ϋ66````ϵɤohb-*'-*'ohb``6·666·66``6·6666666·6·666·`666`666`666`666`6666·6``66·666·6``666666·66666·6ϵɤohb-*'-*'ohb6`·``6666666`666`·```·6```·6```·6```·6`6666`·66666`6666`·66666666`666`6`ϵɤohb-*'-*'ohb6·666666`666Ϋ``666`666`666`666·6``66``66`6``6ϵɤohb-*'-*'ohb6``6·ϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbĭ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\ĭohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb``6``6·ohb-*'-*'ohb`66Ϋ``6ohb-*'-*'ohb666`6``66666·66·66```66666·66·66```666`66666·66```66666·66·66```666```666`·6666`·6`66666````66666```666```666`·666`·66`66·66```666·6666·66Ϋ`·6`6ohb-*'-*'ohb66``6Ϋ``66·666·66·66·666·66·666``666·66```·6````66·`66666``666`·6·6·666·6·`6```6Ϋ``6Ϋ`66666Ϋ```6Ϋ``666666`·6·6·666·6·`6``·`66·6·6666Ϋ`66·666·6·6666·66`·6`6ohb-*'-*'ohb6666`6Ϋ666666·66·6666·66````66·6666·66`66`·666666·66·6666·6666666666·66·66·666·666`6Ϋ6666`6Ϋ66`666·6666666666·66·66·66````66`6Ϋ6666·66·6666·666`ohb-*'-*'ohb6666`6Ϋ666666·66·66·66Ϋ````666`66``6`·6`6`Ϋ66·66·66666`Ϋ666666·66·66·6`6·666`6Ϋ6666`6Ϋ66`666·66666666·66·66·6```6666`6Ϋ66·66·66666`ohb-*'-*'ohb`666```6Ϋ`666666·`6·`6``````66``66````````66``66·66·66·6``6``666```66``66Ϋ``666·6``6Ϋ`6`66·6·6``6Ϋ`66·6``6``66``66Ϋ``66`6````66·6·6·66``6``6·66`6ohb-*'-*'ohb66`66`6666`666`Ϋ`6`66·6`6`·66·66·66·`6``66·66·666``666``66·66``6666·6·666·`66`66```666`6·6`6``666``6666·6·666·666·6`666`6·6666·66``66`6·ohb-*'-*'ohb```·66666·6666666`·6666·6666666`666666ohb-*'-*'ohb666·6666·66·6666666Ϋ`6666·666666`6666666ohb-*'-*'ohb6666666`666666`6·666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb``66ohb-*'-*'ohb``66ohb-*'-*'ohb```666```666`·6666`·`6·66·66·666666·6``·66666`·666`6·6666·66```6666`6666·6666·6`666``666```666·66```66666·6666```66666·666`6``666```66`6``666`·666·66·66·66·`6ohb-*'-*'ohb6`·6·6·666·6·`6``66`·6````·66·66·666666``6Ϋ``6666Ϋ```·`66666`·66·6666``6`·6·6``6Ϋ`6666·66666`66`66·66`·6·6``6`·6·666·6666`66666````6Ϋ``66·6·`666`6`66·6·`666·66·66```6ohb-*'-*'ohb666666·66·66·666Ϋ`6``6``66·66·666666·66`66666`6Ϋ66``Ϋ66`·666·6666·66666666`6Ϋ6666·6666·6666·6666·6666·66666666·666666·6666·6666`6Ϋ6666·66·666`6666·6666·66·66·66ohb-*'-*'ohb6666·66·66·6`6`·``Ϋ`6`666·66·666666·66`66666`6Ϋ6```66·6666·66666`Ϋ666666`6Ϋ6666·6666·6666·6666·66666`Ϋ666666·666666·66666`66`6Ϋ6666·66·666`6666·6666·66·666`ohb-*'-*'ohb``66``66Ϋ``66``6````6`·66·66·666``6``6Ϋ`6666·6·6``66`6``Ϋ66``666``6``66``66``6Ϋ`6`666``66`66·6666``66``66``66666``666·6``6``66``6Ϋ`6666·66·66·``Ϋ6666·6666·66·66``66ohb-*'-*'ohb6666·6·666·66·`6`6Ϋ66·66·6666``6`6·6`666`6·66·66·66·66·66``66·666`66``66·66````66·6666·66·66·6666·66``6``666``66·6`66666``6`666``66666·6`6·66·66·ohb-*'-*'ohb666666·6666666666666666·666666`666ohb-*'-*'ohb666666·66·6666666666666666666666·6666666`·66·66ohb-*'-*'ohb6666·66666666666666``66ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb`6·66````ohb-*'-*'ohb6666````ohb-*'-*'ohb6`66·6``·66`6666·6`66`·66````66666·66`·6`·6```666·66```666·6666`6```666```666`·6666`66```666·66`·666·66```66666·6666·6666```666·66·6666`6ohb-*'-*'ohb6·6```6666·6`·6·`66·66`6·6666``6Ϋ`66`6``6Ϋ``66666``·`66·`6666·6·66`666·66666`·666`·6·6·666·6·`6````6Ϋ`66666·6·66`6``66`66666````66666`·6·6·66·66666`·66ohb-*'-*'ohb6`·66``6`·66``666`6666·66`6Ϋ6666·66`666·6666·66``66·66·66·6666·66·6666`·666666666·66·66·6666`6Ϋ6666·66·6666·666666·6666·66666666·6666·66·6666`·666ohb-*'-*'ohb66````66````666`6666·66`6Ϋ6666·66`666·66666```6666·6666·66·6666·66666666·66·66·6`66`6Ϋ6666·6666·6`Ϋ6666·66666`6`Ϋ6666·6666·66·6666·6666ohb-*'-*'ohb66````66``Ϋ`6``66·``Ϋ6`66``6Ϋ`6`66Ϋ``6Ϋ`66·6``6``66`6``66``6`66·666``6``66``66``66Ϋ``66``6Ϋ`6```6666Ϋ``666`66·6``6``66``666``6``66·666``6``66ohb-*'-*'ohb6`·66``6`·6666`666``66``Ϋ66·6`66``6·66`6``666``66·666·666·66``6``666·66``666666·6·666·6`66``66·``66`·666·66``6``666``66·66·66``66·66·66``66ohb-*'-*'ohb6·6`·66`·``6·6`·66666·6666666666`66666·6666ohb-*'-*'ohb6·66·66·6666666·666666·6666666`·6666·6666·66ohb-*'-*'ohb6666``6666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb`6·66ohb-*'-*'ohb6666ohb-*'-*'ohb66·66666`66```666·66·66`·66``·666·66·66·6``·66`66·6``·666·666`66·66·66```66666·6666·66666`6``666`·666·66·66·66·`6ohb-*'-*'ohb66·6666``6Ϋ`666`·6·6``66`6``6Ϋ`·`66·``66``6``66·6```6666·6`·6·`66·66·66``6Ϋ`66·66·66`66666``66·6666·66`6`66·6·`666·66·66```6ohb-*'-*'ohb66·666666`6Ϋ666666·666666·66`6``Ϋ6666·6666666`·66``6`·66``66·6666`6Ϋ66·66·6666·6666·6666·6666·666`6666·6666·66·66·66ohb-*'-*'ohb66·666666`6Ϋ6666666`Ϋ6666·66`6``6`Ϋ666`Ϋ666666````66````66·6666`6Ϋ66·66·6666·66666`66·6666·666`6666·6666·66·666`ohb-*'-*'ohb666``6``6Ϋ`6```66``666`66Ϋ``6Ϋ``6````66·66``666`6666````66``Ϋ`6``66·6```6Ϋ`66·`6·`666·6``6``66666``666·``Ϋ6666·6666·66·66``66ohb-*'-*'ohb66·66``6`66``66·66·66``6·66`66·66·66·66·`Ϋ`6·66`·66``6`·6666`6``6``666`Ϋ`6`6``666``66·66·66```666``66666·6`6·66·66·ohb-*'-*'ohb666666666·6`·66`·``6·6`·6`666·6666`666ohb-*'-*'ohb66666666666·66·66·66`·66·6666666`·66·66ohb-*'-*'ohb6666``66``66ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb`````````6·ohb-*'-*'ohb`6``````66ohb-*'-*'ohb666`6``66666·66·66```66666·`·666`·6```66666·66`·6`·6```666·66```666·6666`6```666·6666```6666·66`6666·6666```666·66·6666`66`66·6````666```666`·666`·6ohb-*'-*'ohb66``6Ϋ``66·666·66·66·666·66·6·`66·```6`66666``·`66·`6666·6·66`666·66666`·66666·6·66666`·6·6·66Ϋ``6Ϋ`66``66666`·6·6·66·66666`·666·6```6666·6`·66`·6·6·666·6·`6``·`66·ohb-*'-*'ohb6666`6Ϋ666666·66·6666·66``````Ϋ666666·6666·66``66·66·66·6666·66·6666`·66666·66·6666·666666·66`6Ϋ66666666·6666·66·6666`·6666`·66``6`·66666666·66·66·66``ohb-*'-*'ohb6666`6Ϋ666666·66·66·66Ϋ``````6`6666·66666```6666·6666·66·6666·666666·6666·6666``66`6Ϋ666`Ϋ6666·6666·66·6666·666666````66``6666·66·66·6```ohb-*'-*'ohb`666```6Ϋ`666666·`6·`6```````6````66·6666·6``6``66`6``66``6`66·666``6``66``6``6``66````6Ϋ`6```666``6``66·666``6``6666````66````66``66Ϋ``66`6``ohb-*'-*'ohb66`66`6666`666`Ϋ`6`66·6`6`·66·66·6·66``666``66·666·666·66``6``666·66``6666·66``66``6`66``66·66``66·66·66``666`·66``6`·666666·6·666·66ohb-*'-*'ohb```·66666·666666666`·666·6`·66`·``6·6`·66666ohb-*'-*'ohb666·6666·666666·66666·666·666·66·66·66666ohb-*'-*'ohb6666666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'L-*'-*' PƂ-*'-*'USӆX`+4g (P (P")Q#*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P+4gX`-*'-*'XKYMפ ÀVTN֣TLƃL€OO֥OO֤Qǃ).Ny}ʹ᮶᮶᮶家殸欹鬺ꬺꬺ쬺쬺ꬺꬹ鮸殶殶家⮶ⴺ⮲y}).N-*'-*' LգWPVY׃VƀܩKVܨKNץXN֤€NPפRܨJÀOOץOO֥ᆵO~X[uqqqqqpppoommmmmmmmmmmmmmmmmoopppqqqqquɟՄX[-*'-*'U|WڧIMVפ īKVۨKLVƂNTգłƃL€OO֤OO֥QۨKǃ!&Oq{ererdsdsdscucxcwcwayayaza{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{a{azayaycwcwcwcudsdsdsererq{!&O-*'-*'YԂYŀXǁ ܨJNإVܩKNץ€TԅRÁOOئOOצQݩL>YgUcUcUeUfUgThTgTgTiSjSjQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkQkSjSjTiTgTgTgUfUfUeUcUcYg>-*'-*'YԪJY׫K ܨJ ~ÀVܩKNTץNץ€TԬMƃOÁONSԆSԇQハRѮN;IWIWIWIWHXHXGYEZE[E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE]WYhXUhXUhXUWYE]E]E]E]E[E[E[EZGYHWHWIWIWIWIW;-*'-*' êK ÂWۨJT€VۨKNT֤ƂLSN֤łPMүOOQܩKQOKSO֤ 9=M=M=M=O=P=P=O=O=O=O=Q=QRequesting a Callsign Certificate: Authenticating

Requesting a Callsign Certificate: Authenticating

Explain under what circumstances the user should or should not use an existing Callsign Certificate to Authenticate the request for a new Callsign Certificate.

tqsl-2.0/apps/help/tqslapp/crq3.htm0000664000076400007640000000131412231073120017275 0ustar rmurphyrmurphyRequesting a Callsign Certificate: Specifying a Password

Requesting a Callsign Certificate: Specifying a Password

If you're using a shared computer, you should protect your Callsign Certificate by specifying the same password in both textboxes; you'll be asked to provide this password each time you direct TQSL to digitally sign a log file, so be sure to remember it. If you control access to the computer you're using, you can leave both textboxes empty, thereby avoiding the need to provide a password each time you direct TQSL to digitally sign a log file.

tqsl-2.0/apps/help/tqslapp/crq2.htm0000664000076400007640000000043712231073120017301 0ustar rmurphyrmurphyRequesting a Callsign Certificate: Specifying Your Email Address

Requesting a Callsign Certificate: Specifying Your Email Address

Specify the email address to which your requested Callsign Certificate will be sent.

tqsl-2.0/apps/help/tqslapp/crq1.htm0000664000076400007640000000100112231073120017264 0ustar rmurphyrmurphyRequesting a Callsign Certificate: Specifying Your Name and Address

Requesting a Callsign Certificate: Specifying Your Name and Address

1.Specify your Name and Address. For US callsigns, the Address you specify must match your address in the FCC database
2.Click the Next button.

tqsl-2.0/apps/help/tqslapp/crq0.htm0000664000076400007640000000157712231073120017305 0ustar rmurphyrmurphyRequesting a Callsign Certificate: Specifying Your Callsign, DXCC Entity and QSO Dates

Requesting a Callsign Certificate: Specifying Your Callsign, DXCC Entity and QSO Dates

1.Specify the station callsign for which you seek a Callsign Certificate, without any portable identifiers.
2.Select the DXCC entity.
3.Set the QSO begin date to the date of the first QSO made using this callsign.
4.If additional QSOs will be made using this callsign, leave the QSO end date blank; otherwise, set the QSO end date to the day after the date of the last QSO made using this callsign.
5.Click the Next button.

tqsl-2.0/apps/help/tqslapp/contents.hhc0000664000076400007640000001357712231073120020252 0ustar rmurphyrmurphy

tqsl-2.0/apps/help/tqslapp/configxml.htm0000664000076400007640000000324112231073120020414 0ustar rmurphyrmurphyChecking and Updating TQSL's Configuration Data

Checking and Updating TQSL's Configuration Data

TQSL is driven by Configuration Data that defines

  • Bands
  • Modes
  • Propagation Modes
  • Satellite Names
  • DXCC Entities
  • Primary Administrative Subdivisions (e.g. US States, Canadian Provinces, Russian Oblasts)
  • Secondary Administrative Subdivisions (e.g. US Counties)

Determining What Version of Configuration Data TQSL is Currently Using
Select the Help menu's About command (on OS X, select the Application menu's About command); TQSL will display an About dialog that displays the Configuration Data version it's using.
 

Determining Whether a New Version of Configuration Data is Currently Available
If your computer has access to the internet, you can determine whether a new version of Configuration Data is available by selecting the Help menu's Check for Updates... command. If a newer version is available, the Update Available dialog will appear, showing the new version available and providing an OK box that if clicked will download and install the new version:
 

The Check for Updates... command will also inform you if a new version of TQSL is available. tqsl-2.0/apps/help/tqslapp/configops.htm0000664000076400007640000000125412231073120020417 0ustar rmurphyrmurphyTQSL Configuration Operations

Configuration Operations

tqsl-2.0/apps/help/tqslapp/cmdline.htm0000664000076400007640000003034512231073120020046 0ustar rmurphyrmurphyTQSL Command Line Interface

Command Line Interface

When starting TQSL, you may specify command line options that

Most command line options are single-letter switches, some of which require an argument; such arguments should be separated from the switch letter by one or more spaces. Arguments that contain spaces or other shell-special characters should be quoted in a manner suitable for the operating system and shell that's being used. If more than one command line switch is specified, each switch must be separated from the preceding switch by one or more spaces.

A filename not preceded by a switch is assumed to be the name of a log file whose QSOs are to be signed.

After taking the actions specified by command line options, TQSL will enter its menu-driven mode of operation unless one of the -q, -x or -n switches are present, in which case it will terminate.

OptionDescription
-a The action to be taken if a duplicate, out-of-date-range, or invalid QSO is encountered while signing a log file's QSOs:
  -a ask        a dialog will be provided that prompts the user to specify how to proceed
  -a abort      no QSOs will be signed
  -a compliant  neither duplicate QSO nor out-of-date-range QSOs will be signed; all other QSOs will be signed
  -a all        all QSOs, including duplicates and out-of-date-range QSOs, will be signed

If no -a switch is specified and a duplicate or out-of-date-range QSO is encountered while signing QSOs, a dialog will be provided that prompts the user to specify how to proceed.

-b date
-e date
Specifies the beginning (-b)date of QSOs to be signed or the end date (-e) for QSOs to be signed. QSOs before the begin date or after the end date will not be signed. If these are used, -d should also be specified to suppress the QSO date-range dialog.
-d Suppress the date-range dialog; if this switch is present, the QSO date-range dialog will not be displayed before signing a log.
-h Display command line help.
-i Filename Load a specified Callsign Certificate File (.tq6), a Certificate Container File (.p12), or a Configuration Data File (Config.tq6) .
-l Station_Location Select a defined Station Location to be used when signing log files. If the specified Station Location contains embedded spaces, it must be quoted in a manner suitable for the operating system and shell that's being used. If the specified Station Location doesn't exist, no QSOs will be signed or uploaded unless -s is also specified. If -l is not present and a log file is being signed, a dialog will be provided that prompts the user to select a Station Location.
-n Checks for and reports the availablility of
TQSL displays the above information (if any) to stderr, then exits without digitally signing any specified filename. This command line option should therefore not be used with any other command line option.
-o Filename Specify the name of the digitally signed log file to be created. If the specified Filename contains embedded spaces, it must be quoted in a manner suitable for the operating system and shell that's being used. If -o is not present, the specified log filename with its extension set to .tq8 will be used.
-p Password Specify the password that gains access to a password-protected Callsign Certificate when signing a log file. If the specified Password contains embedded spaces or other shell-special characters, it must be quoted in a manner suitable for the operating system and shell that's being used. If -p is not present, a log file is being signed, and the specified or selected Station Location includes a password-protected Callsign Certificate, a dialog will be provided that prompts the user to specify the password.
-q Operate in batch mode: status information will be routed to stderr, and TQSL will terminate after taking the actions specified by command line options.
-s If the -l switch is also present, a dialog will be provided that enables the specified Station Location to be edited; otherwise, a dialog will be provided that enables a new Station Location to be defined.
-t Filename Enable Diagnostic Mode and specify the name of the log file into which diagnostic information is written.
-u Instead of saving the digitally signed log file, upload it to LoTW over the Internet. After processing, the uploaded file will be shown in LoTW's Your Activity list with the specified filename preceded by <TQSLUpl YYYYMMDD-HHMM>, where YYYY is the current year, MM is the current month, DD is the current day, HH is the current hour, and MM is the current minute.

-v Display TQSL version information, and terminate.
-x Operate in batch mode: status information will be routed to stderr, and TQSL will terminate after taking the actions specified by command line options.
Filename A command line option that is not a single-letter switch or the argument associated with a single-letter switch will be considered the name of the ADIF or Cabrillo log file to be digitally signed using the specified or selected Station Location. If the specified Filename contains embedded spaces, it must be quoted in a manner suitable for the operating system and shell that's being used. If -u is present, the resulting signed log file will be uploaded to LoTW via the internet. Otherwise, the resulting signed log file will be saved in the Filename specified by the -o switch; if -o is not present, the resulting log file will be saved in the same directory as the log file using the .tq8 extension, overwriting any existing .tq8 file of the same name.

Invocation Examples:
Without displaying the QSO date-range dialog and ignoring duplicate QSOs, digitally sign the "cqww log.adi" log file using the "CQWW Portable" Station Location, upload the digitally signed log file to LoTW, route stderr to the file results.txt and then terminate:
    tqsl -d -u -a new -x -l "CQWW Portable" "cqww log.adi" 2>results.txt

Edit the "Home" station location before beginning menu-driven operation:
    tqsl -l Home -s

Add a station location, and then terminate:
    tqsl -s -x

Check for new versions and expiring or pending Callsign Certificates, and then terminate:
    tqsl -n 2>news.txt

Status Information
If invoked with -q or -x, status information will be routed to stderr. The last line of stderr will have the following format: HH:MM:SS AM/PM Final Status: Description (Code) where
  • HH:MM:SS AM/PM is the timestamp
  • Description is a textual summary the status that contains no left or right parenthesis
  • Code is an integer uniquely identifying the status, as described in the following table

CodeDescription
0success: all qsos submitted were signed and saved or signed and uploaded
1cancelled by user
2rejected by LoTW
3unexpected response from TQSL server
4TQSL error
5TQSLlib error
6unable to open input file
7unable to open output file
8No QSOs were processed since some QSOs were duplicates or out of date range
9Some QSOs were processed, and some QSOs were ignored because they were duplicates or out of date range
10command syntax error
11LoTW Connection error (no network or LoTW is unreachable)

Status Examples:
05:57:39 PM: Warning: Signing cancelled
05:57:39 PM: No records output
05:57:39 PM: Final Status: cancelled by user (1)

06:05:56 PM: /home/rmurphy/k1mu.adi: 414 QSO records were duplicates
06:05:56 PM: /home/rmurphy/k1mu.adi: wrote 1 records to /home/rmurphy/k1mu.tq8
06:05:56 PM: /home/rmurphy/k1mu.tq8 is ready to be emailed or uploaded.
Note: TQSL assumes that this file will be uploaded to LoTW.
Resubmitting these QSOs will cause them to be reported as duplicates.
06:05:56 PM: Final Status: Some QSOs were duplicates or out of date range (9)

17:21:32 PM: /Signing using Callsign W4TV, DXCC Entity UNITED STATES OF AMERICA
17:21:32 PM: /Warning: Your custom mode map WSPR conflicts with the standard mode definition for WSPR and was deleted.
17:21:32 PM: /Attempting to upload 2 QSOs
17:21:33 PM: /C:\Program Files\LogsAreUs\LotWUpload.ADI: Log uploaded successfully with result "File queued for processing"!
17:21:33 PM: /After reading this message, you may close this program.
17:21:33 PM: /Final Status: Success (0)

in response to -n
17:21:32 PM: A new TQSL release (v2.0) is available.
17:21:32 PM: A new TrustedQSL configuration file (V2.4) is available.
17:21:32 PM: The certificate for VE6LB expires in 9 days.
17:21:33 PM: The certificate for VE6LB/A3 expires in 15 days.
17:21:33 PM: A Callsign Certificate for VE6LB/P5 is pending.
tqsl-2.0/apps/help/tqslapp/certs-icons.htm0000664000076400007640000000132412231073120020657 0ustar rmurphyrmurphyTQSL Callsign Certificate Icons

TQSL Callsign Certificate Icons

Callsign Certificates can be in one of four states, each designated by an icon:

IconCallsign Certificate State
 Pending
 Valid
 Replaced
 Expired
tqsl-2.0/apps/help/tqslapp/certreq1.bmp0000664000076400007640000220754612231073120020162 0ustar rmurphyrmurphyBMf 6(s0 fffWWW/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}hhh/,)1/-𢟝1/-/,)OOOooo}}}hhhοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽ᢟPPPrrrrrr-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽֢-*'WWWaaa0.,οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ̾̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽.,*III222οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾ɡ222-*'˽˽̾̾-*'-*'ञohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb˽˽̾̾-*'-*'ohbohb˽̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb𸵰һQ<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<YgUcUcUeUfUfTgTgThTjSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiThThThUgUgUfUdUdYh>-*'-*'VL֤ }LVפ īK MX׬MX֫MƂU٧JWөLÀMԣ꺉MԣRҫLЅN뼈L٧KLPLԤPLԣPϬNIMKQԢIQIӡ₼߇LʫOJRҡႻއLɫO˨RGҡ}ąIąyئP|ĄwܥTE˛;IWIWIWIWHWHWGYEZE\E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E\E\E[GZHXHXIXIXIXIX;-*'-*'WڦILU֤UڧIWQPIMX֫MXժLULإJMԢ€~€RNԣQѪLئJLNNӢLNϫOKԣOKԢئKㄾOMIKKIO|~LRҡJLGצMLɫOG‚|ĄIĄx|UПF֣M 9=M=M=M=N=O=O=O=O=O=O=Q=Q Requesting an Initial Callsign Certificate

Requesting an Initial Callsign Certificate

LoTW requires that you request your Initial Callsign Certificate using the same computer with which you will accept Your Initial Callsign Certificate.

To request your Initial Callsign Certificate,
1.Create a folder in which to maintain your Callsign Certificates. In these instructions, the folder C:\MyLoTWCertificates will be assumed, but you can choose any folder that does not conflict with your operating system's policies.
   1.aOn Windows Vista, Windows 7, and Windows 8, using a folder within C:\Program Files or C:\Program Files (x86) would require starting TQSL with Run as Administrator, because these versions of Windows consider those two folders to be protected; thus it's best to choose or create a folder that resides elsewhere.
2.If you start TQSL before receiving your Initial Callsign Certificate from the ARRL, or if you have not installed a Callsign Certificate on the computer you're using, an Alert dialog will appear that informs you that you have no Callsign Certificate, and asks if you want to request one. Click the Yes button to request your Initial Callsign Certificate; if you have one or more Callign Certificates on another computer, you can move them to the computer you're using.
 Alternatively, start TQSL, and select the Callsign Certificate menu's Request New Callsign Certificate Request... command.
3.The Request a New Callsign Certificate dialog will appear:
 
 In this dialog,
   3.aSpecify your callsign, DXCC entity, and begin date
       3.a.1.Specify your present primary callsign, without any portable identifiers
       3.a.2.Select your DXCC entity
       3.a.3.Set the QSO begin date to the date of the first QSO made with your present primary callsign
       3.a.4.Leave the QSO end date blank
       3.a.5.Click the Next button
   3.bEnter your name and address
       3.b.1.For US callsigns, the mailing address you enter must match your address in the FCC database
       3.b.2.Click the Next button
   3.cEnter your email address; then click the Next button
   3.dYou will be prompted to enter a password
       3.d.1.If you're using a shared computer, you should protect your Callsign Certificate by entering the same password in both textboxes; you'll be asked to provide this password each time you direct TQSL to digitally sign a log file. If you control access to the computer you're using, you can leave both textboxes empty, thereby avoiding the need to provide a password each time you direct TQSL to digitally sign a log file.
       3.d.2.Click the Next button
   3.eIf your computer has internet access, you will be asked if you want to upload this certificate request to LoTW; click the Yes button; if your computer does not have internet access,
       3.e.1.you will be prompted to save a file whose name is your callsign and whose extension is .tq5; save this file in the folder C:\MyLotWCertificates
       3.e.2.this file will be referred to in these instructions as YourCallsign.tq5
   3.fSelect the Callsign Certificates tab; an entry for your Callsign Certificate will be displayed with a pending icon:  (because the certificate is not yet functional).
   3.gIf you did not upload the certificate request to LoTW in step 3.e, protect your pending Callsign Certificate, by directing TQSL to create a Backup File.
   3.hYou can terminate TQSL by selecting its File menu's Exit command (on OS X, by selecting the Application menu's Quit tqsl command).
4.If you did not upload the certificate request to LoTW in step 3.e,
   4.aupload your certificate request file to the ARRL via https://p1k.arrl.org/lotw/upload ; use the Browse button to navigate to the folder C:\MyLotWCertificates and select the YourCallsign.tq5 file you find there.
   4.bRetain the YourCallsign.tq5 file; its presence in C:\MyLotWCertificates will be required when you accept the Callsign Certificate that the ARRL will send you, so don't delete it!
5.If you are a US licensee, you will receive a post card in the mail
   5.aAbove your address on the front of the postcard, you will find your 8-character Postcard Password
   5.bUsing your web browser, visit https://p1k.arrl.org/lotw/password
       5.b.1.Enter your callsign (the one you specified in step 3.a.1 above)
       5.b.2.Enter your Postcard Password
       5.b.3Click the Submit Password button
       5.b.4.You will receive an email message with your Callsign Certificate attached within 3 business days
6.If you are not a US licensee, you will receive an email message asking you to submit proof of license (for example, a copy of your license) and a copy of one other official document that shows your name (for example, a driver's license). For additional details, see https://www.arrl.org/lotw/docreq . You will receive an email message with your Callsign Certificate attached after your documentation is reviewed and accepted.

tqsl-2.0/apps/help/tqslapp/certaccept2.bmp0000664000076400007640000253226612231073120020633 0ustar rmurphyrmurphyBM 6(? (r h' S1#L>8/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}@'xZNb][/,)1/-󢟝1/-/,)OOOooo}}}ghhͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾碟PPPrrrqqq-*'ͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;οοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳݢ-*'WWW```0.,ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳ.,*III222ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ҡ222-*'ͿͿͿͿ-*'-*'ͿͿͿͿޡohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohb뺺ohb-*'-*'̾̾̾̾ohb랞ohb-*'-*'̾̾̾̾ohb뎎ohb-*'-*'̾̾̾̾ohb|||vvvvvvxxxohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohb돏Ŀohb-*'-*'˼˼˼˼ohbuuuohb-*'-*'˼˼˼˼ohbsssohb-*'-*'˼˼˼˼ohb{{{ohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ff::ohbͿ-*'-*'ohb𕌉ff::ohbͿ̾-*'-*'ohb𕌉::ې::ې::ې::ې:ffې:fff::::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::fې::f:f:::f:f::fې:fې:ohbͿ̾-*'-*'ohb𕌉f:::ff::ff:ff::::ې::fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:fff:ff:۶f::f:ې::ff:۶f:fffېf::ېf::ېohbͿ̾;-*'-*'ohb𕌉ff۶::::ې::::::::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::::ې::f::::f::::f:۶::::ffff򶳮ohbͿ;;-*'-*'ohb𕌉ff:f۶:::f۶::::::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:f::ې::f::::f::::f:۶:::fffffohbͿ̾;̽-*'-*'ohb𕌉ffff::ې::ff:::f::fff:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::::۶ff:۶f::ېff۶:fff:۶f:fff::f:ff۶f:ffohbͿ̾̽̽-*'-*'ohb𕌉ff::ې::ې::ېf۶f:ې:::ې::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې:ې::ff:::ff::ff:fff::ې::::ohb̾̽̽˼-*'-*'ohb𕌉:fېff:::::fff::ې:::fff::f:::::222000111222222222222222000222ohb;̽˼˼-*'-*'ohb𕌉:ې:::::ff::ې::::ff::ې::۶:fې::::::000333777<<>>000ohb˼˼ʻʻ-*'-*'ohb𕌉000<<>>DDDIIIRRR\\\\\\[[[YYYWWWSSSOOOEEEJJJDDDDDDCCCBBBBBBEEEHHH===)))+++,,,---...222UUUTTTRRRRRRPPPOOOLLLDDDohb˽˽˽˽-*'-*'ohb𕌉555>>>DDDIIIUUUZZZYYYYYYXXXVVVTTTSSSPPP999EEECCCBBBAAABBBEEEIIIMMMBBB,,,///111222333777[[[ZZZXXXUUUSSSRRROOOKKK***ohb˽˽˽̾-*'-*'ohb𕌉:::===DDDHHHTTTWWWVVVVVVTTTTTTVVVWWWTTTNNNOOOCCCBBBAAAAAAEEEJJJNNNSSSGGG111444666777888<<>>DDDFFFVVVQQQMMMKKKNNNSSSZZZaaahhhnnnqqq]]]BBBBBBCCCIIIQQQZZZdddnnnvvvjjjNNNTTTXXXYYYYYY[[[{{{sssjjjccc[[[UUUQQQDDDohb˽̾̾̾-*'-*'ohb𕌉;;;AAAFFFFFFUUUOOOKKKKKKOOOWWWaaakkkttt{{{}}}gggBBBDDDHHHQQQ[[[fffqqq}}}zzz^^^dddhhhiiiiiikkk~~~tttjjjcccZZZRRRLLLohb̾̾̾̾-*'-*'ohb𕌉999>>>DDDFFFEEEVVVOOOLLLNNNTTT]]]hhhttt~~~nnnEEEJJJOOOZZZaaammmyyykkkrrrwwwyyyyyyzzzwwwqqqhhh```YYYNNNohb̾̾̾̾-*'-*'ohb𕌉;;;AAADDDDDD@@@BBBQQQOOORRRZZZeeeqqq}}}{{{KKKNNNUUUaaaeeeEEELLLWWWbbblllvvv}}}{{{pppcccTTTaaayyynnneee]]]UUUohb̾̾̾̾-*'-*'ohb𕌉888===BBBDDDBBB===<<>>888444RRRZZZ```iiitttnnnFFFJJJCCCVVVWWW___oookkkmmmxxx~~~wwwlllbbbCCCohb̾̾̾̾-*'-*'ohb𕌉;;;@@@BBB@@@888000---222VVVGGGVVV```DDDSSSFFFKKKOOOKKK]]]ZZZaaarrr{{{{{{zzznnngggohb̾̾̾̾-*'-*'ohb𕌉888<<>>CCCGGGKKKOOOTTTWWWlll]]]bbbtttǾ|||pppiiiohb̾̾̾̾-*'-*'ohb𕌉888===@@@???999666222333444777:::===BBBEEEJJJOOOTTTZZZ___YYYdddbbbsssȾ{{{pppMMMohb̾̾̾̾-*'-*'ohb𕌉888===?????????===111333555999<<>>DDDJJJQQQXXX```hhhqqq{{{lllZZZKKK@@@@@@ohb̾̾̾̾-*'-*'ohb𕌉BBBJJJ999777333222333???>>>@@@FFFMMMTTT\\\dddmmmwwwxxxaaaPPPEEEBBBffohb̾̾̾̾-*'-*'ohb𕌉CCCHHHEEE555222222333JJJ===AAAHHHOOOWWW```gggqqq{{{~~~gggUUUJJJDDDffohb̾̾̾̾-*'-*'ohb𕌉GGGEEEGGG666333222<<>>???===;;;===???GGGTTTXXXTTTTTT^^^fffnnnvvvvvvbbbTTT::ېf:::::::ې:::۶f:ff:ff::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ohb̾̾̾̾-*'-*'ohb𕌉AAA<<<;;;999:::===DDDNNN\\\oooZZZ^^^fffooovvv{{{hhhYYY:::f۶:::::f:fېff۶f:f:::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fohb̾̾̾̾-*'-*'ohb𕌉::::::888999<<>>999:::<<>>AAAGGGLLLVVVbbbooo|||xxxYYY::ې::ffohb̾̾̾̾-*'-*'ohb𕌉DDD>>>BBBGGGNNNVVVcccrrr~~~zzzohb̾̾̾̾-*'-*'ohb𕌉DDDAAAHHHNNNWWWfffqqqhhhzzzpppohb̾̾̾̾-*'-*'ohb𕌉EEEFFFMMMWWWfff]]]RRRdddqqqvvv{{{|||wwwohb̾̾̾̾-*'-*'ohb𕌉MMMLLLVVVbbbTTTNNNUUUpppkkkpppuuu|||ohb̾̾̾̾-*'-*'ohb𕌉WWWQQQ^^^jjjgggeeegggxxxiii{{{||||||wwwohb̾̾̾̾-*'-*'ohb𕌉\\\bbboooiii|||yyywwwtttohb̾̾̾̾-*'-*'ohb𕌉dddgggqqqkkksssmmmmmmnnnnnnlllohb̾̾̾̾-*'-*'ohb𕌉ddddddmmmfffdddeeeeeedddnnnohb̾̾̾̾-*'-*'ohb𕌉􏏏pppqqqggg```dddfffohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉򶳮ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾ͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉򶳮ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉VVVmmmbbbQQQBBB999333---(((ohbͿͿͿͿ-*'-*'ohb𕌉>>>kkkyyyuuurrrfff```]]][[[XXXTTTQQQNNNKKKFFFAAA<<<666111,,,ohbͿͿͿͿ-*'-*'ohb𕌉888NNN^^^hhhbbb```WWWccceee___\\\WWWRRRMMMKKKJJJLLLNNNQQQTTTUUUTTTSSSPPPNNNJJJEEE@@@:::555222ohbͿͿͿͿ-*'-*'ohb𕌉000HHHKKK\\\cccfffAAAcccqqqlllnnnnnnmmmkkkhhhaaa\\\VVVQQQNNNLLLLLLLLLNNNPPPRRRTTTTTTUUUTTTWWWZZZohbͿͿͿο-*'-*'ohb𕌉&&&???EEEKKK\\\eeeggg===bbbqqqlllmmmoooppppppppppppooommmkkkhhhddd```\\\XXXUUURRRPPPNNNNNNOOORRRTTTohbͿͿοο-*'-*'ohb𕌉,,,>>>EEEKKK\\\eeehhh>>>aaannnfffeeeeeeeeeeeeeeeeeedddcccbbbaaa___^^^]]][[[ZZZXXXVVVUUUSSSPPPOOOPPPohbͿͿοο-*'-*'ohb𕌉,,,>>>EEEKKK]]]fffhhh???ZZZeee^^^```bbbcccdddeeeeeedddcccbbbaaa___^^^\\\[[[YYYWWWVVVTTTSSSQQQNNNMMMohbͿͿοο-*'-*'ohb𕌉555<<>>>>>IIIMMMbbbqqqvvvHHHqqqqqqpppooonnnnnnmmmmmmnnnooopppqqqtttvvvsssmmmhhhZZZNNNNNNohb-*'-*'ohb𕌉777@@@IIIMMMggguuuvvvGGGcccMMMNNNohb-*'-*'ohb𕌉666@@@IIIMMMrrrPPPbbbMMMNNNohb-*'-*'ohb𕌉777@@@IIIMMMrrr[[[fffNNNNNNohb-*'-*'ohb𕌉???IIIMMMrrrYYYzzzsssmmmgggVVVNNNNNNohb-*'-*'ohb𕌉AAAIIIMMMtttZZZ}}}zzzwwwtttooojjjgggeeecccccceeefffgggohb-*'-*'ohb𕌉IIIMMMxxx}}}\\\}}}zzzwwwsssrrrqqqppppppqqqqqqrrrrrrrrrrrrrrrpppoooohb-*'-*'ohb𕌉NNN|||yyyuuurrrqqqqqqohb-*'-*'ohb𕌉}}}ohb-*'-*'ohb𕌉vvvohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉򶳮ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ãS<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<=????????????????????????????????????????????????????????????????????????[>Uohb-*'-*'ohb𕌉<>c%h'i(i(i(i(i(i'!!!>-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞ A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*%%%C0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'olj(,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝omiya@=4$ .+(.,*cbadmBFZ/-+.+(544uTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'D1P:EDDtqsl-2.0/apps/help/tqslapp/certaccept1.bmp0000664000076400007640000253226612231073120020632 0ustar rmurphyrmurphyBM 6(? (r h' S1#L>8/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)FFFTTTppp}}}@'xZNb][/,)1/-󢟝1/-/,)OOOooo}}}ghhͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾̾碟PPPrrrqqq-*'ͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;οοοοοοοοοͿͿͿͿͿͿͿͿͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹǹȺɻʼ˽̾̾Ϳݢ-*'WWW```0.,ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˼˼˼˼˼˼̽̽̽;;οοοοοοοοοοͿͿͿͿͿͿͿ̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻʼ˽̾Ϳ.,*III222ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˼˼˼˼˼˼̽̽;;οοοοοοοοοοοͿͿͿͿͿͿ̾̾ͿͿοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾ҡ222-*'ͿͿͿͿ-*'-*'ͿͿͿͿޡohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohb뺺ohb-*'-*'̾̾̾̾ohb랞ohb-*'-*'̾̾̾̾ohb뎎ohb-*'-*'̾̾̾̾ohb|||vvvvvvxxxohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'̾˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohb돏Ŀohb-*'-*'˼˼˼˼ohbuuuohb-*'-*'˼˼˼˼ohbsssohb-*'-*'˼˼˼˼ohb{{{ohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼˼̽̽ohbohb-*'-*'˼̽̽;ohbohb-*'-*'̽̽;;ohb½½ohb-*'-*'̽̽;;ohbohb-*'-*'̽̽;οohbohb-*'-*'̽;;οohb``ohb-*'-*';;οohb``ohb-*'-*';;οohb66·`·6```666`·66``666`·66`6``6ohb-*'-*';οohb`666·`6666·6·`6`66·6·`66·66``6Ϋ`6`·66ohb-*'-*';οohb``66·66·66·66·6666``6666`6`666ohb-*'-*'οohb``6666·66·6666``6666`6Ϋ6666ohb-*'-*'οohb``66``66·6666`6``66``6Ϋ```66ohb-*'-*'ohb``6·666·6``6666666666`66ohb-*'-*'ohb6`·``666666ohb-*'-*'ohb6·6666666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohbͿ-*'-*'ohb𕌉ff::ohbͿ-*'-*'ohb𕌉ff::ohbͿ̾-*'-*'ohb𕌉::ې::ې::ې::ې:ffې:fff::::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::fې::f:f:::f:f::fې:fې:ohbͿ̾-*'-*'ohb𕌉f:::ff::ff:ff::::ې::fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:fff:ff:۶f::f:ې::ff:۶f:fffېf::ېf::ېohbͿ̾;-*'-*'ohb𕌉ff۶::::ې::::::::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::::ې::f::::f::::f:۶::::ffff򶳮ohbͿ;;-*'-*'ohb𕌉ff:f۶:::f۶::::::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:f::ې::f::::f::::f:۶:::fffffohbͿ̾;̽-*'-*'ohb𕌉ffff::ې::ff:::f::fff:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::::۶ff:۶f::ېff۶:fff:۶f:fff::f:ff۶f:ffohbͿ̾̽̽-*'-*'ohb𕌉ff::ې::ې::ېf۶f:ې:::ې::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې:ې::ff:::ff::ff:fff::ې::::ohb̾̽̽˼-*'-*'ohb𕌉:fېff:::::fff::ې:::fff::f:::::222000111222222222222222000222ohb;̽˼˼-*'-*'ohb𕌉:ې:::::ff::ې::::ff::ې::۶:fې::::::000333777<<>>000ohb˼˼ʻʻ-*'-*'ohb𕌉000<<>>DDDIIIRRR\\\\\\[[[YYYWWWSSSOOOEEEJJJDDDDDDCCCBBBBBBEEEHHH===)))+++,,,---...222UUUTTTRRRRRRPPPOOOLLLDDDohb˽˽˽˽-*'-*'ohb𕌉555>>>DDDIIIUUUZZZYYYYYYXXXVVVTTTSSSPPP999EEECCCBBBAAABBBEEEIIIMMMBBB,,,///111222333777[[[ZZZXXXUUUSSSRRROOOKKK***ohb˽˽˽̾-*'-*'ohb𕌉:::===DDDHHHTTTWWWVVVVVVTTTTTTVVVWWWTTTNNNOOOCCCBBBAAAAAAEEEJJJNNNSSSGGG111444666777888<<>>DDDFFFVVVQQQMMMKKKNNNSSSZZZaaahhhnnnqqq]]]BBBBBBCCCIIIQQQZZZdddnnnvvvjjjNNNTTTXXXYYYYYY[[[{{{sssjjjccc[[[UUUQQQDDDohb˽̾̾̾-*'-*'ohb𕌉;;;AAAFFFFFFUUUOOOKKKKKKOOOWWWaaakkkttt{{{}}}gggBBBDDDHHHQQQ[[[fffqqq}}}zzz^^^dddhhhiiiiiikkk~~~tttjjjcccZZZRRRLLLohb̾̾̾̾-*'-*'ohb𕌉999>>>DDDFFFEEEVVVOOOLLLNNNTTT]]]hhhttt~~~nnnEEEJJJOOOZZZaaammmyyykkkrrrwwwyyyyyyzzzwwwqqqhhh```YYYNNNohb̾̾̾̾-*'-*'ohb𕌉;;;AAADDDDDD@@@BBBQQQOOORRRZZZeeeqqq}}}{{{KKKNNNUUUaaaeeeEEELLLWWWbbblllvvv}}}{{{pppcccTTTaaayyynnneee]]]UUUohb̾̾̾̾-*'-*'ohb𕌉888===BBBDDDBBB===<<>>888444RRRZZZ```iiitttnnnFFFJJJCCCVVVWWW___oookkkmmmxxx~~~wwwlllbbbCCCohb̾̾̾̾-*'-*'ohb𕌉;;;@@@BBB@@@888000---222VVVGGGVVV```DDDSSSFFFKKKOOOKKK]]]ZZZaaarrr{{{{{{zzznnngggohb̾̾̾̾-*'-*'ohb𕌉888<<>>CCCGGGKKKOOOTTTWWWlll]]]bbbtttǾ|||pppiiiohb̾̾̾̾-*'-*'ohb𕌉888===@@@???999666222333444777:::===BBBEEEJJJOOOTTTZZZ___YYYdddbbbsssȾ{{{pppMMMohb̾̾̾̾-*'-*'ohb𕌉888===?????????===111333555999<<>>DDDJJJQQQXXX```hhhqqq{{{lllZZZKKK@@@@@@ohb̾̾̾̾-*'-*'ohb𕌉BBBJJJ999777333222333???>>>@@@FFFMMMTTT\\\dddmmmwwwxxxaaaPPPEEEBBBffohb̾̾̾̾-*'-*'ohb𕌉CCCHHHEEE555222222333JJJ===AAAHHHOOOWWW```gggqqq{{{~~~gggUUUJJJDDDffohb̾̾̾̾-*'-*'ohb𕌉GGGEEEGGG666333222<<>>???===;;;===???GGGTTTXXXTTTTTT^^^fffnnnvvvvvvbbbTTT::ېf:::::::ې:::۶f:ff:ff::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ohb̾̾̾̾-*'-*'ohb𕌉AAA<<<;;;999:::===DDDNNN\\\oooZZZ^^^fffooovvv{{{hhhYYY:::f۶:::::f:fېff۶f:f:::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fohb̾̾̾̾-*'-*'ohb𕌉::::::888999<<>>999:::<<>>AAAGGGLLLVVVbbbooo|||xxxYYY::ې::ffohb̾̾̾̾-*'-*'ohb𕌉DDD>>>BBBGGGNNNVVVcccrrr~~~zzzohb̾̾̾̾-*'-*'ohb𕌉DDDAAAHHHNNNWWWfffqqqhhhzzzpppohb̾̾̾̾-*'-*'ohb𕌉EEEFFFMMMWWWfff]]]RRRdddqqqvvv{{{|||wwwohb̾̾̾̾-*'-*'ohb𕌉MMMLLLVVVbbbTTTNNNUUUpppkkkpppuuu|||ohb̾̾̾̾-*'-*'ohb𕌉WWWQQQ^^^jjjgggeeegggxxxiii{{{||||||wwwohb̾̾̾̾-*'-*'ohb𕌉\\\bbboooiii|||yyywwwtttohb̾̾̾̾-*'-*'ohb𕌉dddgggqqqkkksssmmmmmmnnnnnnlllohb̾̾̾̾-*'-*'ohb𕌉ddddddmmmfffdddeeeeeedddnnnohb̾̾̾̾-*'-*'ohb𕌉􏏏pppqqqggg```dddfffohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉򶳮ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾̾-*'-*'ohb𕌉ohb̾̾̾Ϳ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾̾ͿͿ-*'-*'ohb𕌉ohb̾ͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉򶳮ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉ohbͿͿͿͿ-*'-*'ohb𕌉VVVmmmbbbQQQBBB999333---(((ohbͿͿͿͿ-*'-*'ohb𕌉>>>kkkyyyuuurrrfff```]]][[[XXXTTTQQQNNNKKKFFFAAA<<<666111,,,ohbͿͿͿͿ-*'-*'ohb𕌉888NNN^^^hhhbbb```WWWccceee___\\\WWWRRRMMMKKKJJJLLLNNNQQQTTTUUUTTTSSSPPPNNNJJJEEE@@@:::555222ohbͿͿͿͿ-*'-*'ohb𕌉000HHHKKK\\\cccfffAAAcccqqqlllnnnnnnmmmkkkhhhaaa\\\VVVQQQNNNLLLLLLLLLNNNPPPRRRTTTTTTUUUTTTWWWZZZohbͿͿͿο-*'-*'ohb𕌉&&&???EEEKKK\\\eeeggg===bbbqqqlllmmmoooppppppppppppooommmkkkhhhddd```\\\XXXUUURRRPPPNNNNNNOOORRRTTTohbͿͿοο-*'-*'ohb𕌉,,,>>>EEEKKK\\\eeehhh>>>aaannnfffeeeeeeeeeeeeeeeeeedddcccbbbaaa___^^^]]][[[ZZZXXXVVVUUUSSSPPPOOOPPPohbͿͿοο-*'-*'ohb𕌉,,,>>>EEEKKK]]]fffhhh???ZZZeee^^^```bbbcccdddeeeeeedddcccbbbaaa___^^^\\\[[[YYYWWWVVVTTTSSSQQQNNNMMMohbͿͿοο-*'-*'ohb𕌉555<<>>>>>IIIMMMbbbqqqvvvHHHqqqqqqpppooonnnnnnmmmmmmnnnooopppqqqtttvvvsssmmmhhhZZZNNNNNNohb-*'-*'ohb𕌉777@@@IIIMMMggguuuvvvGGGcccMMMNNNohb-*'-*'ohb𕌉666@@@IIIMMMrrrPPPbbbMMMNNNohb-*'-*'ohb𕌉777@@@IIIMMMrrr[[[fffNNNNNNohb-*'-*'ohb𕌉???IIIMMMrrrYYYzzzsssmmmgggVVVNNNNNNohb-*'-*'ohb𕌉AAAIIIMMMtttZZZ}}}zzzwwwtttooojjjgggeeecccccceeefffgggohb-*'-*'ohb𕌉IIIMMMxxx}}}\\\}}}zzzwwwsssrrrqqqppppppqqqqqqrrrrrrrrrrrrrrrpppoooohb-*'-*'ohb𕌉NNN|||yyyuuurrrqqqqqqohb-*'-*'ohb𕌉}}}ohb-*'-*'ohb𕌉vvvohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉򶳮ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉uuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb𕌉䏏ohb-*'-*'ohb𕌉uuuuuuohb-*'-*'ohb𕌉pppc%h'i(i(i(i(i(i'pppohb-*'-*'ohb𕌉pppX!h'i'i'j'j'k'k&k&l&l%k$pppohb-*'-*'ohb𕌉pppg$m&l%m%m%n%o%o$p%p#p#q#q#r#m pppohb-*'-*'ohb𕌉pppo$q$p#q#q#r#s$qt#ru#u!u!v!v!w!x pppohb-*'-*'ohb𕌉pppt"s"t"u!u!u!x% mjoy!wz zz{{{pppohb-*'-*'ohb𕌉pppw w x y yy|" tGMЯx~~pppohb-*'-*'ohb𕌉ppp{||}}{/5Ó{ pppohb-*'-*'ohb𕌉ppp!qu pppohb-*'-*'ohb𕌉ppp׶SW pppohb-*'-*'ohb𕌉ppp ə8< pppohb-*'-*'ohb𕌉pppwzԧ!vxKN!%    pppohb-*'-*'ohb𕌉ppp \_̑ɅBE    pppohb-*'-*'ohb𕌉ppp su ʁ'*eg  pppohb-*'-*'ohb𕌉ppp   :=[] ̀!no    pppohb-*'-*'ohb𕌉ppp      ~       pppohb-*'-*'ohb𕌉ppp   }~  pppohb-*'-*'ohb𕌉ppp       {| pppohb-*'-*'ohb𕌉pppڏ~pppohb-*'-*'ohb𕌉pppڣ ڄHHpppohb-*'-*'ohb𕌉pppۚȝpppohb-*'-*'ohb𕌉pppۧ֨pppohb-*'-*'ohb𕌉ppp۪՟pppohb-*'-*'ohb𕌉pppݠͥtt11^^ŵpppohb-*'-*'ohb𕌉ppp݋ġءՌՉٙpppohb-*'-*'ohb𕌉pppݩpppohb-*'-*'ohb𕌉pppݺpppohb-*'-*'ohb𕌉ppp뙙ƿpppffohb-*'-*'ohb𕌉ppp뢢{}{pppffohb-*'-*'ohb𕌉ppp릦׹ppp:f:ffff:::fff:::fff::::ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::ohb-*'-*'ohb𕌉ppp즦տppp::ff:۶f:::ې::fې:ې::::ې::fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:ffohb-*'-*'ohb𕌉ppp좢ʰ옘prpppp::::f:۶::ې::ې::::::ې:::fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ohb-*'-*'ohb𕌉ppp옘ϲ컻Ͻppp::::f:::ې::::::::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fohb-*'-*'ohb𕌉ppp췷Ɲ즦}~ppp::ff:۶fffff::fff:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::ohb-*'-*'ohb𕌉pppĘٱppp:::f::ې::::ې::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ېohb-*'-*'ohb𕌉pppȥppp:::::fff::ې:::fff::f:::ohb-*'-*'ohb𕌉ppp휜ο횚ppp::::ff::ې::::ff::ې::۶:fې::::ohb-*'-*'ohb𕌉ppp襤°Ѱppp::::ې::ffohb-*'-*'ohb𕌉pppγpppohb-*'-*'ohb𕌉ppp︸pppohb-*'-*'ohb𕌉pppﹹpppohb-*'-*'ohb𕌉f:ېppppppohb-*'-*'ohb𕌉2^^Rjj::ppppppohb-*'-*'ohb𕌉2Tfې::f::ې:f:f::ې::fff:::ې::ې::ې:ffff:::fې:::fې:ppppppohb-*'-*'ohb𕌉2Tf::ې:fff:::ې:::fffff::f:::ې::ې:::f:::ې:ېf:ffېf::ېppppppohb-*'-*'ohb𕌉2T::۶:fې::ff۶:::fې::::::ې::ې::ې::ې::::ې::ې::ې::ffppppppohb-*'-*'ohb𕌉mmmmmmmmmmmmmmmmmm2T::ې::ffff:::::f۶::::ې::ې::ې::ې::::ې::ې:fffppppppohb-*'-*'ohb𕌉2T::ې::ffff::f:ff:::f::ې::ې::ې:::fff::۶ff::f:ffppppppohb-*'-*'ohb𕌉2T:::fې::ff::::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې::ppppppohb-*'-*'ohb𕌉2T:::ې:fې::fېff:::fff::f:::uuuuuuohb-*'-*'ohb𕌉2T:::ې::ې:::ff::ې::۶:fې::::葑ohb-*'-*'ohb𕌉Jff""""""""Tffwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohb𕌉VVzohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉󕌉ϕohb-*'-*'ohb𕌉󕌉ѕohb-*'-*'ohb𕌉TTҖvv00Ҵҕohb-*'-*'ohb𕌉UԗUww00Զԕohb-*'-*'ohb𕌉1Wؚz1WؚWz1ع1zؚWz1Wؚz1z1zz11عWWW1z11عWWW1z11عz1Wؚzz11عzz11عWz11z1عzWz1WWW1z11عWWW1z11عz1Wؚzz11عzz11عz1Wؚz1Wؚz1ؚWWWW1z11عWWW1z11عz1Wؚzz11عzz11عWz1ؕffohb-*'-*'ohb𕌉{11ڻڜWڜW1{W1Wڻ{{{11ڻ1{{1ڻڜW{1{{11ڻW{1ڻWڜW{{11ڻ{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڜW1{{11ڻ{W1ڜ{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11ڻ{{11ڻڜWڜW1{W1{ڜW{{11ڻ1{{1ڻ{W1ڜ{{11ڻWڜW1{W{{11ڻ{{11{{Wڻ11{ڻ{ڕffohb-*'-*'ohb𕌉{11ۼ{{11ۼ{X1X{1ۼ{{11ۼۜ1Xۼ{{{11{{11ۼۜ1X{{{11ۼ{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜۜXXۜ{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼ{{11ۼ{{11ۼ{X1{{11ۼ{11ۼ{{{11ۼ{{11ۼ{{11{{11ۼ{X1{{11ۼ{{11ۼۜXXۜە:ffff:::ې::ې::fې:::f:ې:::::f::ې::fff:::ې::ې::ې:ffff:::fې:::fې:ohb-*'-*'ohb𕌉}22ݾ}}22ݾ}Y2}}22ݾ}}22ݾ}}22ݾݝYY}}22ݾݝ2Y}}2Y}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝYY}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾ}}22ݾ}}22ݾ}Y2}}22ݾ}2}2ݾ}}22ݾ}}22}}22ݾ}Y2}}22ݾ}}22ݾYYݝݕ:fff۶:::ې:ې::ې::ېf:::::fې::ې:::::fffff::f:::ې::ې:::f:::ې:ېf:ffېf::ېohb-*'-*'ohb𕌉55^^5ɨ^^^5555^^ɨ55Ʉ^^^^555^^^55Ʉ55^^5ɨ^5^^5^5^^^^55^^55Ʉ55^^5ɨ^5^^555^^5ɨ^5^^^55Ʉ55^^5ɨ^5^^5^5^^때:fې::ې::ې::ې::ff۶::fې:::ې:::::fې::::::ې::ې::ې::ې::::ې::ې::ې::ffohb-*'-*'ohb𕌉555^555^ʄ55^555^^55ʄ55^^55ʄ5^^555ʄ5^쨄55^^55^^5ʄ555ʄ5^^555ʄ5^쨄55^^555^^^55ʄ5^^555ʄ5^쨄55^^55알::::ې::ې::ff::ې::::ې:::::::f۶::::ې::ې::ې::ې::::ې::ې:fffohb-*'-*'ohb𕌉555̅5_̅5555_̅__55555555핌f:ff::ې::f:ff۶::ff:::ff:f:ff:::f::ې::ې::ې:::fff::۶ff::f:ffohb-*'-*'ohb𕌉555Ά555Ά555Ά55555Ά555555Ά55::ې::ې::ې::::ې::ې::ې::ff::ې::ې::ff:ff:::f:۶ff::ې:ې:::ې::ohb-*'-*'ohb𕌉𕌉:fff::ې:::fff::f:::ohb-*'-*'ohb𕌉񕌉ff::ې::::ff::ې::۶:fې::::ohb-*'-*'ohb𕌉򕌉::ې::ffohb-*'-*'ohb𕌉򕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohb𕌉ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼̼ohb-*'-*'ohbohb-*'-*'ohb3~b8Z~ohb-*'-*'ohb[3߮6Y~ohb-*'-*'ohbމa2ޮ6Y}ohb-*'-*'ohbܮ6X|ܮ6X|6X|܉2[ܮX[[[3|a363X|[[6X|܉26|ܮ6X|ܮ6X|ܮXр2܉26|ܮXX3|a363X|[[6X|܉26|ܮ6X|ܮ6X|܉233|a363X|6X|6X|aa❮6X|a26X|6X|ܮ6X|܉23܉2[6X|[[6X|6X|ܮ6X|ܮXX3|a363X|[[܉2[ܮ6X|ܮ6X|܉2[6X|6X6[XXohb-*'-*'ohbڬ6W{ڬ6W{6W{W~1ڇ{2{~16W{`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{ڬ6W{ڬWWڇ`12{~1`ڇ2໇61{6W{ڬ6W{WWڇ`16W{ڬ6W{`Wڇ{`ڇ2໇61{6W{6W{6~~16W{WW6~6{6W{ڬ6W{`Wڇ{W~1ڬ6W{ڬ6W{ڬ6W{6W{ڬ6W{2{~1`ڇ2໇61{6W{ڬW~1ڬ6W{ڬ6W{W~1ڬ6W{W~1ڇ`1ohb-*'-*'ohb٫6Wz٫6Wz6Wz`1ߛ6~Y6Wzه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz٫6Wzه`1ߛYW`1ߛه`1ߛ62zz6Wz٫6Wz`1ߛYW6Wz٫6Wz2zWه`1ߛ62zz6Wz6Wz6~W6Wzه21ߺ٫6Wz6Wz٫6Wz2zWه`1ߛ٫6Wz٫6Wz٫6Wz6Wz٫6Wz`1ߛه`1ߛ62zz6Wzه`1ߛ٫6Wz٫6Wz`1ߛ٫6Wz6Wz2zWohb-*'-*'ohb׫6Vy׫6Vy6Vy1Yׇ1V6Vy`6y6Vy׫6Vy`1ޚYV6Vy׫6Vy׫6Vyׇ`1ޚYV`1ޚ`6y6Vy׫6Vy`1ޚYV6Vy׫6Vyׇ`1ޚ`6y6Vy6Vy1}1׫6Vyׇ21޹׫6Vy6Vy׫6Vyׇ`1ޚׇ1Y6Vy׫6Vy׫6Vy6Vy׫6Vy`1ޚ`6y6Vyׇ1Y׫6Vy׫6Vy1Y6Vy6VyYVohb-*'-*'ohb֪VV5Vy5Vy5Vy`}12yV֪5Vy֪5Vy5Vy֪5VyVVֆ51yVY``ݙ֪5Vy֪VVֆ51y2y}1֪5Vy5Vy֪5VyVVֆ51yVY``ݙֆֆ21ݸ֪5Vy5Vy5Vy`֪Y֪5VyVV5}5yVY``ݙֆֆ21ݸ֪5Vy`}1V}1֪5Vy֪5Vy5Vy֪5Vy2y}1֪5Vy5Vy֪5Vy`}1֪V5y5Vy`}15VyV2ݸ51yohb-*'-*'ohbԪ5UwԪ5Uw5UwԆ0_ۗԪU{0ԪUXXXUX5UwԆ0UԪ5U_{w{0Ԫ5UwԆ0U1wUXXUX5UwԆ0UԪ5U_{w{0Ԇ_0ۗXXԪ5Uw5Uw1wU5UwԆ0{05Uw5U_{w{0Ԇ_0ۗԆ0_ۗ5U5XUX5UwU{05Uw1wUXXUXԆ0_ۗԪ5UwԪ5UwԆ0_ۗ5Uw5Uw0{0ohb-*'-*'ohbԩ5Uwԩ5Uw_ԅ1۶ԩ5Uwԩ5Uwԩ5Uwԩ5Uw1wUԩ5Uw5Uw1wUԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwԩ5Uwohb-*'-*'ohb8\ɀ8\ɀb38\ɀ8\ɀ8\ɀ8\ɀ3\8\ɀ8\ɀ3\8\ɀ\\8\ɀ8\ɀ8\ɀ8\ɀohb-*'-*'ohb]ӄ484ʂ8]ʂbb84ʂ8]ʂ84ʂ558]ʂ8]ʂ84ʂ5584ʂb584ʂ8]ʂ8]ʂ8]ʂohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'몦rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻ˼˼˼˽˽˽˼˼˼̽̽;;;̾̾̾Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;̽˼˼ʻʻ˼˼˼˽˽˽˼˼˼˼̽;;;̾̾̾ͿͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿͿ̾̽̽˼˼˼˼˼˽˽˼˼˼˼˼̽̽;;̾̾̾ͿͿοͿ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾̾̽;̽̽˼˽˽˼˼˼˼˼̽̽̽̽̾̾̾ͿͿο;Ϳ-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̾;;̽̽˽˽˼˼˼˼˼̽̽̽̽˽̾̾Ϳοο;Ϳ-*'-*' οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿ;;̾̾˽˽˼˼˼˼̽̽̽̽˽˽̾Ϳοο;Ϳ-*'-*'aV  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿͿ̾̽˼˼˼˼̽̽̽˽˽˽˽̾οο;ͿͿ-*'-*'HwX οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾;;̽̽˼̽̽̽̽̽˽˽˽̾;;;ͿͿͿο-*'-*' %XksbPοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾Ϳ;;̽̽˼̽̽̽˽˽˽˽̾;̽̽ͿͿοफ़vqkZVQZVQZVRZVR[VR[VR[VR[VR[WR[WS[WR[WS[WS[WS[WS\XS\XT\XS\XS\XS\XT\XT\XT\XT\XT\XU\XU\XU\XU^ZW^ZW^ZW^ZW^ZW^ZW^ZW]YU_[W_[W]YU\XU\XU\XU^[W^[W^[W_[X_[X_[X_[X_[X&b&S&S&S'T(T (V!)V!*W"+X$-X%-Y%.Z'/Z'0[(0])1])1])1])1^)1])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P*4fXa-*'-*'Cxe #PNդM۩N}ņοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾Ϳ;;̽;̽̽̽˽˽˽̾̾;;̽̾Ϳο^ZUz.<꯵ܯޮ߮୵୵⭵䭷孷嫹髹髹뫹쫹쫹쬻뫺髺髹譸孵孵䭵᭵᳹᭱͐*.O-*'-*'-.fvh#(ڧJR‚QOئKƒ}οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿο;ο;;̽˽˽˽̾̾;̽̽̾ͿͿͿο坖ƼŻŻżŻƼƽƼƽƽƽƽƽǾǾǾǾǾȿǾǾǾǾԀwqȿȿ(5r|r}p}p~p~ppppooonnlllllllllllllllllnnooopppp~p~t~ȞԘW[-*'-*' 6~je #QÂRӬOMܫO~οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾οοο;̾˽˽̾̾;̽̽̾ͿͿ̾Ϳοpjeļ;;;;ͿͿͿ¹{smºººººººûûûºººûûûûûûûüüüû#.}dpdpdqdqcrcrcrbtbvbv`v`x`y`y`z`z`z`z`z`z`z`z`z`{`{`{`{`{`{`{`{`z`y`ybwbvbvbtcrcrcrdqdqpz!&O-*'-*'-*'-*'AljkVVEV; MP֤QMاQ~‚οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺǹȺȺɻɻ˽̾̾ͿͿ̾̾̾;;̽̾̾ͿͿ̾̾ͿZVR¶¶¶÷~qlfVShXUhXUhXUhXUhXUhXUhXUhXUhXU~qløĸĹĹøĸunjŹŹŹŹŹźyfVSfVSfVSfVSfVSfVSfVSfVSfVSfVSzƻƻƺƺƺƺ%xHUHVHVHVHVGVGVFYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYD]D]D]D]D\DZDZDZDYFXGVGVHVHVHVHV;-*'-*'8HxxxxxvvvvvvvvvvvvvvkihYVfVSkivvvvvvvvvvvvvwyyyyʮ'-J-*'-*'cV7<8. 13οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿ̾ͿͿͿͿ[WS℁~fVSfVSfVSfVSfVSfVSfVSfVSBL~~~~~|||||||||||||mkhYVhYVmk||||||||||}}}ͱ*0L-*'-*'  οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾̾ͿͿοͿͿͿ[WS冃fVSiYVFO䄌τфӄӄփ׃كۃރ߃ₐゐ悐灐灐遐omhYVfVShYVom遏邏炏悏わハ჎߄݄ۄلׅօӅӅѵ.3N-*'-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾ͿͿͿͿ[WSꊇfVSiYVOX萙אِِؐݐݐᐚ䐚君珛鏛돛쎛펛펛fVSfVSurfVSfVS펚폚폚돚鏚萚呛呛㑛ᑛߑݑّّܑؼ49Q-*' οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ[WS댉䜒fVSfVSfVSfVSfVSfVSfVSfVSfVSfVST^阠٘ۘݘݘᘢ㘢嘢嘣阣阣엣헣yvfWUfWUfWUyuyufWUfWUfWUyu혢혢뙣陣虣噣噣㙢ᙢߙݙݙ8=S᠞+*)A/.,*οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾Ϳ[WSZb렦ݠݠࠦᠨ㠨䠨堩蟪韪럪ퟪퟫ젪頪顩衩塩䡧㡧ᡧࡧ;@U.,*GECC0.+(οοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ˽̾Ϳ[WS_f᦬᦬᦬㦭夭央褮餮뤯쥮륮饮祮姭䧭㧭᧭?BV衟-*'b`](,οͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾̾[WT`iᬱᬲ䬳嬳嬴謴髴骳荒הּ쬴鬳鬳笳嬳嬲䬱?DY렝b`]{xua@=4$ .+(.,*cbadmBFZ/-+.+(c`^{xuuTTR73% -*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'\ZWmjg{tqsl-2.0/apps/help/tqslapp/certaccept.htm0000664000076400007640000001431512231073120020547 0ustar rmurphyrmurphyAccepting an Initial Callsign Certificate

Accepting an Initial Callsign Certificate

LoTW requires that you accept your Initial Callsign Certificate using the same computer from which you generated the request for your Initial Callsign Certificate.

These instructions assume that your Callsign Certificate reside in the folder C:\MyLoTWCertificates (if you've stored them in a different folder, adjust the instructions accordingly).

When you receive an email message from the ARRL with an attached file named YourCallsign.tq6 (for example, CT2IRY.tq6),
1.Direct your email application to open the email message.
   1.aThe attached file contains your Initial Callsign Certificate -- save it into the folder C:\MyLotWCertificates
   1.bThe message will contain a Web Account Username and a Web Account Password; be sure to record these, as they are required to view your uploaded QSOs and LoTW-generated confirmations via https://p1k.arrl.org/lotwuser/default
2.To proceed, the YourCallsign.tq5 file must be present in C:\MyLotW\Certificates ; if you deleted this file, or initiated the request from a different computer, you'll have to start over by requesting a new Callsign Certificate from the ARRL.
3.Start TQSL and select the Callsign Certificates tab:
 
   3.aClick the Load a Callsign Certificate button; the Select Certificate File dialog will appear
   3.bIn the Select Certificate File dialog,
       3.b.1.Set the Files of type selector (on OS X, set the Enable selector) to Certificate Request response files (*.tq6)
       3.b.2.Select the file YourCallsign.tq6 in your C:\MyLotWCertificates folder
       3.b.3.Click the Open button; a small Install Certificate dialog will appear.
   3.cIn the Install Certificate dialog, you'll be asked if its okay to install a trusted root certificate; click the Yes button
   3.dIn the Load Certificate File dialog, click the Finish button
   3.eThe Callsign Certificates tab will show an entry for your Callsign Certificate, with a yellow medal valid icon: .
    
   3.fTo protect your new Callsign Certificate, direct TQSL to create a Backup File.
   3.gYou can terminate TQSL by selecting its File menu's Exit command (on OS X, by selecting the Application menu's Quit tqsl command).
4.At the completion of this phase, the folder C:\MyLotWCertificates will contain
   *the Certificate Request file YourCallsign.tq5 -- request sent to ARRL (no longer needed)
   *the Certificate file YourCallsign.tq6 -- contains your actual Callsign Certificate, in a form that cannot be moved or copied
5.If you have TQSL installed on multiple computers, then perform the following steps on each such computer:
   5.aDelete the files YourCallsign.tq6 and YourCallsign.p12 if they are present, as these files now contain obsolete information
   5.bObtain a copy of the Backup File you created in step 3.f (via your home network, or by using a thumb drive)
   5.cStart TQSL, and direct it to Restore from the backup file you obtained in step 5.b; this will update all Callsign Certificates, Station Locations, and Preferences on this computer to match those on the computer you used to accept the Callsign Certificate in step 3

A table illustrating the icons used by Windows to designate the above-mentioned LoTW file types in Windows Explorer is provided here. tqsl-2.0/apps/help/tqslapp/cabrillo.htm0000664000076400007640000000227612231073120020224 0ustar rmurphyrmurphyPredefined Cabrillo Contest Definitions

Predefined Cabrillo Contest Definitions

Without additional configuration, TQSL can digitally sign and submit Cabrillo files that specify any of the following contests:

  • AP-SPRINT
  • ARRL-10, ARRL-160
  • ARRL-DX-CW, ARRL-DX-SSB, ARRL-RTTY
  • ARRL-SS-CW, ARRL-SS-SSB
  • ARRL-UHF-AUG
  • ARRL-VHF-JAN, ARRL-VHF-JUN, ARRL-VHF-SEP
  • BARTG-RTTY
  • CQ-160-CW, CQ-160-SSB
  • CQ-VHF
  • CQ-WPX-CW, CQ-WPX-RTTY, CQ-WPX-SSB
  • CQ-WW-CW, CQ-WW-RTTY, CQ-WW-SSB
  • DARC-WAEDC-CW, DARC-WAEDC-RTTY, DARC-WAEDC-SSB
  • IARU-HF
  • NA-SPRINT-CW, NA-SPRINT-SSB
  • NAQP-CW, NAQP-RTTY, NAQP-SSB
  • NEQP
  • OCEANIA-DX-CW, OCEANIA-DX-SSB
  • RSGB-IOTA
  • SAC-CW, SAC-SSB
  • STEW-PERRY
  • TARA-RTTY
  • WAEDC

To digitally sign and submit a Cabrillo file that specifies a contest not on the above list, you can add a Cabrillo contest definition.

tqsl-2.0/apps/help/tqslapp/backuprestore.htm0000664000076400007640000001122212231073120021275 0ustar rmurphyrmurphyBacking Up and Restoring Callsign Certificates, Station Locations, and Preferences

Backing Up and Restoring Callsign Certificates, Station Locations, and Preferences

TQSL can be directed to save all of your Callsign Certificates, Station Locations, and Preferences in a single .tbk file. If you copy this .tbk file to a safe place, you'll be able to quickly recover from a computer failure by directing TQSL to restore your Callsign Certificates, Station Locations, and Preferences. You can configure TQSL to automatically create a backup in a specified folder when terminating.

Safe Places to Store your Callsign Certificates, Station Locations, and Preferences

An external hard drive, a thumb drive, or another computer on your home network will provide local backup that you can quickly access, but will not provide protection against a local catastrophe. A free "cloud storage service" like DropBox or Google Drive or Microsoft SkyDrive can provide better protection, but requires internet access for both backup and recovery. Ideally, important files should be saved both locally and in cloud storage.

Creating a Backup File
To save your Callsign Certificates, Station Locations, and Preferences to a Backup File,
1.Select the File menu's Backup Station Locations, Certificates, and Preferences... command.
2.In the Enter file to save to dialog that appears,
   2.aNavigate to the Folder in which you want the Backup File created.
   2.bSpecify the File name of the Backup File to be created.
   2.cClick the Save button

Configuring TQSL to Automatically Create a Backup File When Terminating
To configure TQSL to automatically create a Backup File when terminating,
1.Select the File menu's Display or Modify Preferences... command (on OS X, select the Application menu's Preferences command).
2.In the Preferences dialog that appears, select the Options tab; on this tab,
   2.aCheck the Allow automatic configuration backup box.
   2.bClick the Browse button to the right of the Backup File Folder textbox and use the Browse For Folder dialog that appears to select the folder in which Backup Files will automatically be created when terminating.
   2.cClick the OK button.

Restoring from a Backup File
To restore Callsign Certificates, Station Locations, and Preferences from a selected Backup File,
1.Select the File menu's Restore Station Locations, Certificates, and Preferences... command.
2.In the Select saved configuration file dialog that appears,
   2.aNavigate to the Folder that contains the Backup File you wish to restore.
   2.bSelect the Backup File to be restored.
   2.cClick the Open button
tqsl-2.0/apps/help/tqslapp/addstnl0.bmp0000664000076400007640000003737612231073120020145 0ustar rmurphyrmurphyBM>6(=  @@bbbrt¶:;RS*+ffBDºZ[ NO23~npz|^_JK&'ikVZbfvxFG67..VVbb"">?''''''''''''''''''''' 'P '''M 'M  ''M  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  '' '''''''' ''''''''  ''''''''''  '''''''''''''''' ''''''''''  ''''''''''''''''''  ''''''''''''' ''''''''''''  ''''''''''''  ''' ''''''' ''''''' ''  '' ''''''''''  ''''''''' ' '''''''''''  '' '''''''''''  ''''''''''''''' '''''' ''''''''  '''' '''''''''''''  '' '''''''' ''''''''  '' '''''''  '' '''' ''' '  '''''  '' ''' ''' '  ''''  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''M' M'  'M'  ''N'N' 'N' ''OO 'O ''''''''''''''''''''''''''' ' ' ' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''<'L''<'K''<'K' '<'L' ' '<'L' ' '.' 'L' ' '/' 'L'' ' '0' ' /'' ' ''''''''''' ' 0' ' ' '''''' ''''''''''' ' 0''' ' ' ''''''''''''' ' 0''' ' ' ' ''''''''' '''''' ' 0''' ' ' '''''''''''''' '0'' ' ' ' ''''''''''''''' ' 1''' ' ' ' ''' ''''''' 'C'' '' ' '''''@'''' ' ''''L''' ' ' '<'L' ' '<'L'' '<'[' '<'K''<'M''<'{'<'x'<'x'<'x' '<'x' '<'x' '<'x'' '<'K'' ''''''''' 'L' ' ''''''''''''' 'L''' '''''''''''' 'L''' ' ''''''''' 'L''' ''''''''' ' L'' ' ''''''''''' 'M''' ''''''''' 'p'' '' ''''' '' g'''' ''' ''x''' ' '<'x' '<'x''<'x'<'y'<'{''''''''''''''''''''''''''''''''''''''''''''''''''''':::55&55&5&&;;%;% % 6 666444 4 <<<3<3 # 8."" "9/9////) )  )  00!0!! !!!11 >+>+ ??,??,,?,, --- ((====== $$$$*$$**$*:::5 &;;;%%;% % % 6 6644 4 <<<3< 3 #  8.8.8."" //9/99/9//)) ) ) )  000!0!!1111+++>++,,?,?,----(((====$$*$**   : :55 5&&;; % 6664 44 < <<3<<3#3###  8.."" "9/9///))  ) ) 0000!0!!0!!111 +>+>>+,,??,, ----- (7====$$*$*$***  ::555 &;;% % 6644 4 << < <<<333#3##  8 ..8.8.8."" 9/9/9/9///) ) 00!0!!111 >+>>+>+? , ,?,?,---((((( == $***  :::5& ;;;%%%%% 44 4   <<<<<33#33##   8 88.8.8.""9""9///)))) )) ) ) 00!0!0!!1111 >>++>++++ ?,???,,,?-- --(((======$$**$*** 7  ::55 55&&&& ;;;%;%%  666444   <<<<33##3##  8 8 88.8888""" /"/9/9////)) )) )  000!0!!0!!111>++>>>,?,?,?  ------(((==$$**  : :::5*55&&&&;;;%%%%%% 6166444 44   <<<<<33#3#  . 88..8.."/"99/99/ ))    00!0!00 ! !!!11111 +++ ,,??,,,??-- -((7===== $$$$*$***** ::55&&&&&;;;%;%%  666 664  <<<<33#3#   .8 8.8 "/9"9/99/)) )) ) )  000!0!!11 >>>+>>+>+?,,?,,?--(-(==$$*$$*  :::5&&&;;;;%% % 66644444 <<<<<<< 3 # 8.8 "9/))) )  00!0!111 >+>> ??,,?? --((====$$$*$$*$$**  :::5&&5&&;;%%%% % ,666 664444    <<3 3#  88.8..88.88 "//9//9/)) ) )  00!0!11111+ ?, ?,??,?,?-((=7=====$$*** :::::5&55&;;; %%%%%6  6444  < <<<3<3<3#3#  8.8.8.. "//)) ))  ) ))  0000 !1111>+?,,?,,?----(=== $$$*'' '  ::5 5&&&5&&;;;%;%;% %% %6%6 666666644  4 44 4 < < <<<33#3#  8 .8.8.8. "/99/9/)) )  00 !111>++++?,,?,,?, ,,----(((===$ * *'''' :::55 5&&&;&;;%;%;% %  66444 4 < < < <<3<3<33#33###  8 8.88.""9""9//9//)  )   00!00!!!11111 >++>>+>+> ,,?,,,?,------(((===$$$**22'2  ::::55&55&5&5&;;%;;%;%%; % % % 66 66 44444 4 4 < < <<3<333##3##  8 8 .8.8.88""9"/9/9/)) ) )  0!0!0!!111 >++>>+>+ ?,,,?,??,,,---((7=====$$*$**22  :::55&&5&55&&;;%%;%;% % 6 66644 4 < <<3<33#3##  8 .8.888"" 9"/9/9/9//))) ) )  00!0!!11111 +>>+>>+>> ,?,?,????----(-(( =======$$$*$*   ::::555 &&5&&&&&;;;%%;%% % % 6 6 664444 4 << < <<<3333#3##  88 88"""99"99/9/9)) )  0!!0!!1111 >>>>+>+++? ?,?,?,?--- -((==(==$$$**$**  : 5&&5&&5& ;%%;% 6  4 << 3#  8  "9//)  )  0 ! 1 >>+>+> ?,?,?? --(( =  $**    :  5&&5&  ;%%;% 664 <<3 #  8  "9  )  0 ! 1 >  ?? --  =  $**tqsl-2.0/apps/help/tqslapp/additional-info.htm0000664000076400007640000000075712231073120021500 0ustar rmurphyrmurphyTQSL Additional Information

Additional Information

tqsl-2.0/apps/help/tqslapp/addcertreq.htm0000664000076400007640000002122512231073120020546 0ustar rmurphyrmurphyRequesting an Additional Callsign Certificate

Requesting an Additional Callsign Certificate

When submitting a QSO to LoTW, you must present a Callsign Certificate that matches the station callsign you used over the air when making the QSO. Thus if you've made QSOs using callsigns other than your present primary callsign, you'll need to request a Callsign Certificate for each. This process is more straightforward and rapid than requesting your Initial Callsign Certificate because your initial certificate is used to authenticate your request.

LoTW requires that you request an additional Callsign Certificate using the same computer with which you will accept that additional callsign certificate.

These instructions assume that your Callsign Certificates reside in the folder C:\MyLoTWCertificates (if you've stored them in a different folder, adjust the instructions accordingly).

To request an additional Callsign Certificate,
1.Start TQSL and select the Callsign Certificates tab, which displays a list of your Callsign Certificates.
2.Open TQSL's Callsign Certificate menu and select the Request New Callsign Certificate... command; the Request a New Callsign Certificate dialog will appear.
 
3.In the Request a New Callsign Certificate dialog,
   3.aSpecify your station callsign, DXCC entity, begin date, and end date
       3.a.1.specify the station callsign for which you seek a Callsign Certificate
       3.a.2.select the DXCC entity
       3.a.3set the QSO begin date to the date of the first QSO made using this callsign
       3.a.4.if additional QSOs will be made using this callsign, leave the QSO end date blank; otherwise, set the QSO end date to the day after the date of the last QSO made using this callsign
       3.a.5.click the Next button
   3.bEnter your name and address
       3.b.1.for US callsigns, the mailing address you enter must match your address in the FCC database
       3.b.2.click the Next button
   3.cEnter your email address; click the Next button
   3.dYou will be prompted to enter a password
       3.d.1.If you're using a shared computer, you should protect your Callsign Certificate by entering the same password in both textboxes; you'll be asked to provide this password each time you direct TQSL to digitally sign a log file. If you control access to the computer you're using, you can leave both textboxes empty, thereby avoiding the need to provide a password each time you direct TQSL to digitally sign a log file.
       3.d.2.Click the Next button
   3.eIf this callsign certificate is for your personal callsign,
       3.e.1.set the Sign Request panel to Signed
       3.e.2.in the list of Callsign Certificates, select your Initial Callsign Certificate
       3.e.3.click the Finish button, and proceed to step 3.g
   3.fIf this callsign certificate is for a club station, or for another station for which you will serve as QSL Manager,
       3.f.1.set the Sign Request panel to Unsigned
       3.f.2.click the Finish button
   3.gIf your computer has internet access, you will be asked if you want to upload this certificate request to LoTW; click the Yes button; if your computer does not have internet access,
       3.g.1.you will be prompted to save a file whose name is the callsign and whose extension is .tq5; save this file in the folder C:\MyLoTWCertificates
       3.g.2.this file will be referred to as theCallsign.tq5
   3.hThe Callsign Certificates tab will now show an entry for your certificate with a pending icon:   (because the Callsign Certificate doesn't actually yet exist, and thus is not functional).
   3.iYou can close TQSL by opening its File menu and selecting the Exit command (on OS X, by selecting the Application menu's Quit tqsl command).
4.If you did not upload the certificate request to LoTW in step 3.g,
   4.aupload your certificate request file to the ARRL via https://p1k.arrl.org/lotw/upload ; use the Browse button to navigate to the folder C:\MyLotWCertificates and select the YourCallsign.tq5 file you find there.
   4.bRetain the YourCallsign.tq5 file; its presence in C:\MyLotWCertificates will be required when you accept the Callsign Certificate that the ARRL will send you, so don't delete it!
tqsl-2.0/apps/help/tqslapp/addcertaccept.htm0000664000076400007640000001211312231073120021212 0ustar rmurphyrmurphyAccepting an Additional Callsign Certificate

Accepting an Additional Callsign Certificate

LoTW requires that you accept an additional Callsign Certificate using the same computer from which you generated the request for that additional Callsign Certificate.

These instructions assume that your Callsign Certificates reside in the folder C:\MyLoTWCertificates (if you've stored them in a different folder, adjust the instructions accordingly).

When you receive an email message from the ARRL with an attached file named theCallsign.tq6 (for example, K4CY.tq6),
1.Direct your email application to open the email message, and save the attached file into the folder C:\MyLoTWCertificates.
2.To proceed, the file theCallsign.tq5 must be present in C:\MyLoTWCertificates; if you deleted this file, you'll have to start over by requesting a new certificate from the ARRL.
3.Start TQSL and select the Callsign Certificates tab:
   3.aClick the Load a Callsign Certificate button; the Select Certificate File dialog will appear
   3.bIn the Select Certificate File dialog,
       3.b.1.Set the Files of type selector (on OS X, set the Enable selector) to Certificate Request response files (*.tq6)
       3.b.2.Select the file theCallsign.tq6 in your C:\MyLotWCertificates folder
       3.b.3.Click the Open button; a small Install Certificate dialog will appear.
   3.cIn the Install Certificate dialog, you'll be asked if its okay to install a trusted root certificate; click the Yes button
   3.dIn the Load Certificate File dialog, click the Finish button
   3.eThe Callsign Certificates tab will show an entry for your Callsign Certificate, with a yellow medal valid icon: .
   3.fProtect your new Callsign Certficate by directing TQSL to create a Backup File.
   3.gYou can terminate TQSL by selecting its File menu's Exit command (on OS X, by selecting the Application menu's Quit tqsl command).
4.At the completion of these actions, the folder C:\MyLoTWCertificates will contain
   *the file theCallsign.tq6 -- contains the actual Callsign Certificate, in a form that cannot be moved to another folder or saved on an archival storage device
5.If you have TQSL installed on multiple computers, then perform the following steps on each such computer:
   5.aDelete the files theCallsign.tq6 and theCallsign.p12 if they are present, as these files now contain obsolete information
   5.bObtain a copy of the Backup File you created in step 3.f (via your home network, or by using a thumb drive)
   5.cStart TQSL, and direct it to Restore from the backup file you obtained in step 5.b; this will update all Callsign Certificates, Station Locations, and Preferences on this computer to match those on the computer you used to accept the Callsign Certificate in step 3
tqsl-2.0/apps/help/tqslapp/addcert1.bmp0000664000076400007640000220754612231073120020123 0ustar rmurphyrmurphyBMf 6(s0 db`VTR/,)0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*0-*/,)ECBSQPnlj{xvfdb/,)1/-𢟝1/-/,)NLKmki{xvfdbοοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻɻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻʼ̾̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽ᢟOMLpnlpnl-*'οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻɻ˽̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽֢-*'VTR`]\0.,οοοοͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻʻɻɻɻɻȺȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ̾̾ͿͿ̾̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽˽.,*HFE200οοοοͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾˽˽˽˽˽˽˽˽˼˼˼˼ʻʻʻʻʻʻʻʻʻɻɻɻɻɻȺȺȺȺȺǹǹǹǹǹǹǹǹǹǹǹǹȺȺȺȺɻʼ˽̾̾Ϳ̾̽̽˼˼ʻʻʻʻʻʻʻʻʻʻʻʻ˼˼˼˼˼˼˼˼˽˽˽˽˽˽˽˽˽˽˽˽˽˽̾ɡ200-*'˽˽̾̾-*'-*'ञohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohbohb˽˽̾̾-*'-*'ohbohb˽̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohb𸵰𸵰uuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb̾̾̾̾-*'-*'ohb𹶱𹶱䏏ohb̾̾̾̾-*'-*'ohb𶳮򶳮𶳮򶳮uuuuuuohb̾̾̾̾-*'-*'ohb𵲭𵲭ppppppohb̾̾̾̾-*'-*'ohb𵲭􃃃𵲭􃃃ppppppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppppppohb̾̾̾̾-*'-*'ohb𵲭􃃗Ѓ􃃗􃃪⾗𵲭􃃗⃃ЪЃ⾗ppp1yVVVV1y11yy11ָyy11ָy1֙Vy1y1yy11ָpppohb̾̾̾̾-*'-*'ohb𵲭􃗾⾗⾗⃗Ъ⃪⾗𵲭􃃪⃃ЪЗ􃃪ppp1zWؚWWzz11ع1zz1zz11عzz11ع1zؚWؚWؚWzz11عpppohb̾̾̾̾-*'-*'ohb𵲭ЗЗ⾗Ъ𵲭⾾⾗􃃃⾗􃃗Ъpppڜ1Wڻ{{11ڻ{{{11{{11ڻ{{11{{11ڻ{{11ڻ{{11ڻpppohb̾̾̾̾-*'-*'ohb𵲭􃃪Ъ􃃗⾗􃃗𵲭⾗⃃⃃⾗ppp{{11ۼ{1{1{{11ۼ{{11{{11ۼ{1X{{11ۼpppohb̾̾̾̾-*'-*'ohb𵲭З􃃗Ъ􃗾Ъ⪃𵲭⃪Ъ⪃З􃃗Ъppp}Y2ݝYݝY}2ݝYY}2ݾ2}ݝYݝYYݝ}}22}}22ݾpppohb̾̾̾̾-*'-*'ohb𵲭􃗾Ъ⃃􃃪𵲭Ъ􃃗􃃪⾗⾃⾗􃃪ppp55Ʉ55Ʉ55^^^^55Ʉ55pppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppp5^^^55pppohb̾̾̾̾-*'-*'ohb𵲭􃃗Ъ𵲭􃃗⾗ppp__55pppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppp55pppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppppppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppppppohb̾̾̾̾-*'-*'ohb𵲭𵲭ppppppohb̾̾̾̾-*'-*'ohb𶳮򶳮𶳮򶳮uuuuuuohb̾̾̾̾-*'-*'ohb𸵱𸵱葑ohb̾̾̾̾-*'-*'ohb𾻷𾻷𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾̾-*'-*'ohbohb̾̾̾Ϳ-*'-*'ohbohb̾̾ͿͿ-*'-*'ohbohb̾̾ͿͿ-*'-*'ohbohb̾̾ͿͿ-*'-*'ohbohb̾ͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohb𠠠ohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿͿ-*'-*'ohbohbͿͿͿο-*'-*'ohbohbͿͿοο-*'-*'ohbohbͿͿοο-*'-*'ohbohbͿͿοο-*'-*'ohbohbͿοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοοο-*'-*'ohbohbοοο-*'-*'ohbohbοο-*'-*'ohbohbοο-*'-*'ohbohbοο-*'-*'ohbohbο-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbpppvv00Ҵpppohb-*'-*'ohbpppww00Զpppohb-*'-*'ohbpppyy11ָyy11ָy1y1yy11y1V֙pppohb-*'-*'ohbpppzz11عzz11عWؚWzz11zz11عWz1عpppohb-*'-*'ohbppp{{11ڻ{{11{{11ڻ{{11{{11ڻڜ1Wڻ{pppohb-*'-*'ohbppp{{11ۼ{{11{1X{{11{{11ۼۜ1Xۼ{pppohb-*'-*'ohbppp}2}2ݾYYݝ}}22}}22}22ݾ}YYݝpppohb-*'-*'ohbppp5555Ʉ55Ʉ55^555^^pppohb-*'-*'ohbppp555555pppohb-*'-*'ohbppp555555pppohb-*'-*'ohbppp55pppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohb𐐐wwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'οohbohb-*'-*'οοohbohb-*'-*'οοohbohb-*'-*'οοohbohb-*'-*'οοοohbohb-*'-*'οοοοohbohb-*'-*'οοοοohbohb-*'-*'οοοοohbohb-*'-*'οοοͿohbohb-*'-*'οοͿͿohbohb-*'-*'οοͿͿohbohb-*'-*'οοͿͿohbohb-*'-*'οͿͿͿohbohb-*'-*'ͿͿͿͿohbohb-*'-*'ͿͿͿ̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'ͿͿ̾̾ohbohb-*'-*'Ϳ̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾̾ohbohb-*'-*'̾̾̾˽ohbohb-*'-*'̾̾˽˽ohb``ohb-*'-*'̾̾˽˽ohb``ohb-*'-*'̾̾˽˽ohb666`6``66666·66·666``666`·6`·666·6666`·666·66```666`6```666·66·66```6666````666·66·66`·666`6·6666·`6ohb-*'-*'̾˽˽˽ohb66``6Ϋ``66·666·66·66`66·6·`66·`6``6666·`6``66666·66```·6666·6·66·666`·6·66`666·6·66·66·`66666`·66·6666·`6ohb-*'-*'˽˽˽˽ohb6666`6Ϋ666666·66·66·6666``66666666·66·666666·66`66`·66·66·66·66·66666666·66·66·66``Ϋ66`·666·6666ohb-*'-*'˽˽˽˽ohb6666`6Ϋ666666·66·66·6666``666`Ϋ6666·66·6`Ϋ6666``6`·66·66·66·66666666·66·66``66·6666·6666ohb-*'-*'˽˽˽˽ohb`666```6Ϋ`666666·`6·`6·6666`6``66``666``6·66Ϋ``666`````````66·66``666```66·66`6``Ϋ66``666``6ohb-*'-*'˽˽˽˽ohb66`66`6666`666`Ϋ`6`6666666·666·66``6·666·66``66·`6``66·66·66·66``66·66·6666·66·66·66``ohb-*'-*'˽˽˽˽ohb```·66666666666·66ohb-*'-*'˽˽˽˽ohb666·666666·666666·6666ohb-*'-*'˽˽˽˽ohb666666·66ohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˽ohbohb-*'-*'˽˽˽˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˽˼˼ohbohb-*'-*'˽˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼˼ohbohb-*'-*'˼˼˼ʻohbohb-*'-*'˼˼ʻʻohbohb-*'-*'˼˼ʻʻohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'˼˼ʻʻohb䏏䏏䏏ohb-*'-*'˼ʻʻʻohbuuuuuuuuuuuuuuuuuuohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohbppppppppppppppppppohb-*'-*'ʻʻʻʻohb66pppppp6666pppppp66·ppppppohb-*'-*'ʻʻʻʻohb66pppppp6666pppppp66``ppppppohb-*'-*'ʻʻʻʻohb66pppppp66·`666pppppp6666ppppppohb-*'-*'ʻʻʻʻohb66pppppp66``66pppppp66``ppppppohb-*'-*'ʻʻʻʻohb`666`pppppp66``Ϋ66·66pppppp66``ppppppohb-*'-*'ʻʻʻʻohb66`6pppppp666·6``66pppppp6666ppppppohb-*'-*'˼ʻʻɻohb```·6pppppp`6666`·66666pppppp666`ppppppohb-*'-*'˼ʻɻɻohb666·pppppp6``6pppppp6`ppppppohb-*'-*'˼ʼʼɻohbuuuuuuuuuuuuuuuuuuohb-*'-*'ʼʼʼɻohb葑葑葑ohb-*'-*'ʼʼʼʼohbwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ʼʼʼʼohbohb-*'-*'ʼʼʼʼohbohb-*'-*'ʼʼʼʼohbohb-*'-*'ʼʼʼɻohbohb-*'-*'ʼʼɻɻohbohb-*'-*'ʼʼɻɻohb`6·ohb-*'-*'ɻʼɻɻohb66ohb-*'-*'ɻȺɻɻohb6`66·6`66·6666```666```666```666`·666·66·ohb-*'-*'ȺȺȺɻohb6·6```6666·6`·6``66666`·6·66`·6·6·666·6·`6``66·ohb-*'-*'ȺȺȺɻohb6`·66``6`·66666666·6666666666·66·66·66ohb-*'-*'ȺȺȺȺohb66````66``6`Ϋ6666·66666666·66·66·6`ohb-*'-*'ɻȺȺȺohb66````66````666``6``66``66``66Ϋ``66·66·ohb-*'-*'ɻɻȺȺohb6`·66``6`·6666·66``666666·6·666·66·ohb-*'-*'ɼɻɻǹohb6·6`·66`·``6·6`·6666666ohb-*'-*'ɼɼȺǹohb6·66·66·6666666ohb-*'-*'ʼʽɼɻohb6666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuuppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏䏏䏏ohb-*'-*'ohbuuuuuuuuuuuuuuuuuuohb-*'-*'ohbppppppppppppppppppohb-*'-*'ohbppppppppppppppppppohb-*'-*'ohbppppppppppppppppppohb-*'-*'ohbppp1y֙VVy1yy11ָy1֙Vpppppp1y֙V1y֙Vpppppp1y֙Vpppohb-*'-*'ohbpppzz11عع1zz1zz11عWؚWzW1ؚppppppzz11عzz11عppppppzz11عpppohb-*'-*'ohbppp{{11ڻ{{11ڻ{{11ڻڻ11{ڻ{pppppp{{11ڻ{{11ڻpppppp{{11ڻpppohb-*'-*'ohbppp{{11ۼ{1Xۜ1{{1ۼۜ1Xۼ{pppppp{{11ۼ{{11ۼpppppp{{11ۼpppohb-*'-*'ohb66ppp}}22ݾ2Yݾ}ݾ22}ݾ}2}}2}}22ݾY}2ppp6666ppp}}22ݾ}}22ݾppp66·ppp}}22ݾpppohb-*'-*'ohb66ppp55ɨ^^^^5Ʉ555ɨ^^ppp6666ppp5555ppp66``ppp55pppohb-*'-*'ohb66ppp555^^5^^^555ʨ^^ppp66·`666ppp5555ppp6666ppp55pppohb-*'-*'ohb66ppp5____5̩_5̅ppp66``66ppp5_5_ppp66``ppp5_pppohb-*'-*'ohb`666`pppppp66``Ϋ66·66pppppp66``ppppppohb-*'-*'ohb66`6pppppp666·6``66pppppp6666ppppppohb-*'-*'ohb```·6pppppp`6666`·66666pppppp666`ppppppohb-*'-*'ohb666·pppppp6``6pppppp6`ppppppohb-*'-*'ohbuuuuuuuuuuuuuuuuuuohb-*'-*'ohb葑葑葑ohb-*'-*'ohbwwwppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohb`6·``ohb-*'-*'ohb66``ohb-*'-*'ohb6`66·6`6666`6·66·6666```666```666`·666·66·ohb-*'-*'ohb6·6```6666·6`·6666Ϋ```6`·66·66·66666`·6·6·666·6·`6``66·ohb-*'-*'ohb6`·66``6`·6666`6Ϋ66`666·66·6666666666·66·66·66ohb-*'-*'ohb66````66``66`6Ϋ6`Ϋ6666·66·66666666·66·66·6`ohb-*'-*'ohb66````66``66·6·6``66``66·666``6``66``66Ϋ``66·66·ohb-*'-*'ohb6`·66``6`·66`666`6·66·66·66·66``6666·6·666·66·ohb-*'-*'ohb6·6`·66`·``6·6`·6666666ohb-*'-*'ohb6·66·66·666666666ohb-*'-*'ohb6666ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbuuupppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppuuuohb-*'-*'ohb䏏ohb-*'-*'ohbuuuuuuohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohbppppppohb-*'-*'ohb``ppppppohb-*'-*'ohb`6ppppppohb-*'-*'ohb66·`6`66`6`66·6666```666`·666·66·ppppppohb-*'-*'ohb66``6`6`6```6`````6666·`666·`66·666·ppppppohb-*'-*'ohb6666Ϋ```6Ϋ6`·6`·666666·66·66·66````ppppppohb-*'-*'ohb66```6·66666`Ϋ6666·66·66·66````ppppppohb-*'-*'ohb66``66·`6`6``666``6·66·66·66````66·ppppppohb-*'-*'ohb6666Ϋ6`6666·66·66·66``6``666666`6`·66·ppppppohb-*'-*'ohb666``·66`6```6```6666ppppppohb-*'-*'ohb6`````````66·66·66ppppppohb-*'-*'ohbuuuuuuohb-*'-*'ohb葑ohb-*'-*'ohbwwwpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppwwwohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷٷohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbϵɤohb-*'-*'ohb``ϵɤohb-*'-*'ohb``ϵɤohb-*'-*'ohb6````666·66·66`·666`6·6666·66·ϵɤohb-*'-*'ohb6```Ϋ666·6·66·66·`66666`·66·6666·66·ϵɤohb-*'-*'ohb6`·66·66·66·66``Ϋ66`·666·6666ϵɤohb-*'-*'ohb6666·66·66``66·6666·6666ϵɤohb-*'-*'ohb`6``66·66`6``Ϋ66``666``6·66·ϵɤohb-*'-*'ohb66·66·66·6666·66·66·66``66·ϵɤohb-*'-*'ohb6```66·66ϵɤohb-*'-*'ohb``66·6666ϵɤohb-*'-*'ohb66·66ϵɤohb-*'-*'ohbϵɤohb-*'-*'ohbͶ\{={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={={=\Ͷohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'-*'XԫLzPϝ-*'-*'XԫLLDž-*'-*'XիLH~X`+4f (P (P")Q#*S$+T%-U%-V'.W(/X)1Y)2Z)2[)2[)1])1])2])1])1])2])1])1])1[)1\)1])2])2])2[)2[)2Z)1Y(0X'/W%.V%.U$,T#+S"*Q )P )P+4gXa-*'-*'W٦HU} NTMVNTMWOMԢOMԢ}~āئJ~NOKԢOKӢO~~M{KإLKץLߨH~ÂI֥LIץLLǫOʧQGР|Ą޿xÄIإOݥFTϞޯ(-Mx|͵᮶᮶᮶家殸欹鬺ꬻꬻ쬻쬻ꬻꬺ鯹殷殷宷⮷ⴻ⮳y}).N-*'-*'WۦI ŀ ŀWKҏ MӎNץTLVԩL€~RMԢ~~LQÁQ~PڿN٧L冿PLԢOKԢOΪM~~KKئLKئLჼץLჺצL~JצL߂݆LǫOʨRGѡ|ąIS|ĄަGئO|ĄݿvƒX[uqqqqqpppoommmmmmmmmmmmmmmmmooppqqqqqquɟՄX[-*'-*'WڦILU֤ }Y֫MX֫LXիLإJ€P€MOԢ}~OOӢO~NצJNOKԢOKԢئK~~O̪O|KئLKإLKÁ~ÂIצL߁݆LȫOʧQGѡ|ĄUGѡKƉIئO|Ąށډ!&Oq{ererdsdsdscucwcwcxazayaza{a{a{a{a{a{a{a{a{a|a|a|a|a|a|a|a|a{azazcxcxcxcvdtdtdtesesq|!&O-*'-*'VۧI ۧI } }Y׬MX׬MX֫MāWāÀMԣ~~PJLN񿀬PLԣPLԣPÂPάO}K٧MK٦LQIӡ~JئMއLɫO˨RGҡ}ąUGҡ}ئP}ą߁|>YgUcUcUeUfUfTgTgThTjSjSjQkQkQkQkQkQkQkQkQkQlQlQlQlQlQlQlQlQlQlSkSjTiThThThUgUgUfUdUdYh>-*'-*'VL֤ }LVפ īK MX׬MX֫MƂU٧JWөLÀMԣ꺉MԣRҫLЅN뼈L٧KLPLԤPLԣPϬNIMKQԢIQIӡ₼߇LʫOJRҡႻއLɫO˨RGҡ}ąIąyئP|ĄwܥTE˛;IWIWIWIWHWHWGYEZE\E[E[E]E]E]E]E]E]WYhXUhXUhXUWYE^WYhXUhXUhXUWYE^E^E^E]E[E\E\E[GZHXHXIXIXIXIX;-*'-*'WڦILU֤UڧIWQPIMX֫MXժLULإJMԢ€~€RNԣQѪLئJLNNӢLNϫOKԣOKԢئKㄾOMIKKIO|~LRҡJLGצMLɫOG‚|ĄIĄx|UПF֣M 9=M=M=M=N=O=O=O=O=O=O=Q=Q]7[6R+EECCB?I%ƩG20 @??????A H,leڎ:۶ffې::f:f:ff:ې:f:ff:ېffohb-*'-*'ohb{{|ukdB_8^6_7R,ECCC?I%ƩG20 @??????AF)xVJ{{|ohb-*'-*'ohbnnosfgDb:`9a9a:V.EBCAH$ȯG21 @??????@F&{O@nnoohb-*'-*'ohbnnouijGe>dV/BF ŹG21 B@@@@@@AG)yYL{{|:fې:fohb-*'-*'ohbښrQlEkCkBkAjBjBjBjBa:V0I31 BAAAAAACI+qjڎfې:f:ې:fېf:ffohb-*'-*'ohbz\rKoGoFoFmFmFmFlEkCkCݳÃC,2 A@@AA@AE"M1ffff:fېf:ffohb-*'-*'ohbǢּsvRsJrIrIrIrIqHpHoHkEoKrMqLrNgBW0T.P)N'K&M&M'O*T2YCң:fېfې:fffې:::ې:f:fې:::f:ffffff:fې:fې:fېf::fېff:f:f:fې:::f:::fې:fې:f:fff:fې:fې:f:::fې::::f::fېfې::f:::::::ې::fېffohb-*'-*'ohb륓ՄbwQuNvMuMuMuMtKsJsKh?`8^9Z2h@jCg@d>b<_9^7[6[6]>pf:fېfffې:ې:ې::fې:ې:f::fې:۶f:۶ffې:f::ff:ې:fې:fېff::ېfff::f:ff::fې:۶f:۶ff:ې::ې:fېfې:f::fې:fېf:ې::ېf::fېff::ې:ې:fې::fې:۶f:۶f:۶f:۶f:ې::fېffohb-*'-*'ohbҕ}[zRyRyQyPyPxPxOqGڅdˢacF}u폏:fېf:::ې:f:fې::::ېff:fې:fې:fېff:fې:fې:fې:fې:::fېffff:fff:fې:fې:ff:ې:fې:fېff:fې:fېf:ې:f:fې:fې:f:::fې:f::ې:f:fې:fې:fې:fې:fېfې::fېffohb-*'-*'ohb˫ߍm^YYWW|R\躧e9pGlCiBh@gBhIl^ٸ:fې:::f:f:fې:ې:ff:fff:fېf:ې::ې:fې:fې:fې:fېff::ېffffff:fff:fې:fې:fېf:ې::ېf:ff:fې:f:fېff::ې:ې:ff:fېfې::fېff:fېff:fېf::fېffohb-*'-*'ohb땕ٲnb][ZY|R˸߇eoFrIpGmElGmNp^ӕ:fېf:::ېfې::fې:fff:::fې:fې:f:ې::fې:fې:fې:fې:::fېff:ff::::fې:fېff:fې:f:ې::f:ې:ff::ې:fې:::fېff:f:f:fې:fې:fې:fې:fې:fېfې:ffohb-*'-*'ohbؐػ|hca\[WhtJxOvMsMrOrTufᐐ:fې:ff:f::fېf:ff:fې:ff::fې:fې:fېff:fې:ff::fې:fېf::fېff:fې:fې:ff::ff:fې::fېffohb-*'-*'ohbѐ̿tifb]|RyM{R}W{VzWxXw^Ӑ:fېf:ې:ې:f::fېffffېff:۶f:۶f:fې:fې:fېffېff:۶f:۶f:fې:fېf::ff:fېfې::ې::ff:fې:۶f:۶f:۶f:۶ff:۶ffffohb-*'-*'ohbؕҿ汜|qlމg܇dׅbЁc~a~hfې:fې:ff:fېfې:ff:f:f:fې::ې:fې:fېf:ې:f:f:fې:fې::f:ېf:ېf:ې:f:ff:ېf:ffohb-*'-*'ohb배Ŀ뿿ohb-*'-*'ohb٩ohb-*'-*'ohbǨ{{|nnonno{{|ohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'ohbohb-*'-*'解rkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerkerke-*'-*'-*'-*'οͿͿ̿̿̿ͿͿͿ̾̾ͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾ͿͿ̾̾̾̾ͿͿͿͿͿ-*'-*'Ϳ̿̿̿ͿͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾̾̾̾ͿͿͿ-*'-*'Ϳ̿̿̿ͿͿͿͿͿͿͿͿ̾̾̾̾̾̾̾̾̾̾ͿͿ-*'-*'ͿͿͿͿͿͿͿͿͿͿ̾̾̾̾̾̾-*'-*'ͿͿͿͿͿͿͿͿͿͿ̾̾ͿͿ-*'-*'ͿͿͿͿͿͿͿͿ-*'-*'ͿͿͿͿͿ-*'-*'ͿͿͿͿͿͿ-*'-*'ͿͿͿͿW`*4f (P (P")Q#*S$+T%-U%-V'.W(/X)0Y)1Z)1[)1[)1])1])2])1])1])2])1])1])1[)1\)1])1])1])1[)1[)1Z)0Y(/X'.W%-V%-U$+T#*S")Q (P (P+4gX`-*'-*' ~ ŀLVPNۨJ ŀYILPբ )-Ny}̳୵୵୵㭵䭷䫸竹諹諹꫹뫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫹쫺쬺묺鬺鬹许家家䮶᮶ᴺ᮲y}).N-*'-*' U}VŀV}VۨJ ۧI ۧIWLգW٦HWZ~tp~p~pppooonnllllllllllllmmmmmoopppqqqqquȟԄX[-*'-*' LU֤ ŀYԪKY֪KLU֤LUգWڦI &Opzdqdqcrcrcrbtbvbvbv`x`x`y`z`z`z`z`z`z`z`z`z`{`{a{a{a{a{a{a{azayaycwcwcwcudsdsdsererq{!&O-*'-*'  ŀLVפ ŀYԫKY׫KLVפLUգVڦI>XfTbTbTdTeTeSfSfSfShRiRiPjPjPjPjPjPjPjPjPjPkPkQkQkQkQkQkQkQkQkSjSjTiTgTgTgUfUfUeUcUcYg>-*'-*' L ֤VKӲVۨJV} ۨJLVפLUգVڦI;HVHVHVHVGVGVFXDYDZDZDZD\D\D\D\D\D\WYhXUhXUhXUWYD]WYhXUhXUhXUWYE]E]E]E]E[E[E[EZGYHWHWIWIWIWIW;-*'-*'V|K LUTK ŀLU֤LUգW 9hvd{ }dQK8rnH~~'[a8FYXP[ xn[UJO!*RgʆؐϿsi<1n:jk2@u)K.Näצ>@n:EHlmj jxrTXRSaVŹ,^Rο?Q@;_Gª-V7$M-]vԳ§̮JnzÝݹǥ|(^37Y00^3 J^0g;Z/,d;1a7*[/2f7.e4H6t@ުFo^ari[]tqsl-2.0/apps/getpassword.h0000664000076400007640000000360712231073120016021 0ustar rmurphyrmurphy/*************************************************************************** getpassword.h - description ------------------- begin : Tue Aug 5 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __getpassword_h #define __getpassword_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/wxhtml.h" class GetPasswordDialog : public wxDialog { public: GetPasswordDialog(wxWindow *parent, const wxString& title = wxT("Enter password"), const wxString& message = wxT("Enter password"), wxHtmlHelpController *help = 0, wxString helpfile = wxT("")); wxString Password() { return _password; } virtual bool TransferDataFromWindow(); private: void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); void OnHelp(wxCommandEvent&); wxHtmlHelpController *_help; wxString _helpfile; wxString _password; wxTextCtrl *_pw; DECLARE_EVENT_TABLE() }; class GetNewPasswordDialog : public wxDialog { public: GetNewPasswordDialog(wxWindow *parent, const wxString& title = wxT("New password"), const wxString& message = wxT("Enter new password"), bool blankok = false, wxHtmlHelpController *help = 0, wxString helpfile = wxT("")); wxString Password() { return _password; } private: void PWChange(wxCommandEvent&); void OnOk(wxCommandEvent&); void OnCancel(wxCommandEvent&); void OnHelp(wxCommandEvent&); bool _blankok; wxHtmlHelpController *_help; wxString _helpfile; wxString _password; wxTextCtrl *_pw1, *_pw2; wxButton *_okbut; wxStaticText *_pwstatus; DECLARE_EVENT_TABLE() }; #endif // __getpassword_h tqsl-2.0/apps/getpassword.cpp0000664000076400007640000001276412231073120016360 0ustar rmurphyrmurphy/*************************************************************************** getpassword.cpp - description ------------------- begin : Tue Aug 5 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "getpassword.h" #include "tqsltrace.h" #define GPW_ID_LOW 6400 #define GPW_ID_PW1 GPW_ID_LOW #define GPW_ID_PW2 GPW_ID_LOW+1 #define GPW_ID_OK GPW_ID_LOW+2 #define GPW_ID_CAN GPW_ID_LOW+3 #define GPW_ID_HELP GPW_ID_LOW+4 BEGIN_EVENT_TABLE(GetPasswordDialog, wxDialog) EVT_BUTTON(GPW_ID_OK, GetPasswordDialog::OnOk) EVT_BUTTON(GPW_ID_CAN, GetPasswordDialog::OnCancel) EVT_BUTTON(GPW_ID_HELP, GetPasswordDialog::OnHelp) END_EVENT_TABLE() GetPasswordDialog::GetPasswordDialog(wxWindow *parent, const wxString& title, const wxString& message, wxHtmlHelpController *help, wxString helpfile) : wxDialog(parent, -1, title), _help(help), _helpfile(helpfile) { tqslTrace("GetPassword::GetPasswordDialog","parent=%lx, title=%s, message=%s", (void *)parent, _S(title), _S(helpfile)); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, message), 1, wxALL|wxEXPAND, 10); _pw = new wxTextCtrl(this, GPW_ID_PW1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); sizer->Add(_pw, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); wxBoxSizer *butsizer = new wxBoxSizer(wxHORIZONTAL); wxButton *okButton = new wxButton(this, GPW_ID_OK, wxT("Ok")); butsizer->Add(okButton, 0, 0, 0); okButton->SetDefault(); butsizer->Add(new wxButton(this, GPW_ID_CAN, wxT("Cancel")), 0, wxLEFT, 20); if (_help && _helpfile != wxT("")) butsizer->Add(new wxButton(this, GPW_ID_HELP, wxT("Help")), 0, wxLEFT, 20); sizer->Add(butsizer, 0, wxALL|wxALIGN_CENTER, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CentreOnParent(); } bool GetPasswordDialog::TransferDataFromWindow() { tqslTrace("GetPasswordDialog::TransferDataFromWindow"); _password = _pw->GetValue(); return true; } void GetPasswordDialog::OnOk(wxCommandEvent&) { tqslTrace("GetPasswordDialog::OnOk"); if (TransferDataFromWindow()) EndModal(wxID_OK); } void GetPasswordDialog::OnCancel(wxCommandEvent&) { tqslTrace("GetPasswordDialog::OnCancel"); EndModal(wxID_CANCEL); } void GetPasswordDialog::OnHelp(wxCommandEvent&) { tqslTrace("GetPasswordDialog::OnHelp"); if (_help && _helpfile != wxT("")) _help->Display(_helpfile); } BEGIN_EVENT_TABLE(GetNewPasswordDialog, wxDialog) EVT_TEXT(GPW_ID_PW1, GetNewPasswordDialog::PWChange) EVT_TEXT(GPW_ID_PW2, GetNewPasswordDialog::PWChange) EVT_BUTTON(GPW_ID_OK, GetNewPasswordDialog::OnOk) EVT_BUTTON(GPW_ID_CAN, GetNewPasswordDialog::OnCancel) EVT_BUTTON(GPW_ID_HELP, GetNewPasswordDialog::OnHelp) END_EVENT_TABLE() GetNewPasswordDialog::GetNewPasswordDialog(wxWindow *parent, const wxString& title, const wxString& message, bool blankok, wxHtmlHelpController *help, wxString helpfile) : wxDialog(parent, -1, title), _blankok(blankok), _help(help), _helpfile(helpfile) { tqslTrace("GetNewPasswordDialog::GetNewPasswordDialog", "parent=%lx, title=%s, message=%s, blankok=%d", (void *)parent, _S(title),_S(message)); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, message), 1, wxALL|wxEXPAND, 10); sizer->Add(new wxStaticText(this, -1, wxT("New password:")), 0, wxLEFT|wxRIGHT, 10); _pw1 = new wxTextCtrl(this, GPW_ID_PW1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); sizer->Add(_pw1, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); sizer->Add(new wxStaticText(this, -1, wxT("Enter again to confirm:")), 0, wxLEFT|wxRIGHT, 10); _pw2 = new wxTextCtrl(this, GPW_ID_PW2, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_PASSWORD); sizer->Add(_pw2, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); _pwstatus = new wxStaticText(this, -1, wxT("")); sizer->Add(_pwstatus, 0, wxALL|wxEXPAND, 10); wxBoxSizer *butsizer = new wxBoxSizer(wxHORIZONTAL); _okbut = new wxButton(this, GPW_ID_OK, wxT("Ok")); _okbut->Enable(_blankok); butsizer->Add(_okbut, 0, 0, 0); butsizer->Add(new wxButton(this, GPW_ID_CAN, wxT("Cancel")), 0, wxLEFT, 20); if (_help && _helpfile != wxT("")) butsizer->Add(new wxButton(this, GPW_ID_HELP, wxT("Help")), 0, wxLEFT, 20); sizer->Add(butsizer, 0, wxALL|wxALIGN_CENTER, 10); SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); CentreOnParent(); } void GetNewPasswordDialog::PWChange(wxCommandEvent&) { tqslTrace("GetNewPasswordDialog::PWChange"); _password = wxT(""); wxString pw1 = _pw1->GetValue(); wxString pw2 = _pw2->GetValue(); if (pw1 != pw2) { _pwstatus->SetLabel(wxT("Password entries do not match")); _okbut->Enable(false); return; } if (!_blankok && pw1 == wxT("")) { _pwstatus->SetLabel(wxT("")); _okbut->Enable(false); return; } _password = pw1; if (pw1 != wxT("")) _pwstatus->SetLabel(wxT("Password confirmed")); _okbut->Enable(true); _okbut->SetDefault(); } void GetNewPasswordDialog::OnOk(wxCommandEvent&) { tqslTrace("GetNewPasswordDialog::OnOk"); EndModal(wxID_OK); } void GetNewPasswordDialog::OnCancel(wxCommandEvent&) { tqslTrace("GetNewPasswordDialog::OnCancel"); EndModal(wxID_CANCEL); } void GetNewPasswordDialog::OnHelp(wxCommandEvent&) { tqslTrace("GetNewPasswordDialog::OnHelp"); if (_help && _helpfile != wxT("")) _help->Display(_helpfile); } tqsl-2.0/apps/folder.xpm0000664000076400007640000000117212231073120015302 0ustar rmurphyrmurphy/* XPM */ static const char * folder_xpm[] = { "16 16 17 1", " c None", ". c #56560E", "+ c #FEFEFE", "@ c #8A8A7A", "# c #8E8E02", "$ c #92920E", "% c #EEEEEE", "& c #CACA02", "* c #5E5E32", "= c #FEFE02", "- c #66664A", "; c #6A6A52", "> c #828202", ", c #828222", "' c #818154", ") c #828232", "! c #F6F6F6", "++++++++++++++++", "++++++++++++++++", "!.>>>>@+++++++++", "-&====$,,,,,,,,'", ")=============='", ")=============='", ")=============='", ")=============='", ")=============='", ")=============='", ")=============='", ")=============='", "*$$$$$$$$$$$$##;", "%%%%%%%%%%%%%%%!", "++++++++++++++++", "++++++++++++++++"}; tqsl-2.0/apps/file_edit_dis.xpm0000664000076400007640000001676312231073120016626 0ustar rmurphyrmurphy/* XPM */ static const char * file_edit_dis_xpm[] = { "48 48 175 2", " c None", ". c #9E9E9E", "+ c #A8A8A8", "@ c #A9A9A9", "# c #ABABAB", "$ c #ACACAC", "% c #AAAAAA", "& c #A6A6A6", "* c #A4A4A4", "= c #A2A2A2", "- c #A0A0A0", "; c #9C9C9C", "> c #9A9A9A", ", c #989898", "' c #969696", ") c #949494", "! c #929292", "~ c #909090", "{ c #8E8E8E", "] c #8C8C8C", "^ c #8A8A8A", "/ c #888888", "( c #868686", "_ c #858585", ": c #878787", "< c #898989", "[ c #8B8B8B", "} c #848484", "| c #999999", "1 c #E7E7E7", "2 c #F6F6F6", "3 c #F5F5F5", "4 c #F4F4F4", "5 c #F3F3F3", "6 c #F2F2F2", "7 c #F1F1F1", "8 c #F0F0F0", "9 c #EFEFEF", "0 c #E1E1E1", "a c #808080", "b c #9D9D9D", "c c #E2E2E2", "d c #DEDEDE", "e c #DFDFDF", "f c #E5E5E5", "g c #E0E0E0", "h c #E3E3E3", "i c #E4E4E4", "j c #E6E6E6", "k c #EDEDED", "l c #DDDDDD", "m c #9B9B9B", "n c #EEEEEE", "o c #BFBFBF", "p c #BBBBBB", "q c #BCBCBC", "r c #BDBDBD", "s c #BEBEBE", "t c #979797", "u c #E8E8E8", "v c #E9E9E9", "w c #EAEAEA", "x c #919191", "y c #C1C1C1", "z c #C0C0C0", "A c #EBEBEB", "B c #838383", "C c #8F8F8F", "D c #8D8D8D", "E c #D4D4D4", "F c #DCDCDC", "G c #ECECEC", "H c #828282", "I c #B8B8B8", "J c #B7B7B7", "K c #737373", "L c #4E4E4E", "M c #454545", "N c #626262", "O c #777777", "P c #4A4A4A", "Q c #939393", "R c #616161", "S c #A7A7A7", "T c #818181", "U c #505050", "V c #434343", "W c #C3C3C3", "X c #B5B5B5", "Y c #7F7F7F", "Z c #6B6B6B", "` c #B0B0B0", " . c #787878", ".. c #5A5A5A", "+. c #464646", "@. c #3C3C3C", "#. c #444444", "$. c #C2C2C2", "%. c #6A6A6A", "&. c #C5C5C5", "*. c #D2D2D2", "=. c #B9B9B9", "-. c #646464", ";. c #424242", ">. c #363636", ",. c #383838", "'. c #606060", "). c #C7C7C7", "!. c #D1D1D1", "~. c #D0D0D0", "{. c #343434", "]. c #414141", "^. c #B4B4B4", "/. c #5E5E5E", "(. c #BABABA", "_. c #CDCDCD", ":. c #7E7E7E", "<. c #959595", "[. c #7C7C7C", "}. c #5D5D5D", "|. c #9F9F9F", "1. c #767676", "2. c #6D6D6D", "3. c #5C5C5C", "4. c #525252", "5. c #7A7A7A", "6. c #C4C4C4", "7. c #B6B6B6", "8. c #C8C8C8", "9. c #ADADAD", "0. c #6E6E6E", "a. c #676767", "b. c #B1B1B1", "c. c #656565", "d. c #D6D6D6", "e. c #636363", "f. c #AEAEAE", "g. c #5F5F5F", "h. c #747474", "i. c #585858", "j. c #A3A3A3", "k. c #535353", "l. c #717171", "m. c #707070", "n. c #6C6C6C", "o. c #CBCBCB", "p. c #6F6F6F", "q. c #4D4D4D", "r. c #666666", "s. c #4F4F4F", "t. c #696969", "u. c #D9D9D9", "v. c #A1A1A1", "w. c #DBDBDB", "x. c #D8D8D8", "y. c #7B7B7B", "z. c #F7F7F7", "A. c #CACACA", "B. c #F8F8F8", "C. c #F9F9F9", "D. c #7D7D7D", "E. c #DADADA", "F. c #575757", "G. c #2B2B2B", "H. c #323232", "I. c #D3D3D3", "J. c #D5D5D5", "K. c #D7D7D7", "L. c #797979", "M. c #474747", "N. c #CECECE", "O. c #CFCFCF", "P. c #CCCCCC", "Q. c #555555", "R. c #545454", " ", " ", " ", " . + @ # $ $ # % + & * = - . ; > , ' ) ! ~ { ] ^ / ( _ : < [ ] ] ^ } ", " | 1 2 3 3 2 2 2 2 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 8 8 8 8 8 9 9 0 a ", " b 6 c d e e f 0 g 0 0 0 c c c h h h h i i i i i i i i i i i i i i j k ( ", " b 6 0 l d d i g e g g 0 0 0 c c c c h h h h h h h i i i i h h h h f k ( ", " ; 6 c d d e f g g g 0 0 c c c h h h h i i i i i i i i i i i i i i j k _ ", " m 6 c d e e f 0 0 0 0 c c h h h i i i i f f f f f f f f f f f f f j n _ ", " > 6 h e e g j 0 0 e o p q q q q q q r r r r r r r r r r r s f f f 1 n _ ", " | 6 h e g g j c c e s p p q q q q q q r r r r r r r r r r r f j j 1 n _ ", " t 6 h g g 0 1 c c g o q q q q q q r r r r r r r r r r r r r j 1 1 u n } ", " ' 7 i g 0 0 1 h h h h h i i f f f j j j j j j 1 1 1 1 1 1 1 1 1 1 v n } ", " ) 7 i 0 0 c u h h i i f f j j j 1 1 1 u u u u u u v v v u u u u u v n } ", " ! 7 i 0 c c u i i i f f j j 1 1 1 u u u v v v v v v v v v v v v v w n } ", " x 7 f c c h u i i c y r r s s s s s o o o o o z z z z z z z v v v A n B ", " C 7 f c h h u f f c z r r r s s s s s s o o o o o o o o o o v w w A n B ", " D 8 j E F i v f j h y r r s s s s o o o o o o o o o o o o o w A A G 0 H ", " [ 8 j I l f v j j j j 1 1 1 u u v v v w w w w A A A A A A A A A u J K L M ", " < 9 j c G f w j j 1 1 u v v v w w A A A G G G G k k k k k k G i = N ' m O P ", " / 9 1 i f f w 1 1 1 u v v w w w A A G G G k k k k k k k k k g Q R S - T N U V ", " ( 9 1 i f f A 1 1 f W o z z z z z z y y y y y y y y y y y X Y Z ` m ...+.@.#. ", " } 9 1 f f j A u u f $.o o o o o o z z z z z z z y y y z % %.O &.*.=.-.;.>.,.;. ", " H 9 u f j j A u u j W o o o o o z z z z z y y y y y y * '. .q ).!.~.~ {.{.]. ", " a n u f j 1 G u v v v v w w A A G k k k n n n 9 9 A ^./._ =.(.% ` _.% {.#. ", " :.n u j j 1 G v v w w A A G k k n n 9 9 8 8 8 8 v % /.! (.=.* <.t r :.V ", " [.n u j 1 1 G v v w A A G G k n n 9 9 8 8 7 7 f m }.|.(.I - <.Q 1.2.3.4. ", " 5.n u j 1 u G v w 1 6.z z y y y $.$.$.W W $.7.:.'.@ (.X m <.~ 2.L 1.8.'. ", " .k u j 1 u G w w 1 W o o z z z y y y $.y 9.0.a.` (.b.| ) ] c.U ( l k '. ", " O k v p d.u G w w u W o z z z y y y $.$.@ e.K X p f.t <.: g.U | j 6 k '. ", " h.G v *.k v k w w A A A G k k n 9 9 k (.R T I (.+ <.) a i.i.f.G 5 5 k R ", " K G v 1 v v k w A A G k k n 9 8 8 A b.N { (.I j.<.! .k.-.o 8 4 5 5 k R ", " l.G v 1 u v k w A A G k n n 9 8 i = 3.m p J |.<.! m.L n.o.4 3 4 4 5 k R ", " p.G v 1 u v k A A v &.y y $.$.I H /.& (.^.> <.{ a.q.m.X &.&.4 3 4 4 k R ", " 2.G v 1 u v k A A u 6.z z y (.O r.9.(.` , ) / '.s.Y I 6.6.6.4 3 4 4 k R ", " Z A v 1 u v k A A v 6.z z z > /.&.W $ ' <.B ..k.! s &.&.6.6.3 3 3 4 k R ", " t.w v 1 u v k A A G G G k u.Z v.w.x.b.Q y.k.R p 9 z.z.z.2 2 2 3 3 4 k R ", " a.w v 1 u v k A A G k n G j.t._.*.~.&. .U p.A.4 z.B.C.C.B.z.2 3 3 4 k R ", " c.w v 1 u v k A A G k n !.r.& ).8.6.- ..D.x.3 z.z.B.B.B.B.z.2 3 3 4 k R ", " e.w v 1 u v k A A G k v { a.D $ ^ e.Z ; E.k n 9 8 7 6 6 5 4 4 4 4 4 k R ", " R w v 1 u v k A A w j s F.G.H.}.O j.&.I.J.J.J.K.u.w.l g c i j v A k w '. ", " g.v v 1 u v k A A v w.L.M./.{ =.N.I.!.O._.P._.O.!.E K.E.l g c f u w 1 g. ", " }.v w v v w n G G G $.D ^.w.u u j f i i i i i f j 1 v w G k n 8 7 6 k R ", " k.E G G G G k G G G i j G k k k k k k k k k k k k k k k k k k k k k E.Q. ", " R.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.R R R R R R R R R R R R R R R R Q. ", " ", " ", " "}; tqsl-2.0/apps/file_edit.xpm0000664000076400007640000002521712231073120015761 0ustar rmurphyrmurphy/* XPM */ static const char * file_edit_xpm[] = { "48 48 377 2", " c None", ". c #9E9E9E", "+ c #A8A8A8", "@ c #A9A9A9", "# c #ABABAB", "$ c #ACACAC", "% c #AAAAAA", "& c #A6A6A6", "* c #A4A4A4", "= c #A2A2A2", "- c #A0A0A0", "; c #9C9C9C", "> c #9A9A9A", ", c #989898", "' c #969696", ") c #949494", "! c #929292", "~ c #909090", "{ c #8E8E8E", "] c #8C8C8C", "^ c #8A8A8A", "/ c #888888", "( c #868686", "_ c #858585", ": c #878787", "< c #898989", "[ c #8B8B8B", "} c #848484", "| c #999999", "1 c #E7E7E7", "2 c #F6F6F6", "3 c #F5F5F5", "4 c #F4F4F4", "5 c #F3F3F3", "6 c #F2F2F2", "7 c #F1F1F1", "8 c #F0F0F0", "9 c #EFEFEF", "0 c #E1E1E1", "a c #808080", "b c #9D9D9D", "c c #E2E2E2", "d c #DEDEDE", "e c #DFDFDF", "f c #E5E5E5", "g c #E0E0E0", "h c #E3E3E3", "i c #E4E4E4", "j c #E6E6E6", "k c #EDEDED", "l c #DDDDDD", "m c #9B9B9B", "n c #EEEEEE", "o c #BFBFBF", "p c #BBBBBB", "q c #BCBCBC", "r c #BDBDBD", "s c #BEBEBE", "t c #979797", "u c #E8E8E8", "v c #E9E9E9", "w c #EAEAEA", "x c #919191", "y c #C1C1C1", "z c #C0C0C0", "A c #EBEBEB", "B c #838383", "C c #8F8F8F", "D c #8D8D8D", "E c #D4D4D4", "F c #DCDCDC", "G c #ECECEC", "H c #E2E1DE", "I c #828281", "J c #B8B8B8", "K c #E8E8E7", "L c #BFB7A6", "M c #85714B", "N c #684B1C", "O c #5E4310", "P c #E5E4E2", "Q c #ADA18A", "R c #7C5F32", "S c #C98A75", "T c #ED867F", "U c #D75E4E", "V c #734313", "W c #E3E0DD", "X c #A09276", "Y c #7D5D30", "Z c #E5988A", "` c #FF8686", " . c #FF5F5F", ".. c #FE3838", "+. c #C33419", "@. c #5C410C", "#. c #C3C3C3", "$. c #B8B5AF", "%. c #8F7E5D", "&. c #86683E", "*. c #E8A293", "=. c #F98181", "-. c #FF5454", ";. c #FD2E2E", ">. c #EB1919", ",. c #C41812", "'. c #61410C", "). c #C2C2C2", "!. c #AFAAA0", "~. c #7C6843", "{. c #90744C", "]. c #DEC298", "^. c #EFCF9D", "/. c #EDAF89", "(. c #F33E39", "_. c #E31717", ":. c #C41010", "<. c #9C1E0D", "[. c #5D400C", "}. c #828282", "|. c #AAA396", "1. c #745F35", "2. c #96753A", "3. c #DBB88B", "4. c #E5C394", "5. c #F1CE94", "6. c #F1CD8F", "7. c #DC7E5E", "8. c #BC0F0F", "9. c #9B1A0B", "0. c #6C3A0C", "a. c #ECEBEA", "b. c #BCB3A2", "c. c #745C2E", "d. c #A48241", "e. c #DCB671", "f. c #DDB771", "g. c #D6A651", "h. c #DCAA6B", "i. c #F0CA89", "j. c #DBA26A", "k. c #8F1D0A", "l. c #673F0C", "m. c #7E7E7E", "n. c #EAE9E7", "o. c #B4A994", "p. c #755C2B", "q. c #B38F4E", "r. c #DDB772", "s. c #DDB670", "t. c #D3A044", "u. c #CB9023", "v. c #C9913E", "w. c #E2B97C", "x. c #A1784D", "y. c #5E4011", "z. c #7C7C7C", "A. c #E6E5E2", "B. c #A79A7F", "C. c #765B26", "D. c #C09C59", "E. c #DCB56C", "F. c #D09C3A", "G. c #CB9022", "H. c #C98E21", "I. c #A27124", "J. c #8E683C", "K. c #715A31", "L. c #585247", "M. c #7A7A7A", "N. c #C4C4C4", "O. c #B9B6B0", "P. c #8C7D5E", "Q. c #7B5E26", "R. c #CBA662", "S. c #DBB266", "T. c #CE9731", "U. c #C58B21", "V. c #966A18", "W. c #6B4C12", "X. c #88744F", "Y. c #CDC8BF", "Z. c #606060", "`. c #787878", " + c #B2ADA5", ".+ c #7F6D4A", "++ c #83652B", "@+ c #D2AD69", "#+ c #D9AE5F", "$+ c #CD942B", "%+ c #CA8F21", "&+ c #C08820", "*+ c #8B6216", "=+ c #6B4E16", "-+ c #958564", ";+ c #E1DDD7", ">+ c #777777", ",+ c #D6D6D6", "'+ c #C2C2C1", ")+ c #AEA99D", "!+ c #76623A", "~+ c #917135", "{+ c #D8B26D", "]+ c #DEB873", "^+ c #D7AA56", "/+ c #CC9226", "(+ c #B9831F", "_+ c #825C15", ":+ c #694E1B", "<+ c #A6987D", "[+ c #E8E6E2", "}+ c #747474", "|+ c #D2D2D2", "1+ c #EDEDEC", "2+ c #C1B9A9", "3+ c #766033", "4+ c #9F7E40", "5+ c #DBB570", "6+ c #D4A44B", "7+ c #CA8F22", "8+ c #AF7C1D", "9+ c #785513", "0+ c #6F5626", "a+ c #B8AD99", "b+ c #EDECEA", "c+ c #616161", "d+ c #737373", "e+ c #ECEBE9", "f+ c #BAB09C", "g+ c #786031", "h+ c #AD8B4B", "i+ c #DCB56E", "j+ c #D29F41", "k+ c #C88E21", "l+ c #A5741B", "m+ c #725112", "n+ c #796336", "o+ c #C6BEAE", "p+ c #F1F0EF", "q+ c #717171", "r+ c #E6E4E1", "s+ c #ADA189", "t+ c #745A28", "u+ c #BB9856", "v+ c #DCB46B", "w+ c #D09B38", "x+ c #C78D21", "y+ c #996D19", "z+ c #6B4C11", "A+ c #7F6B44", "B+ c #D1CBC0", "C+ c #F4F4F3", "D+ c #6F6F6F", "E+ c #C5C5C5", "F+ c #BAB8B3", "G+ c #908165", "H+ c #785C27", "I+ c #C8A361", "J+ c #DAB165", "K+ c #CE962F", "L+ c #C28920", "M+ c #8E6417", "N+ c #694B14", "O+ c #816F4D", "P+ c #B8B5AD", "Q+ c #6D6D6D", "R+ c #BBBAB7", "S+ c #867657", "T+ c #81642C", "U+ c #CFAA67", "V+ c #D8AD5C", "W+ c #CC942A", "X+ c #BA841F", "Y+ c #845D15", "Z+ c #684D18", "`+ c #8C7E61", " @ c #6B6B6B", ".@ c #C1C0C0", "+@ c #A29988", "@@ c #755D29", "#@ c #D7C58E", "$@ c #DFC181", "%@ c #D6A852", "&@ c #CB9226", "*@ c #B37F1E", "=@ c #7B5713", "-@ c #6B5120", ";@ c #9D917B", ">@ c #BFBEBB", ",@ c #696969", "'@ c #DCD9D4", ")@ c #7E6A42", "!@ c #B5A16A", "~@ c #E5DCAE", "{@ c #E4D9A8", "]@ c #D5AF5B", "^@ c #C98F22", "/@ c #A8771C", "(@ c #765F32", "_@ c #C3BAA8", ":@ c #F0EFEE", "<@ c #F7F7F7", "[@ c #676767", "}@ c #ECECEB", "|@ c #AEA28B", "1@ c #826830", "2@ c #DFCE95", "3@ c #E2D39D", "4@ c #E1D098", "5@ c #DDC583", "6@ c #A17522", "7@ c #6E4E12", "8@ c #826D44", "9@ c #D0C9BC", "0@ c #F8F8F8", "a@ c #F9F9F9", "b@ c #656565", "c@ c #D6D1C9", "d@ c #7B6438", "e@ c #BFA564", "f@ c #DEC787", "g@ c #DEC888", "h@ c #DCC483", "i@ c #BB9F5D", "j@ c #74581D", "k@ c #8E7B58", "l@ c #DCD8CF", "m@ c #F5F5F4", "n@ c #636363", "o@ c #EAE9E8", "p@ c #9D8D70", "q@ c #786643", "r@ c #A28C59", "s@ c #C8AB64", "t@ c #A68947", "u@ c #7D6129", "v@ c #7F693F", "w@ c #A79B82", "x@ c #DCDAD4", "y@ c #C4BDB0", "z@ c #6B552A", "A@ c #322A1A", "B@ c #423111", "C@ c #745B2A", "D@ c #887653", "E@ c #ACA290", "F@ c #C8C5C0", "G@ c #D4D3D3", "H@ c #D5D5D5", "I@ c #D7D7D7", "J@ c #D9D9D9", "K@ c #DBDBDB", "L@ c #5F5F5F", "M@ c #DCDBD7", "N@ c #897854", "O@ c #5D4516", "P@ c #705C36", "Q@ c #9A8D73", "R@ c #BFB9AE", "S@ c #CFCECC", "T@ c #D3D3D3", "U@ c #D1D1D1", "V@ c #CFCFCF", "W@ c #CDCDCD", "X@ c #CCCCCC", "Y@ c #DADADA", "Z@ c #5D5D5D", "`@ c #C8C1B4", " # c #9B8C6E", ".# c #BCB3A1", "+# c #DDDBD5", "@# c #E9E8E8", "## c #535353", "$# c #E6E4E2", "%# c #E7E6E5", "&# c #555555", "*# c #545454", " ", " ", " ", " . + @ # $ $ # % + & * = - . ; > , ' ) ! ~ { ] ^ / ( _ : < [ ] ] ^ } ", " | 1 2 3 3 2 2 2 2 3 3 4 4 4 4 4 5 5 5 5 5 6 6 6 6 6 7 8 8 8 8 8 9 9 0 a ", " b 6 c d e e f 0 g 0 0 0 c c c h h h h i i i i i i i i i i i i i i j k ( ", " b 6 0 l d d i g e g g 0 0 0 c c c c h h h h h h h i i i i h h h h f k ( ", " ; 6 c d d e f g g g 0 0 c c c h h h h i i i i i i i i i i i i i i j k _ ", " m 6 c d e e f 0 0 0 0 c c h h h i i i i f f f f f f f f f f f f f j n _ ", " > 6 h e e g j 0 0 e o p q q q q q q r r r r r r r r r r r s f f f 1 n _ ", " | 6 h e g g j c c e s p p q q q q q q r r r r r r r r r r r f j j 1 n _ ", " t 6 h g g 0 1 c c g o q q q q q q r r r r r r r r r r r r r j 1 1 u n } ", " ' 7 i g 0 0 1 h h h h h i i f f f j j j j j j 1 1 1 1 1 1 1 1 1 1 v n } ", " ) 7 i 0 0 c u h h i i f f j j j 1 1 1 u u u u u u v v v u u u u u v n } ", " ! 7 i 0 c c u i i i f f j j 1 1 1 u u u v v v v v v v v v v v v v w n } ", " x 7 f c c h u i i c y r r s s s s s o o o o o z z z z z z z v v v A n B ", " C 7 f c h h u f f c z r r r s s s s s s o o o o o o o o o o v w w A n B ", " D 8 j E F i v f j h y r r s s s s o o o o o o o o o o o o o w A A G H I ", " [ 8 j J l f v j j j j 1 1 1 u u v v v w w w w A A A A A A A A A K L M N O ", " < 9 j c G f w j j 1 1 u v v v w w A A A G G G G k k k k k k G P Q R S T U V ", " / 9 1 i f f w 1 1 1 u v v w w w A A G G G k k k k k k k k k W X Y Z ` ...+.@. ", " ( 9 1 i f f A 1 1 f #.o z z z z z z y y y y y y y y y y y $.%.&.*.=.-.;.>.,.'. ", " } 9 1 f f j A u u f ).o o o o o o z z z z z z z y y y z !.~.{.].^./.(._.:.<.[. ", " }.9 u f j j A u u j #.o o o o o z z z z z y y y y y y |.1.2.3.4.5.6.7.8.9.0. ", " a n u f j 1 G u v v v v w w A A G k k k n n n 9 9 a.b.c.d.e.f.g.h.i.j.k.l. ", " m.n u j j 1 G v v w w A A G k k n n 9 9 8 8 8 8 n.o.p.q.r.s.t.u.v.w.x.y. ", " z.n u j 1 1 G v v w A A G G k n n 9 9 8 8 7 7 A.B.C.D.r.E.F.G.H.I.J.K.L. ", " M.n u j 1 u G v w 1 N.z z y y y ).).).#.#.).O.P.Q.R.r.S.T.G.U.V.W.X.Y.Z. ", " `.k u j 1 u G w w 1 #.o o z z z y y y ).y +.+++@+r.#+$+%+&+*+=+-+;+k Z. ", " >+k v p ,+u G w w u #.o z z z y y y ).'+)+!+~+{+]+^+/+G.(+_+:+<+[+6 k Z. ", " }+G v |+k v k w w A A A G k k n 9 9 1+2+3+4+5+f.6+u.7+8+9+0+a+b+5 5 k c+ ", " d+G v 1 v v k w A A G k k n 9 8 8 e+f+g+h+r.i+j+G.k+l+m+n+o+p+4 5 5 k c+ ", " q+G v 1 u v k w A A G k n n 9 8 r+s+t+u+]+v+w+G.x+y+z+A+B+C+3 4 4 5 k c+ ", " D+G v 1 u v k A A v E+y y ).).F+G+H+I+r.J+K+G.L+M+N+O+P+E+E+4 3 4 4 k c+ ", " Q+G v 1 u v k A A u N.z z y R+S+T+U+r.V+W+%+X+Y+Z+`+F+N.N.N.4 3 4 4 k c+ ", " @A v 1 u v k A A v N.z z .@+@@@#@$@%@&@G.*@=@-@;@>@E+E+N.N.3 3 3 4 k c+ ", " ,@w v 1 u v k A A G G G k '@)@!@~@{@]@^@/@m+(@_@:@<@<@<@2 2 2 3 3 4 k c+ ", " [@w v 1 u v k A A G k n }@|@1@2@3@4@5@6@7@8@9@C+<@0@a@a@0@<@2 3 3 4 k c+ ", " b@w v 1 u v k A A G k n c@d@e@f@g@h@i@j@k@l@m@<@<@0@0@0@0@<@2 3 3 4 k c+ ", " n@w v 1 u v k A A G k o@p@q@r@s@t@u@v@w@x@k n 9 8 7 6 6 5 4 4 4 4 4 k c+ ", " c+w v 1 u v k A A w j y@z@A@B@C@D@E@F@G@H@H@H@I@J@K@l g c i j v A k w Z. ", " L@v v 1 u v k A A v M@N@O@P@Q@R@S@T@U@V@W@X@W@V@U@E I@Y@l g c f u w 1 L@ ", " Z@v w v v w n G G G `@ #.#+#@#u j f i i i i i f j 1 v w G k n 8 7 6 k c+ ", " ##E G G G G k G G G $#%#G k k k k k k k k k k k k k k k k k k k k k Y@&# ", " *#Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.Z.c+c+c+c+c+c+c+c+c+c+c+c+c+c+c+c+&# ", " ", " ", " "}; tqsl-2.0/apps/extwizard.h0000664000076400007640000000405612231073120015477 0ustar rmurphyrmurphy/*************************************************************************** extwizard.h - description ------------------- begin : Thu Aug 7 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #ifndef __extwizard_h #define __extwizard_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #include "wxutil.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "wx/wizard.h" #include "wx/wxhtml.h" class ExtWizard_Page; class ExtWizard : public wxWizard { public: ExtWizard(wxWindow *parent, wxHtmlHelpController *help = 0, const wxString& title = wxEmptyString); ExtWizard_Page *GetCurrentPage() { return (ExtWizard_Page *)wxWizard::GetCurrentPage(); } wxHtmlHelpController *GetHelp() { return _help; } void DisplayHelp(const wxString& file) { if (_help) _help->Display(file); } void ReportSize(const wxSize& size); void AdjustSize() { SetPageSize(_minsize); } bool HaveHelp() const { return _help != 0; } protected: void OnPageChanged(wxWizardEvent&); wxHtmlHelpController *_help; wxSize _minsize; DECLARE_EVENT_TABLE() }; class ExtWizard_Page : public wxWizardPageSimple { public: ExtWizard_Page(ExtWizard *parent) : wxWizardPageSimple(parent), _parent(parent), _helpfile(wxT("")) {} virtual const char *validate() { return NULL; } // Returns error message string or NULL=no error virtual void refresh() { } // Updates page contents based on page-specific criteria void check_valid(TQ_WXTEXTEVENT&); protected: ExtWizard *_parent; void AdjustPage(wxBoxSizer *sizer, const wxString& helpfile = wxT("")); private: void OnHelp(wxCommandEvent&) { if (_helpfile != wxT("")) _parent->DisplayHelp(_helpfile); } wxString _helpfile; DECLARE_EVENT_TABLE(); }; #endif // __extwizard_h tqsl-2.0/apps/extwizard.cpp0000664000076400007640000000444612231073120016035 0ustar rmurphyrmurphy/*************************************************************************** extwizard.cpp - description ------------------- begin : Thu Aug 7 2003 copyright : (C) 2003 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "extwizard.h" #include "tqsltrace.h" #define EW_HELP_BUT wxID_HIGHEST+300 BEGIN_EVENT_TABLE(ExtWizard, wxWizard) EVT_WIZARD_PAGE_CHANGED(-1, ExtWizard::OnPageChanged) END_EVENT_TABLE() void ExtWizard::OnPageChanged(wxWizardEvent&) { tqslTrace("ExtWizard::OnPageChanged"); GetCurrentPage()->refresh(); GetCurrentPage()->SetFocus(); wxWindow *but = FindWindow(wxID_FORWARD); if (but == NULL) return; but->Enable(!GetCurrentPage()->validate()); } void ExtWizard::ReportSize(const wxSize& size) { tqslTrace("ExtWizard::ReportSize", "size=%d %d", size.GetWidth(), size.GetHeight()); if (size.GetWidth() > _minsize.GetWidth()) _minsize.SetWidth(size.GetWidth()); if (size.GetHeight() > _minsize.GetHeight()) _minsize.SetHeight(size.GetHeight()); } ExtWizard::ExtWizard(wxWindow *parent, wxHtmlHelpController *help, const wxString& title) : wxWizard(parent, -1, title), _help(help) { tqslTrace("ExtWizard::ExtWizard", "parent=%lx, title=%s", (void *)parent, _S(title)); CenterOnParent(); } BEGIN_EVENT_TABLE(ExtWizard_Page, wxWizardPageSimple) EVT_BUTTON(EW_HELP_BUT, ExtWizard_Page::OnHelp) END_EVENT_TABLE() void ExtWizard_Page::check_valid(TQ_WXTEXTEVENT&) { tqslTrace("ExtWizard_Page::check_valid"); wxWindow *but = GetParent()->FindWindow(wxID_FORWARD); if (but != NULL) but->Enable(validate() == NULL); } void ExtWizard_Page::AdjustPage(wxBoxSizer *sizer, const wxString& helpfile) { tqslTrace("ExtWizard_Page::AdjustPage"); _helpfile = helpfile; if (_helpfile != wxT("") && _parent->HaveHelp()) { // Space filler sizer->Add(new wxStaticText(this, -1, wxT("")), 1, 0, 10); sizer->Add(new wxButton(this, EW_HELP_BUT, wxT("Help")), 0, wxALL, 10); } SetAutoLayout(TRUE); SetSizer(sizer); sizer->Fit(this); sizer->SetSizeHints(this); _parent->ReportSize(sizer->CalcMin()); } tqsl-2.0/apps/expired.xpm0000664000076400007640000000230412231073120015465 0ustar rmurphyrmurphy/* XPM */ static const char * expired_xpm[] = { "16 16 56 1", " c None", ". c #FDE55E", "+ c #FEEA80", "@ c #FEED92", "# c #FEEE97", "$ c #FEEC88", "% c #FEEC8D", "& c #FDE976", "* c #E2CA45", "= c #FADF4C", "- c #FDE76B", "; c #FEEA7E", "> c #BFC1CC", ", c #FDE769", "' c #FDE664", ") c #FDE354", "! c #F0D649", "~ c #D6BF41", "{ c #EDD448", "] c #FDE250", "^ c #FBFBFB", "/ c #FCFCFC", "( c #FDFDFD", "_ c #FEFEFE", ": c #F2D84A", "< c #E9D047", "[ c #DCC543", "} c #CFB93F", "| c #F6F6F6", "1 c #F5F5F5", "2 c #9C9C9C", "3 c #F8F8F8", "4 c #CDB73F", "5 c #CEB83F", "6 c #F3F3F3", "7 c #F0F0F0", "8 c #EFEFEF", "9 c #F7F7F7", "0 c #C6B13C", "a c #EDEDED", "b c #E9E9E9", "c c #E8E8E8", "d c #E4E4E4", "e c #E2E2E2", "f c #B64F54", "g c #B00000", "h c #DEDEDE", "i c #CF6767", "j c #FE6464", "k c #FCAFAD", "l c #737373", "m c #FAFAF7", "n c #EC4F4F", "o c #DA3939", "p c #C51D1D", "q c #FFFFFF", "qqqqqqqqqqqqqqqq", "q.+@#qq$%$&qqqqq", "*=-;>>>>,')!qqqq", "~{]>^/(_>:<[qqqq", "}*>|123^_>~4qqqq", "5>678269^_>0qqqq", "q>abc2a63(>qqqqq", "q>bde2222/fggqqq", "q>cehec81igjggqq", "q>>dedb7|gjkjgqq", "ql2>cba6fgjmjggq", "l2l>>>>>gnnnnngq", "llqqqqqqgoomoogq", "qqqqqqqgpooooopg", "qqqqqqqqgggggggq", "qqqqqqqqqqqqqqqq"}; tqsl-2.0/apps/edit_dis.xpm0000664000076400007640000001466112231073120015622 0ustar rmurphyrmurphy/* XPM */ static const char * edit_dis_xpm[] = { "48 48 107 2", " c #FFFFFF", ". c #B9B9B9", "+ c #C1C1C1", "@ c #C0C0C0", "# c #CACACA", "$ c #D0D0D0", "% c #C9C9C9", "& c #CFCFCF", "* c #C8C8C8", "= c #CDCDCD", "- c #BEBEBE", "; c #BABABA", "> c #C6C6C6", ", c #CCCCCC", "' c #C5C5C5", ") c #CBCBCB", "! c #C7C7C7", "~ c #BBBBBB", "{ c #BCBCBC", "] c #A8A8A8", "^ c #ACACAC", "/ c #AFAFAF", "( c #A7A7A7", "_ c #ADADAD", ": c #959595", "< c #979797", "[ c #989898", "} c #9B9B9B", "| c #969696", "1 c #999999", "2 c #9C9C9C", "3 c #9A9A9A", "4 c #9E9E9E", "5 c #9F9F9F", "6 c #9D9D9D", "7 c #A0A0A0", "8 c #A6A6A6", "9 c #BFBFBF", "0 c #A1A1A1", "a c #A2A2A2", "b c #B6B6B6", "c c #D2D2D2", "d c #D4D4D4", "e c #A3A3A3", "f c #D6D6D6", "g c #D7D7D7", "h c #D8D8D8", "i c #D9D9D9", "j c #CECECE", "k c #A4A4A4", "l c #DADADA", "m c #DBDBDB", "n c #DCDCDC", "o c #DDDDDD", "p c #DEDEDE", "q c #C3C3C3", "r c #A5A5A5", "s c #B2B2B2", "t c #DFDFDF", "u c #E0E0E0", "v c #E1E1E1", "w c #B8B8B8", "x c #E2E2E2", "y c #E3E3E3", "z c #E4E4E4", "A c #E5E5E5", "B c #AAAAAA", "C c #E7E7E7", "D c #E8E8E8", "E c #E9E9E9", "F c #A9A9A9", "G c #E6E6E6", "H c #EAEAEA", "I c #EBEBEB", "J c #D3D3D3", "K c #ABABAB", "L c #ECECEC", "M c #EDEDED", "N c #EEEEEE", "O c #EFEFEF", "P c #F0F0F0", "Q c #AEAEAE", "R c #F1F1F1", "S c #F2F2F2", "T c #F3F3F3", "U c #B0B0B0", "V c #F4F4F4", "W c #B1B1B1", "X c #F5F5F5", "Y c #F6F6F6", "Z c #B4B4B4", "` c #F7F7F7", " . c #F8F8F8", ".. c #B3B3B3", "+. c #F9F9F9", "@. c #FAFAFA", "#. c #B5B5B5", "$. c #FBFBFB", "%. c #B7B7B7", "&. c #C2C2C2", "*. c #BDBDBD", "=. c #FCFCFC", "-. c #FDFDFD", ";. c #FEFEFE", ">. c #D5D5D5", ",. c #D1D1D1", "'. c #2C2C2C", " ", " ", " ", " . + + + + + + + + @ ", " # $ $ $ $ $ $ $ $ $ # ", " % & & & & & & & & & & % ", " * = = = = = = = = = = = % - - - - - - - - - - - - - - - - - - - - - - - - - - ; ", " > , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , * ", " ' ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ! ", " ~ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { ", " ] ^ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / ^ ( ", "^ ~ ; ; ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ; ; ~ _ ", ": < < [ } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } [ < < : ", "| [ [ 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 [ [ | ", "< 3 3 } 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 } 3 3 < ", "[ } } 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 } } [ ", "1 6 6 6 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 9 @ ( 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 4 6 6 1 ", "} 4 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a b = c d $ . a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 5 4 4 } ", "6 7 7 7 e e e e e e e e e e e e e e e _ * f g h h i i j / e e e e e e e e e e e e e e e 0 7 7 6 ", "7 0 0 a k k k k k k k k k k k k k ( @ g l m m n n o o p m q ] k k k k k k k k k k k k k a 0 0 7 ", "e e e k r r r r r r r r r r r r s c o p p t t t u u u u u v i w r r r r r r r r r r r r k e e e ", "8 r r 8 ( ( ( ( ( ( ( ( ( ( ^ # t u u v v v x x y y y z z z A A j _ ( ( ( ( ( ( ( ( ( ( 8 r r 8 ", " ( ( ( ] ] ] ] ] ] ] ] B ~ m x y y y z z z A A A C C C D D D D E v q B ] ] ] ] ] ] ] ] ( ( ( F ", " F F F F F F F F F F F - j & A G G G C C D D D D E E E H H I I I J c q B F F F F F F F F F F ", " K B B B B B B B B B B B B B A D E H H H H H I I I L L L L M N L K B B B B B B B B B B B B K ", " _ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ G I I L L L L M M N N O O O O P P L ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ _ ", " Q Q _ _ _ _ _ _ _ _ _ _ _ _ G M N N N O O O P P P P R R S S T M Q _ _ _ _ _ _ _ _ _ _ _ Q Q ", " U / Q _ _ _ _ _ _ _ _ _ _ _ G P P P R R S S S S S T T T T V V L Q _ _ _ _ _ _ _ _ _ _ Q / U ", " s W U / / / / / / / / / / / C S S T T T T & w w w w I X Y Y Y L / / / / / / / / / / / U W W ", " Z s W U U U U U U U U U U U C T V V X X X ) U U U U M ` ` . .L U U U U U U U U U U U W s .. ", " b Z s W W W W W W W W W W W C X Y Y Y ` ` $ W W W W R +.+.+.@.L s W W W W W W W W W W s Z b ", " { ; w #.#.#.#.#.#.#.#.#.#.#.D . . .+.+.+.d #.#.#.#.V @.@.@.$.M b #.#.#.#.#.#.#.#.#.#.%.; { ", " &.@ *.~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ; G +.@.@.@.@.@.l ~ ~ ~ ~ .=.=.-.-.L ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ *.@ &. ", " * > q + + + + + + + + + + + z $.$.$.$.$.$.t + + + + $.-.;.;.;.H + + + + + + + + + + + q > * ", " = = % ! ! ! ! ! ! ! ! ! ! ! ) & & & & & & # ! ! ! ! & & & & & , ! ! ! ! ! ! ! ! ! ! ! % = = ", " J d & , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , & J J ", " >.f $ & j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j j & $ >.>. ", " ,.$ # % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % # $ ,. ", " w %.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.%.w ", " '.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.'. ", " ", " ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/edit.xpm0000664000076400007640000002415212231073120014757 0ustar rmurphyrmurphy/* XPM */ static const char * edit_xpm[] = { "48 48 343 2", " c None", ". c #ECB362", "+ c #F2BB6E", "@ c #F2BA6C", "# c #FAC479", "$ c #FFCA81", "% c #FBC479", "& c #FAC375", "* c #FFC97D", "= c #FBC375", "- c #FAC272", "; c #FFC779", "> c #FBC373", ", c #F2B865", "' c #EFB360", ") c #FAC06F", "! c #FFC676", "~ c #FBC271", "{ c #FABF6B", "] c #FFC472", "^ c #FBC06D", "/ c #F1B26F", "( c #F6B979", "_ c #F2B472", ": c #E49F4B", "< c #E6A35C", "[ c #E9A661", "} c #E7A35D", "| c #E39E4B", "1 c #EDA43F", "2 c #F2B45C", "3 c #F2B35B", "4 c #F3B45C", "5 c #EDA53F", "6 c #EA8A05", "7 c #EC8C05", "8 c #ED8D07", "9 c #EE900E", "0 c #EA8B05", "a c #ED8E09", "b c #EF9210", "c c #EE8E0A", "d c #EA8B06", "e c #EB8C08", "f c #EE8F0B", "g c #EE900D", "h c #F09313", "i c #EC8D0A", "j c #EF910D", "k c #EF920F", "l c #F19515", "m c #EC8F0C", "n c #F09210", "o c #F09312", "p c #F19617", "q c #F29D25", "r c #F5B862", "s c #F5B964", "t c #F29E27", "u c #F19717", "v c #F09412", "w c #ED9110", "x c #F19413", "y c #F19514", "z c #F29719", "A c #F2981A", "B c #F4AE4B", "C c #F7C888", "D c #F8CD92", "E c #F8CF95", "F c #F8CB8C", "G c #F5B152", "H c #EF9314", "I c #F29615", "J c #F29617", "K c #F3991B", "L c #F4A434", "M c #F7C279", "N c #F9D29C", "O c #F9D39E", "P c #F9D49F", "Q c #F9D4A0", "R c #F9D5A2", "S c #F8C986", "T c #F4A639", "U c #F29717", "V c #EE9314", "W c #F09619", "X c #F39718", "Y c #F39819", "Z c #F49A1D", "` c #F49D23", " . c #F7B962", ".. c #FAD39D", "+. c #FAD6A4", "@. c #FAD7A5", "#. c #FAD7A7", "$. c #FAD8A7", "%. c #FAD8A9", "&. c #FAD9AA", "*. c #FAD9AB", "=. c #FADAAD", "-. c #FAD7A6", ";. c #F7BC6A", ">. c #F49F27", ",. c #F2991D", "'. c #F4991B", "). c #F49A1C", "!. c #F59B1F", "~. c #F6A93F", "{. c #F9CD91", "]. c #FBDAAD", "^. c #FBDBAE", "/. c #FBDBAF", "(. c #FBDBB0", "_. c #FBDCB2", ":. c #FBDDB3", "<. c #FBDDB5", "[. c #FBDEB6", "}. c #FAD5A2", "|. c #F7B04E", "1. c #F39C23", "2. c #F59B1E", "3. c #F59C1F", "4. c #F59D21", "5. c #F6A32E", "6. c #F9C47A", "7. c #FBDEB5", "8. c #FBDFB7", "9. c #FBE0B9", "0. c #FBE0BA", "a. c #FBE1BB", "b. c #FBE1BD", "c. c #FCE1BD", "d. c #FCE2BF", "e. c #FBE2BE", "f. c #F9C987", "g. c #F6A431", "h. c #F49C23", "i. c #F69D21", "j. c #F69E23", "k. c #F6A027", "l. c #F8B354", "m. c #FBD7A6", "n. c #FCE0BA", "o. c #FCE1BC", "p. c #FCE2BE", "q. c #FCE4C1", "r. c #FCE4C2", "s. c #FCE4C3", "t. c #FCE5C4", "u. c #FCE5C5", "v. c #FCE5C6", "w. c #FCE6C7", "x. c #FCE6C8", "y. c #F8BC67", "z. c #F6A028", "A. c #F69D22", "B. c #F59F28", "C. c #F79F24", "D. c #F79F25", "E. c #F9B659", "F. c #FAC883", "G. c #FAC986", "H. c #FCE2BD", "I. c #FCE3BF", "J. c #FCE3C1", "K. c #FCE4C4", "L. c #FCE6C6", "M. c #FCE7CA", "N. c #FCE8CB", "O. c #FDE8CC", "P. c #FDE8CD", "Q. c #FDE9CE", "R. c #FBCE91", "S. c #FBCD8F", "T. c #F9BC69", "U. c #F7A026", "V. c #F8A128", "W. c #F8A026", "X. c #F7A027", "Y. c #FDE7C9", "Z. c #FDE8CB", "`. c #FDE9CD", " + c #FDEACF", ".+ c #FDEAD0", "++ c #FDEAD1", "@+ c #FDEBD4", "#+ c #FDECD4", "$+ c #FCEAD0", "%+ c #F7A22B", "&+ c #F8A027", "*+ c #F8A127", "=+ c #F9A32B", "-+ c #F9A229", ";+ c #F8A229", ">+ c #FDEBD2", ",+ c #FDEBD3", "'+ c #FDECD3", ")+ c #FDECD5", "!+ c #FDEDD6", "~+ c #FDEDD7", "{+ c #FDEDD8", "]+ c #FDEED9", "^+ c #F8A32C", "/+ c #FAA52E", "(+ c #FAA42C", "_+ c #FAA32B", ":+ c #FCE3C0", "<+ c #FDECD6", "[+ c #FDEEDA", "}+ c #FDEFDA", "|+ c #FDEFDC", "1+ c #FDF0DD", "2+ c #FEF0DE", "3+ c #FEF0DF", "4+ c #FEF1E0", "5+ c #FDEBD1", "6+ c #F9A42E", "7+ c #FBA732", "8+ c #FBA52F", "9+ c #F9A42D", "0+ c #FDEFDB", "a+ c #FEEFDC", "b+ c #FEF0DD", "c+ c #FEF1DE", "d+ c #FEF1DF", "e+ c #FEF2E1", "f+ c #FEF2E2", "g+ c #FEF3E4", "h+ c #FEF3E5", "i+ c #F9A530", "j+ c #FBA632", "k+ c #FCA935", "l+ c #FCA732", "m+ c #FBA631", "n+ c #FAA52F", "o+ c #FDE4C2", "p+ c #FEF1E1", "q+ c #FCC982", "r+ c #FBB048", "s+ c #FEF4E7", "t+ c #FEF5E8", "u+ c #FEF5E9", "v+ c #FEF5EA", "w+ c #FAA632", "x+ c #FCA834", "y+ c #FDAB38", "z+ c #FDA935", "A+ c #FCA833", "B+ c #FDE4C1", "C+ c #FEF2E3", "D+ c #FEF3E3", "E+ c #FEF4E6", "F+ c #FCC57A", "G+ c #FEF6ED", "H+ c #FEF7EE", "I+ c #FBA733", "J+ c #FDAA37", "K+ c #FEAD3D", "L+ c #FEAB38", "M+ c #FCA936", "N+ c #FBA834", "O+ c #FDE4C3", "P+ c #FEF4E8", "Q+ c #FEF6EB", "R+ c #FEF6EC", "S+ c #FCCA83", "T+ c #FEF8F0", "U+ c #FEF8F1", "V+ c #FEF8F2", "W+ c #FEF9F2", "X+ c #FBA936", "Y+ c #FEAD3C", "Z+ c #FFB34B", "`+ c #FFB146", " @ c #FDAF42", ".@ c #FCAC3F", "+@ c #FDE5C4", "@@ c #FEF7EF", "#@ c #FEF8EF", "$@ c #FDCF90", "%@ c #FDF3E5", "&@ c #FEFAF5", "*@ c #FEFBF6", "=@ c #FDEBD0", "-@ c #FCAD41", ";@ c #FDAE42", ">@ c #FFBA5B", ",@ c #FFB857", "'@ c #FDB552", ")@ c #FCB24E", "!@ c #FCB24D", "~@ c #FDE3C1", "{@ c #FEF9F3", "]@ c #FEFAF4", "^@ c #FDD59E", "/@ c #FDF7ED", "(@ c #FEFCF8", "_@ c #FEFCF9", ":@ c #FEFDFA", "<@ c #FCB34F", "[@ c #FFC16B", "}@ c #FFBF69", "|@ c #FDBC63", "1@ c #FCB95E", "2@ c #FDE1BE", "3@ c #FEFAF6", "4@ c #FEFBF7", "5@ c #FEFBF8", "6@ c #FDDBAC", "7@ c #FDFBF6", "8@ c #FEFDFC", "9@ c #FEFEFC", "0@ c #FDBC62", "a@ c #FFC77A", "b@ c #FDC372", "c@ c #FCC06E", "d@ c #FCC983", "e@ c #FCC478", "f@ c #FCC67B", "g@ c #FDC272", "h@ c #FFCD87", "i@ c #FFCE8B", "j@ c #FCC981", "k@ c #FCC67D", "l@ c #FECE8B", "m@ c #FFCF8E", "n@ c #FED192", "o@ c #FCCA86", "p@ c #FBC983", "q@ c #FBC883", "r@ c #FED092", "s@ c #FCCC89", "t@ c #FBCB89", "u@ c #F7C47F", "v@ c #F5C37E", "w@ c #F6C47F", "x@ c #FCCC8A", "y@ c #E0B377", "z@ c #E1B273", "A@ c #E0B273", "B@ c #2E2C2A", " ", " ", " ", " . + + + + + + + + @ ", " # $ $ $ $ $ $ $ $ $ % ", " & * * * * * * * * * * = ", " - ; ; ; ; ; ; ; ; ; ; ; > , , , , , , , , , , , , , , , , , , , , , , , , , , ' ", " ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~ ", " { ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ^ ", " / ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( _ ", " : < [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ } | ", "1 2 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 3 2 5 ", "6 7 7 8 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 8 7 7 6 ", "0 8 8 a b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b c 8 8 d ", "e f f g h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h h g f f e ", "i j j k l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l k j j i ", "m n n o p p p p p p p p p p p p p p p p p p q r s t u p p p p p p p p p p p p p p p p p v n n m ", "w x x y z z z z z z z z z z z z z z z z A B C D E F G A z z z z z z z z z z z z z z z z y x x w ", "H I I J K K K K K K K K K K K K K K K L M N O P Q R R S T K K K K K K K K K K K K K K K U I I V ", "W X X Y Z Z Z Z Z Z Z Z Z Z Z Z Z ` ...+.@.#.$.%.&.*.=.-.;.>.Z Z Z Z Z Z Z Z Z Z Z Z Z Y X X W ", ",.'.'.).!.!.!.!.!.!.!.!.!.!.!.!.~.{.*.].].^./.(._._.:.<.<.[.}.|.!.!.!.!.!.!.!.!.!.!.!.!.).'.'.,.", "1.2.2.3.4.4.4.4.4.4.4.4.4.4.5.6./._._.7.7.[.8.8.9.0.0.a.b.c.d.e.f.g.4.4.4.4.4.4.4.4.4.4.3.2.2.h.", " i.i.i.j.j.j.j.j.j.j.j.k.l.m.8.9.n.n.o.o.c.p.d.d.q.r.s.t.u.v.w.x.[.y.z.j.j.j.j.j.j.j.j.A.i.i.B.", " C.C.C.D.D.D.D.D.D.D.D.E.F.G.H.I.J.J.r.K.t.u.L.w.x.M.M.N.O.P.P.Q.R.S.T.U.D.D.D.D.D.D.D.C.C.C. ", " V.W.W.X.X.X.X.X.X.X.X.X.X.X.p.w.x.Y.Y.Z.Z.O.`.Q.Q. +.+.+++@+#+$+%+X.X.X.X.X.X.X.X.X.X.&+W.*+ ", " =+-+-+;+;+;+;+;+;+;+;+;+;+;+I.Q.Q. + +.+.+>+,+'+)+!+~+{+{+]+]+.+^+;+;+;+;+;+;+;+;+;+;+-+-+=+ ", " /+(+_+=+=+=+=+=+=+=+=+=+=+=+:+,+#+<+<+~+{+{+]+[+}+}+|+1+2+3+4+5+6+=+=+=+=+=+=+=+=+=+=+_+(+/+ ", " 7+8+/+9+9+9+9+9+9+9+9+9+9+9+J.]+[+[+0+a+b+c+d+d+d+e+e+f+f+g+h+++i+9+9+9+9+9+9+9+9+9+9+/+8+j+ ", " k+l+m+n+n+n+n+n+n+n+n+n+n+n+o+d+d+4+p+e+f+q+r+r+r+r+`.s+t+u+v+++w+n+n+n+n+n+n+n+n+n+n+m+l+x+ ", " y+z+A+m+m+m+m+m+m+m+m+m+m+m+B+C+D+g+E+E+s+F+m+m+m+m+>+G+G+H+H+.+I+m+m+m+m+m+m+m+m+m+m+A+z+J+ ", " K+L+M+N+N+N+N+N+N+N+N+N+N+N+O+P+u+v+v+Q+R+S+N+N+N+N+0+T+U+V+W+.+X+N+N+N+N+N+N+N+N+N+N+M+L+Y+ ", " Z+`+ @.@.@.@.@.@.@.@.@.@.@.@+@H+H+@@#@T+T+$@.@.@.@.@%@&@&@&@*@=@-@.@.@.@.@.@.@.@.@.@.@;@`+Z+ ", " >@,@'@)@)@)@)@)@)@)@)@)@)@!@~@U+W+{@]@]@&@^@)@)@)@)@/@(@_@:@:@.+<@)@)@)@)@)@)@)@)@)@)@'@,@>@ ", " [@}@|@1@1@1@1@1@1@1@1@1@1@1@2@3@3@4@4@4@5@6@1@1@1@1@7@8@9@9@9@Y.1@1@1@1@1@1@1@1@1@1@1@0@}@[@ ", " ; a@b@c@c@c@c@c@c@c@c@c@c@c@F+q+q+q+q+q+d@e@c@c@c@c@q+d@d@d@d@f@c@c@c@c@c@c@c@c@c@c@c@g@a@; ", " h@i@j@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@k@j@l@h@ ", " m@n@o@p@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@q@p@o@r@m@ ", " s@t@u@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@v@w@t@x@ ", " y@z@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@A@z@y@ ", " B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@B@ ", " ", " ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/dxcc.h0000664000076400007640000000161412231073120014374 0ustar rmurphyrmurphy/*************************************************************************** dxcc.h - description ------------------- begin : Tue Jun 18 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __dxcc_h #define __dxcc_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif class DXCC { public: DXCC() {}; int number() const { return _number; } const char * name() const { return _name; } const char * zonemap() const { return _zonemap; } bool getFirst(); bool getNext(); bool getByEntity(int e); static bool init(); private: static bool _init; int _number, _index; const char *_name; const char *_zonemap; }; #endif // __dxcc_h tqsl-2.0/apps/dxcc.cpp0000664000076400007640000000420412231073120014725 0ustar rmurphyrmurphy/*************************************************************************** dxcc.cpp - description ------------------- begin : Tue Jun 18 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include #include #include "dxcc.h" #include "tqsllib.h" #include "tqsltrace.h" #include "winstrdefs.h" bool DXCC::_init = false; static int num_entities = 0; static struct _dxcc_entity { int number; const char *name; const char *zonemap; } *entity_list = 0; static int _ent_cmp(const void *a, const void *b) { return strcasecmp(((struct _dxcc_entity *)a)->name, ((struct _dxcc_entity *)b)->name); } bool DXCC::init() { tqslTrace("DXCC::init"); // if (!_init) { if (tqsl_getNumDXCCEntity(&num_entities)) return false; entity_list = new struct _dxcc_entity[num_entities]; for (int i = 0; i < num_entities; i++) { tqsl_getDXCCEntity(i, &(entity_list[i].number), &(entity_list[i].name)); tqsl_getDXCCZoneMap(entity_list[i].number, &(entity_list[i].zonemap)); } qsort(entity_list, num_entities, sizeof (struct _dxcc_entity), &_ent_cmp); // } _init = true; return _init; } bool DXCC::getFirst() { tqslTrace("DXCC::getFirst"); if (!init()) return false; _index = -1; return getNext(); } bool DXCC::getNext() { tqslTrace("DXCC::getNext"); int newidx = _index+1; if (newidx < 0 || newidx >= num_entities) return false; _index = newidx; _number = entity_list[newidx].number; _name = entity_list[newidx].name; _zonemap = entity_list[newidx].zonemap; return true; } bool DXCC::getByEntity(int e) { tqslTrace("DXCC::getByEntity", "e=%d", e); _number = 0; _name = ""; _zonemap = ""; if (!init()) return false; for (int i = 0; i < num_entities; i++) { if (entity_list[i].number == e) { _index = i; _number = entity_list[i].number; _name = entity_list[i].name; _zonemap = entity_list[i].zonemap; return true; } } return false; } tqsl-2.0/apps/download_dis.xpm0000664000076400007640000001614212231073120016500 0ustar rmurphyrmurphy/* XPM */ static const char * download_dis_xpm[] = { "48 48 150 2", " c None", ". c #767676", "+ c #9D9D9D", "@ c #7D7D7D", "# c #A2A2A2", "$ c #9E9E9E", "% c #969696", "& c #909090", "* c #8C8C8C", "= c #4E4E4E", "- c #7F7F7F", "; c #A0A0A0", "> c #989898", ", c #9B9B9B", "' c #8E8E8E", ") c #8A8A8A", "! c #888888", "~ c #858585", "{ c #838383", "] c #7C7C7C", "^ c #797979", "/ c #757575", "( c #727272", "_ c #717171", ": c #494949", "< c #4D4D4D", "[ c #787878", "} c #919191", "| c #5C5C5C", "1 c #929292", "2 c #A4A4A4", "3 c #8D8D8D", "4 c #818181", "5 c #7A7A7A", "6 c #777777", "7 c #737373", "8 c #707070", "9 c #6F6F6F", "0 c #414141", "a c #747474", "b c #949494", "c c #5A5A5A", "d c #000000", "e c #AEAEAE", "f c #868686", "g c #848484", "h c #6A6A6A", "i c #676767", "j c #656565", "k c #636363", "l c #666666", "m c #3F3F3F", "n c #939393", "o c #595959", "p c #010101", "q c #898989", "r c #A8A8A8", "s c #999999", "t c #8B8B8B", "u c #878787", "v c #6D6D6D", "w c #565656", "x c #373737", "y c #404040", "z c #8F8F8F", "A c #5B5B5B", "B c #363636", "C c #505050", "D c #A3A3A3", "E c #828282", "F c #626262", "G c #474747", "H c #979797", "I c #3E3E3E", "J c #484848", "K c #A1A1A1", "L c #6E6E6E", "M c #686868", "N c #575757", "O c #959595", "P c #525252", "Q c #515151", "R c #4F4F4F", "S c #545454", "T c #6B6B6B", "U c #606060", "V c #585858", "W c #555555", "X c #5E5E5E", "Y c #616161", "Z c #696969", "` c #4C4C4C", " . c #9F9F9F", ".. c #7E7E7E", "+. c #5F5F5F", "@. c #535353", "#. c #5D5D5D", "$. c #464646", "%. c #808080", "&. c #646464", "*. c #6C6C6C", "=. c #020202", "-. c #7B7B7B", ";. c #444444", ">. c #353535", ",. c #030303", "'. c #2E2E2E", "). c #0B0B0B", "!. c #434343", "~. c #313131", "{. c #151515", "]. c #454545", "^. c #2D2D2D", "/. c #0A0A0A", "(. c #B7B7B7", "_. c #202020", ":. c #040404", "<. c #AFAFAF", "[. c #C9C9C9", "}. c #303030", "|. c #C4C4C4", "1. c #9A9A9A", "2. c #424242", "3. c #A5A5A5", "4. c #B1B1B1", "5. c #ACACAC", "6. c #A6A6A6", "7. c #BFBFBF", "8. c #B9B9B9", "9. c #B2B2B2", "0. c #CDCDCD", "a. c #C5C5C5", "b. c #BBBBBB", "c. c #DDDDDD", "d. c #D2D2D2", "e. c #C8C8C8", "f. c #4B4B4B", "g. c #3D3D3D", "h. c #4A4A4A", "i. c #3B3B3B", "j. c #323232", "k. c #333333", "l. c #3C3C3C", "m. c #2C2C2C", "n. c #262626", "o. c #101010", "p. c #383838", "q. c #3A3A3A", "r. c #393939", "s. c #282828", " ", " . + ", " @ # $ % & * ", " = - ; > $ , ' ) ! ~ { - ] ^ / ( _ _ ", " : < [ > } @ | 1 2 % 3 ! 4 @ 5 6 7 ( _ 8 8 _ _ ( ( ( ( ( 8 9 ", " 0 : < a & b c d * e + % } ' ) ) ! f g 4 @ 5 6 a 9 h i j k k j l i ", " m : < ( ' n o p q r s b & 3 t t * * 3 3 * t ) u g - 5 7 v i w = = ", " x y : < ( z b A p u 2 > n z * t t t t t t t ) q ! ! u f f ~ u l = = ", " B y : < ( * q C p ~ D > n & 3 * * * * t t t ) q ! u f g { E E F < = ", " x y : < i / . G p g # H } ! f ~ u ! ) t * 3 * * t ) ! u f ~ ~ k < = ", " I I : < F _ . J p { K % } - _ _ 8 9 L L v v L 9 8 _ a . 7 v M c = = ", " 9 N m J < F ( . G p { ; O 1 4 . . / a 7 a a ( 8 l o P Q R < S w w = = ", " h @ P G < F ( . G p E ; O & 4 6 . 6 / / T U | A V W S P Q C W N w = = ", " X Y F M Z h h h L . ^ R ` F _ / G p E .b & ..7 ( Z k F +.| A o N W @.Q R R S N w = = ", "F M v _ ( a / / / / a . 8 < #._ / $.p 4 $ n } ' %.9 &.k F F Y +.#.A o N W @.Q W w N = = ", "F i *.9 ( a a a a / / a 6 Y Y v / $.p %.$ O ~ L F k j j j j j &.k Y U +.#.| c V w S = = ", "F i *.9 ( a / / a 7 _ L h i @.v 7 $.p E s 5 i F F &.j j j j &.k F U +.X | c o N w Q R = ", "F M v 9 8 9 v h i l j &.Y A c W _ $.=./ -.h M &.F &.j j j j &.k F U +.#.| c o N w Q R = ", "Y k F F k &.&.&.&.j j &.F | w @.+.;.=.l . *.i k F &.j j j j &.k F U +.#.| c V N w Q R = ", "+.N c X F &.j j j j j &.F | w C G >.,.i / T l k F &.j j j j &.k F U X #.| c V N w Q R = ", "Y +.Y k &.j j j j j j &.F | w C ;.'.).&.a M &.F F &.j j j j &.k F U +.#.A c V N W Q R = ", "j h T T T h i j j j j &.F | w C !.~.{.F ( _ j F k &.j j j j &.k Y U +.#.A c V w W Q R = ", "h . 6 . a _ *.i j j j &.F | w C ].^./.k L (.D Y k &.j j j j k k Y U X #.A c V w W Q R = ", "9 g g 4 - ^ a v i j j &.F | w C G _.:.&.L <.[.a k &.j j j &.k F Y U X #.A o V w W Q R = ", "/ n } ' q { -.a v i j &.F | w S !.}.:.k 8 O |.%.k &.j j j &.k F Y +.X #.A o V w W Q R = ", "5 # .1.O 3 g -.( h j &.F | A 2.w 2.=.F v 3.4./ k &.j j j &.k F Y +.X | A o V w W Q R = ", "%.4.5.6. .% * 4 6 L i &.F +.@.< Z ;.=.F 9 1 T F k &.j j j &.k F Y +.X | A o N w W Q R = ", "f 7.8.9.r .n u ] ( h &.F +.: #.9 2.=.Y L & v k k &.j j j &.k F Y +.#.| c o N w W Q R = ", "t 0.a.b.4.6.s * %./ *.j M 2.R T L 2.=.U v ~ h k k &.j j j &.k F Y +.X | c o N w S Q R = ", "1 c.d.e.b.5.$ } g 6 L T f.y #.h v 0 =.+.*.Y +.F k &.j j j &.k F U +.X | c o N W S Q R = ", " 9 7 U g.: +.Z v 0 =.+.T k U Y k &.j j j &.k F U +.#.| c V N W S S R = ", " *.a m 0 ` +.Z *.0 =.X h k U Y k &.j j j &.k F U +.#.A c V N W S w = = ", " _ h.x $.f.X M *.y =.X Z F U Y k &.j j j &.k F U +.#.A c V N W S w = = ", " x i.$.f.X M T y =.#.Z Y U Y k &.j j j &.k Y U X #.A c V N W S w = = ", " j.g.$.f.X M h m =.| M Y U Y k &.j j &.&.k Y U X #.A c V w W S w = = ", " k.g.$.f.#.i h m =.| i U U F k &.j j &.&.F Y U X #.A o V w W @.W = = ", " k.g.].f.#.i h m =.A l U U F k &.j j &.k F Y U X #.A o V w W @.w = = ", " >.l.].f.#.l Z m =.A l +.U F k &.j j &.k F Y +.X #.A o N w W @.w = = ", " m.I ].f.#.l M m =.c j X U F k &.j j &.k F Y +.X | A o N w S @.Q = < ", " m.I ].f.| j M I =.Y L l j j j j j j &.k F Y +.X #.A c V w W @.C R C ", " n.m ].f.| j i g.d F _ *.v 9 8 8 8 8 9 v T M &.U | V W P C = = R P S ", " }.J f.| k l 0 o.k _ *.L L v T M Y | w Q = ` ` ` = C P S S W S N c ", " p.= X M F U N k j +.| N P < f.h.` = Q S W S @.C = h.].y q.>.j. ", " I T ^ / ( l U #.A V S Q = f.$.0 l.B ~.m. ", " w v F Q 2.r.k.^.s. ", " ", " ", " "}; tqsl-2.0/apps/download.xpm0000664000076400007640000004155612231073120015650 0ustar rmurphyrmurphy/* XPM */ static const char * download_xpm[] = { "48 48 775 2", " c None", ". c #BD3030", "+ c #D76363", "@ c #C03A3A", "# c #D86C6C", "$ c #D66666", "% c #D25A5A", "& c #CF5252", "* c #CD4B4B", "= c #9C0000", "- c #C13E3E", "; c #D86969", "> c #D06060", ", c #D86565", "' c #DB5B5B", ") c #CE4E4E", "! c #CC4848", "~ c #CB4646", "{ c #C74444", "] c #C54141", "^ c #C23D3D", "/ c #BF3939", "( c #BD3535", "_ c #BA3131", ": c #B82D2D", "< c #B72C2C", "[ c #930000", "} c #9B0000", "| c #BE3232", "1 c #D65B5B", "2 c #D35050", "3 c #AF4C4C", "4 c #803838", "5 c #C75E5E", "6 c #DA6F6F", "7 c #D35959", "8 c #CF4C4C", "9 c #CC4444", "0 c #C63D3D", "a c #C23838", "b c #C03535", "c c #BD3131", "d c #B92E2E", "e c #B72D2D", "f c #B52D2D", "g c #B42D2D", "h c #B52E2E", "i c #B62E2E", "j c #B62F2F", "k c #B52F2F", "l c #B32E2E", "m c #B12D2D", "n c #820000", "o c #BD2B2B", "p c #D24F4F", "q c #DA4E4E", "r c #823232", "s c #000101", "t c #BB5E5E", "u c #DE7F7F", "v c #D56666", "w c #D45858", "x c #D54E4E", "y c #D64646", "z c #D54040", "A c #D63E3E", "B c #D43D3D", "C c #D23B3B", "D c #CF3939", "E c #CB3737", "F c #C63535", "G c #C23333", "H c #BE3131", "I c #BA2E2E", "J c #B62828", "K c #B32222", "L c #B01F1F", "M c #AE1C1C", "N c #AC1B1B", "O c #AB1C1C", "P c #AB2020", "Q c #A92323", "R c #A92525", "S c #7F0000", "T c #9A0000", "U c #BC2929", "V c #D14C4C", "W c #D94E4E", "X c #833030", "Y c #020000", "Z c #BA5959", "` c #DB7575", " . c #D35F5F", ".. c #D35555", "+. c #D44C4C", "@. c #D54545", "#. c #D54141", "$. c #D74040", "%. c #D84141", "&. c #D94141", "*. c #D64141", "=. c #D44040", "-. c #D03F3F", ";. c #CC3C3C", ">. c #C73737", ",. c #C23232", "'. c #BB2B2B", "). c #B52525", "!. c #AE2020", "~. c #A10B0B", "{. c #9D0000", "]. c #6F0000", "^. c #810000", "/. c #D14D4D", "(. c #D95050", "_. c #843232", ":. c #030000", "<. c #B95555", "[. c #D35D5D", "}. c #D35454", "|. c #D34B4B", "1. c #D44545", "2. c #D64040", "3. c #D24040", "4. c #D04040", "5. c #CF4141", "6. c #CD4242", "7. c #CB4242", "8. c #C94343", "9. c #C64848", "0. c #AD1F1F", "a. c #6D0000", "b. c #D04949", "c. c #D43F3F", "d. c #7F2222", "e. c #B85252", "f. c #D96D6D", "g. c #D35353", "h. c #D74141", "i. c #CE4040", "j. c #CC4040", "k. c #C94040", "l. c #C74040", "m. c #C54040", "n. c #C34242", "o. c #A71E1E", "p. c #6E0400", "q. c #920000", "r. c #B71717", "s. c #C52525", "t. c #CC2020", "u. c #7B1313", "v. c #B85050", "w. c #D96C6C", "x. c #D25C5C", "y. c #D25151", "z. c #D03C3C", "A. c #D13A3A", "B. c #D43B3B", "C. c #D53C3C", "D. c #D83F3F", "E. c #D84040", "F. c #D84242", "G. c #D74242", "H. c #D54343", "I. c #D34343", "J. c #D04444", "K. c #CE4343", "L. c #CB4343", "M. c #C64444", "N. c #C44646", "O. c #A71F1F", "P. c #7B3102", "Q. c #7D0000", "R. c #B51010", "S. c #C41F1F", "T. c #CC2121", "U. c #7C1414", "V. c #B84F4F", "W. c #D96A6A", "X. c #D25B5B", "Y. c #C63838", "Z. c #B82B2B", "`. c #B92929", " + c #B82828", ".+ c #B82626", "++ c #B82525", "@+ c #B82424", "#+ c #B82323", "$+ c #B92222", "%+ c #B92323", "&+ c #BA2525", "*+ c #BA2727", "=+ c #BA2929", "-+ c #BB2E2E", ";+ c #BC3131", ">+ c #BA2C2C", ",+ c #B82222", "'+ c #B61B1B", ")+ c #A21313", "!+ c #9B0101", "~+ c #A8CE10", "{+ c #9C9D12", "]+ c #7F0700", "^+ c #910000", "/+ c #C42020", "(+ c #7B1414", "_+ c #D25959", ":+ c #D35151", "<+ c #C93939", "[+ c #C02D2D", "}+ c #C12C2C", "|+ c #C02B2B", "1+ c #BF2A2A", "2+ c #BE2929", "3+ c #BE2A2A", "4+ c #B92828", "5+ c #B31919", "6+ c #AC0707", "7+ c #A50000", "8+ c #A20000", "9+ c #9E0000", "0+ c #A80000", "a+ c #AD0000", "b+ c #A00C0C", "c+ c #A6C60E", "d+ c #B0D822", "e+ c #997B0B", "f+ c #8E0000", "g+ c #B74D4D", "h+ c #D86868", "i+ c #D25858", "j+ c #BF2F2F", "k+ c #BF2E2E", "l+ c #BD2E2E", "m+ c #BD2D2D", "n+ c #B91E1E", "o+ c #B40C0C", "p+ c #B10707", "q+ c #AF0707", "r+ c #AC0404", "s+ c #A90202", "t+ c #A70202", "u+ c #A40000", "v+ c #A00000", "w+ c #AA0000", "x+ c #AE0000", "y+ c #A00D0D", "z+ c #8FA914", "A+ c #93AE14", "B+ c #98B312", "C+ c #A2C110", "D+ c #A6C50E", "E+ c #A8C715", "F+ c #ADCB21", "G+ c #ACD41E", "H+ c #995406", "I+ c #980000", "J+ c #CB2020", "K+ c #D76767", "L+ c #D25757", "M+ c #D34E4E", "N+ c #C63737", "O+ c #BA2D2D", "P+ c #BA2B2B", "Q+ c #B61D1D", "R+ c #B31313", "S+ c #B21313", "T+ c #B10D0D", "U+ c #AF0909", "V+ c #AE0808", "W+ c #AC0606", "X+ c #AA0505", "Y+ c #A80303", "Z+ c #A50202", "`+ c #A20101", " @ c #9F0000", ".@ c #A90000", "+@ c #99B70E", "@@ c #95AB26", "#@ c #9DB624", "$@ c #A3BF23", "%@ c #A8C421", "&@ c #ACC920", "*@ c #ADCA20", "=@ c #ACCA20", "-@ c #ACCA1F", ";@ c #ACCC20", ">@ c #A5C51C", ",@ c #983002", "'@ c #B5050F", ")@ c #C31F1F", "!@ c #CB1F1F", "~@ c #7A1313", "{@ c #B74C4C", "]@ c #D76565", "^@ c #D15656", "/@ c #D34949", "(@ c #D03131", "_@ c #CB1414", ":@ c #C80101", "<@ c #C60000", "[@ c #C50000", "}@ c #C40000", "|@ c #C20000", "1@ c #BE0000", "2@ c #BB0000", "3@ c #B70000", "4@ c #B30000", "5@ c #AF0000", "6@ c #A60000", "7@ c #A30000", "8@ c #AB0000", "9@ c #A00E0E", "0@ c #98B60E", "a@ c #94AA25", "b@ c #9CB523", "c@ c #A2BD22", "d@ c #A8C420", "e@ c #ACC91F", "f@ c #A8CA24", "g@ c #9BAA18", "h@ c #B22310", "i@ c #C4171E", "j@ c #7A1212", "k@ c #B64A4A", "l@ c #D76666", "m@ c #CE3D3D", "n@ c #C71616", "o@ c #C70000", "p@ c #CA0000", "q@ c #CB0000", "r@ c #C80000", "s@ c #C30000", "t@ c #C00000", "u@ c #B80000", "v@ c #B40000", "w@ c #B00000", "x@ c #AC0000", "y@ c #A20707", "z@ c #ACCA21", "A@ c #ABC91D", "B@ c #AAC91A", "C@ c #A9C716", "D@ c #A2BF15", "E@ c #95BC13", "F@ c #988B0F", "G@ c #BF1C1B", "H@ c #CC1B1E", "I@ c #D55E5E", "J@ c #C72E2E", "K@ c #C10D0D", "L@ c #C20202", "M@ c #C90000", "N@ c #C10000", "O@ c #BF0000", "P@ c #BC0000", "Q@ c #B50000", "R@ c #B20000", "S@ c #9DB625", "T@ c #A7C31E", "U@ c #A9C718", "V@ c #A8C713", "W@ c #A6C60F", "X@ c #A4C50A", "Y@ c #A4C508", "Z@ c #A3C406", "`@ c #A2C305", " # c #9CBC06", ".# c #92AF08", "+# c #84AB09", "@# c #9A6C11", "## c #CD161E", "$# c #7B1112", "%# c #040000", "&# c #B13939", "*# c #C82E2E", "=# c #C01515", "-# c #C20E0E", ";# c #C30505", "># c #97B50D", ",# c #90A81E", "'# c #95B015", ")# c #9AB70E", "!# c #9EBE08", "~# c #A2C404", "{# c #A3C405", "]# c #A2C306", "^# c #9DBC08", "/# c #93B009", "(# c #87A20A", "_# c #799C0B", ":# c #AA4F15", "<# c #7E0A12", "[# c #AB2222", "}# c #C62626", "|# c #C01818", "1# c #C20C0C", "2# c #C30404", "3# c #B10000", "4# c #96B40A", "5# c #88A10D", "6# c #8FAB09", "7# c #97B508", "8# c #9EBE06", "9# c #88A20A", "0# c #7A940C", "a# c #73820D", "b# c #5E280C", "c# c #070000", "d# c #AC2322", "e# c #C01616", "f# c #C20B0B", "g# c #C30303", "h# c #BD0000", "i# c #98B50E", "j# c #8DA619", "k# c #95AF14", "l# c #9AB80F", "m# c #9FBE0A", "n# c #A2C307", "o# c #7C940C", "p# c #687D0C", "q# c #415408", "r# c #160B01", "s# c #AA1F22", "t# c #C52424", "u# c #C1100F", "v# c #C10808", "w# c #C30202", "x# c #9AB714", "y# c #94AC28", "z# c #9BB423", "A# c #A0BB1C", "B# c #A4C115", "C# c #A5C50F", "D# c #A4C509", "E# c #687B0C", "F# c #47580B", "G# c #282203", "H# c #A81C20", "I# c #C32223", "J# c #B62C2C", "K# c #BD0E0E", "L# c #C30101", "M# c #BA0000", "N# c #9EB91B", "O# c #9EB33A", "P# c #A3BA34", "Q# c #A7C02C", "R# c #A9C523", "S# c #AAC81A", "T# c #A7C712", "U# c #697D0D", "V# c #415308", "W# c #140900", "X# c #AB1C1D", "Y# c #BD201F", "Z# c #BBB4B5", "`# c #BD8A8B", " $ c #C20201", ".$ c #A8BA4E", "+$ c #ACC147", "@$ c #AEC53E", "#$ c #B0CA34", "$$ c #AFCB28", "%$ c #ACCA1E", "&$ c #A8C714", "*$ c #A5C50A", "=$ c #6E820C", "-$ c #3B2406", ";$ c #080000", ">$ c #AC1C1C", ",$ c #BC2020", "'$ c #B9A6A7", ")$ c #C3CFD0", "!$ c #BF2929", "~$ c #B60000", "{$ c #A6C02B", "]$ c #B2C364", "^$ c #B5C75B", "/$ c #B5CB51", "($ c #B6CE45", "_$ c #B5CF38", ":$ c #B1CD2A", "<$ c #ABCA1E", "[$ c #7C9D0B", "}$ c #7A500D", "|$ c #5D030B", "1$ c #AB1B1B", "2$ c #BF2223", "3$ c #A28889", "4$ c #BDC9CB", "5$ c #C04041", "6$ c #A9C233", "7$ c #BDCB7A", "8$ c #BECE70", "9$ c #BED164", "0$ c #BDD357", "a$ c #BBD347", "b$ c #B5D038", "c$ c #B0CD29", "d$ c #ABC91B", "e$ c #88AB0B", "f$ c #7A780A", "g$ c #9D1013", "h$ c #790C0E", "i$ c #050000", "j$ c #AB1A1A", "k$ c #BD1F1E", "l$ c #AC9FA0", "m$ c #B2B0B2", "n$ c #BF2C2D", "o$ c #B90000", "p$ c #ADC53B", "q$ c #C8D38F", "r$ c #C7D584", "s$ c #C6D677", "t$ c #C4D767", "u$ c #C0D756", "v$ c #BAD345", "w$ c #B4CF34", "x$ c #AECB24", "y$ c #A8C716", "z$ c #93B509", "A$ c #869C0A", "B$ c #8A1F10", "C$ c #C21117", "D$ c #7A0E0E", "E$ c #AB1919", "F$ c #BE2020", "G$ c #949092", "H$ c #954142", "I$ c #B2C943", "J$ c #D2DBA4", "K$ c #D0DC97", "L$ c #CDDC88", "M$ c #CADB76", "N$ c #C6DA64", "O$ c #BFD650", "P$ c #B8D13E", "Q$ c #B1CD2C", "R$ c #ABC91C", "S$ c #9DBD08", "T$ c #92B608", "U$ c #873C0B", "V$ c #B00B15", "W$ c #C91716", "X$ c #780D0D", "Y$ c #AB1717", "Z$ c #BD1F1F", "`$ c #918F91", " % c #9B4041", ".% c #B6CC4A", "+% c #DBE3B8", "@% c #D8E1A9", "#% c #D4E097", "$% c #CFDF84", "%% c #CADD6F", "&% c #C2D85A", "*% c #BBD346", "=% c #B3CE33", "-% c #A8C712", ";% c #9FC808", ">% c #816003", ",% c #9D010C", "'% c #C01617", ")% c #C61616", "!% c #AB1616", "~% c #BC1E1E", "{% c #838688", "]% c #9D3738", "^% c #BED451", "/% c #EAF0CA", "(% c #E5EEB7", "_% c #DFECA4", ":% c #D8E88F", "<% c #CDDF7A", "[% c #C6DA63", "}% c #BDD54D", "|% c #B6D038", "1% c #A5CE09", "2% c #909105", "3% c #800300", "4% c #B2090C", "5% c #BF1616", "6% c #C61515", "7% c #770C0C", "8% c #A91616", "9% c #A71C1C", "0% c #B80707", "a% c #A9C816", "b% c #ABCE18", "c% c #9EB809", "d% c #7B1900", "e% c #B30C0C", "f% c #BE1515", "g% c #C61414", "h% c #770B0B", "i% c #A81616", "j% c #C21414", "k% c #C20504", "l% c #A30505", "m% c #A7C811", "n% c #ABD018", "o% c #7B3F03", "p% c #830000", "q% c #B20C0C", "r% c #C51414", "s% c #A81515", "t% c #C21313", "u% c #BE0808", "v% c #C00101", "w% c #9C0101", "x% c #AAD112", "y% c #87740D", "z% c #6E0000", "A% c #8D0000", "B% c #970000", "C% c #B10B0B", "D% c #BD1414", "E% c #C51313", "F% c #770A0A", "G% c #A81414", "H% c #C11212", "I% c #BE0707", "J% c #9F0D0D", "K% c #6C1F02", "L% c #770000", "M% c #8C0000", "N% c #C51212", "O% c #A71313", "P% c #C11111", "Q% c #BD0505", "R% c #640200", "S% c #7A0000", "T% c #960000", "U% c #BD1313", "V% c #C41111", "W% c #760909", "X% c #A71212", "Y% c #C11010", "Z% c #660000", "`% c #B10A0A", " & c #BC1313", ".& c #A71111", "+& c #C10E0E", "@& c #BD0404", "#& c #A70000", "$& c #9E0D0D", "%& c #670000", "&& c #8B0000", "*& c #BC1212", "=& c #C41010", "-& c #A71010", ";& c #C00D0D", ">& c #BD0303", ",& c #6B0000", "'& c #790000", ")& c #BC1111", "!& c #C30F0F", "~& c #760808", "{& c #A70F0F", "]& c #C00C0C", "^& c #BD0202", "/& c #9F0E0E", "(& c #590000", "_& c #7C0000", ":& c #B10909", "<& c #BB1111", "[& c #C30E0E", "}& c #A70E0E", "|& c #C00A0A", "1& c #9E0505", "2& c #540404", "3& c #8A0000", "4& c #B00909", "5& c #BB1010", "6& c #760707", "7& c #AA1919", "8& c #C41919", "9& c #C20808", "0& c #C50505", "a& c #C70303", "b& c #C90101", "c& c #A10000", "d& c #420B0B", "e& c #7E0000", "f& c #BB0F0F", "g& c #C20D0D", "h& c #750606", "i& c #010000", "j& c #AA1A1A", "k& c #C51E1E", "l& c #C21616", "m& c #C91515", "n& c #CC1414", "o& c #CE1313", "p& c #D01111", "q& c #D11010", "r& c #D10E0E", "s& c #CE0D0D", "t& c #CB0B0B", "u& c #C60B0B", "v& c #C00909", "w& c #B90808", "x& c #B20707", "y& c #AB0606", "z& c #A60404", "A& c #A10303", "B& c #9E0202", "C& c #9D0101", "D& c #A40101", "E& c #570909", "F& c #900000", "G& c #B00808", "H& c #BA0D0D", "I& c #C10B0B", "J& c #780A0A", "K& c #130E0E", "L& c #C61D1D", "M& c #C31515", "N& c #C71515", "O& c #C91414", "P& c #C81313", "Q& c #BF1111", "R& c #B40F0F", "S& c #AA0E0E", "T& c #A10C0C", "U& c #990909", "V& c #950707", "W& c #930505", "X& c #940404", "Y& c #970202", "Z& c #B20202", "`& c #6A0707", " * c #B10C0C", ".* c #B90C0C", "+* c #B01010", "@* c #A10D0D", "#* c #B70F0F", "$* c #B20606", "%* c #AA0404", "&* c #A20202", "** c #950000", "=* c #A00101", "-* c #990303", ";* c #900404", ">* c #850505", ",* c #790707", "'* c #6C0909", ")* c #600A0A", "!* c #590B0B", "~* c #7A0303", "{* c #CB2727", "]* c #C92222", "^* c #CA1A1A", "/* c #C70606", "(* c #9A0202", "_* c #920404", ":* c #870606", "<* c #7C0707", "[* c #700909", "}* c #620A0A", "|* c #560C0C", "1* c #4A0E0E", "2* c #951717", "3* c #B02B2B", "4* c #9C2828", "5* c #891919", "6* c #770E0E", "7* c #680B0B", "8* c #5A0D0D", "9* c #4C0E0E", "0* c #411010", " ", " . + ", " @ # $ % & * ", " = - ; > , ' ) ! ~ { ] ^ / ( _ : < < ", " [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g g f h i j j j k l m ", " n [ } o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R ", " S [ T U V W X Y Z ` ...+.@.#.$.%.%.&.&.%.*.=.-.;.>.,.'.).!.~.{.= ", " ].^.[ T U /.(._.:.<.6 [.}.|.1.2.$.$.$.$.$.2.=.3.4.5.6.7.8.{ 9.0.= = ", " a.^.[ T U b.c.d.:.e.f.[.g.+.@.h.%.%.h.$.$.2.=.3.4.i.j.k.l.m.n.o.T = ", " p.^.q.} r.s.t.u.:.v.w.x.y.4.z.A.B.C.A D.E.F.G.H.I.J.K.L.8.M.N.O.T = ", " P.Q.q.} R.S.T.U.:.V.W.X.2 Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+= ", " ~+{+]+^+T R./+T.(+:.V.; _+:+<+[+}+|+1+2+3+3+U 4+5+6+7+8+9+} 0+a+b+!+= ", " c+d+e+f+T R./+T.u.:.g+h+i+p <+j+k+j+l+m+n+o+p+q+r+s+t+u+8+v+w+x+y+!+= ", " z+A+B+C+D+c+c+c+E+F+G+H+I+R.S.J+u.:.g+K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @9+.@x+y+!+= ", "+@@@#@$@%@&@*@*@*@=@-@;@>@,@'@)@!@~@:.{@]@^@2 /@(@_@:@<@[@}@|@1@2@3@4@5@w+6@7@8@a+9@!+= ", "0@a@b@c@d@e@-@-@-@=@=@&@f@g@h@i@!@j@:.k@l@i+m@n@}@o@p@q@q@q@p@r@<@s@t@1@2@u@v@w@x@y@= = ", "0@a@b@c@%@&@z@=@-@A@B@C@D@E@F@G@H@j@:.g+I@J@K@L@[@r@p@p@p@p@M@o@}@N@O@P@u@Q@R@x+x@7@9+= ", "0@@@S@c@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#[@r@p@p@p@p@M@o@}@N@O@2@u@Q@R@x+x@8+9+= ", ">#,#'#)#!#`@~#{#{#Z@Z@]#^#/#(#_#:#<#%#[#}#|#1#2#[@r@p@p@p@p@r@<@}@N@1@2@u@Q@3#x+x@8+9+= ", "4#5#6#7#8#]#Z@Z@Z@Z@Z@]#^#/#9#0#a#b#c#d#s.e#f#g#[@r@p@p@p@p@r@<@}@N@h#2@u@v@3#x+x@8+9+= ", "i#j#k#l#m#n#Z@Z@Z@Z@Z@]#^#/#9#o#p#q#r#s#t#u#v#w#[@r@p@p@p@p@r@<@}@t@1@2@3@v@3#x+8@8+9+= ", "x#y#z#A#B#C#D#Z@Z@Z@Z@]#^#/#9#o#E#F#G#H#I#J#K#L#<@r@p@p@p@p@r@<@s@t@1@M#3@v@w@a+8@8+9+= ", "N#O#P#Q#R#S#T#X@Z@Z@Z@]#^#/#9#o#U#V#W#X#Y#Z#`# $<@r@p@p@p@p@o@<@s@t@h#M#3@v@w@a+8@8+9+= ", "c@.$+$@$#$$$%$&$*$Z@Z@]#^#/#9#o#=$-$;$>$,$'$)$!$<@M@p@p@p@M@o@[@s@t@h#M#~$4@w@a+8@8+9+= ", "{$]$^$/$($_$:$<$V@D#Z@]#^#/#9#[$}$|$;$1$2$3$4$5$<@M@p@p@p@M@o@[@s@O@h#M#~$4@w@a+w+8+9+= ", "6$7$8$9$0$a$b$c$d$W@Z@]#^#/#e$f$g$h$i$j$k$l$m$n$<@M@p@p@p@M@o@[@|@O@h#o$~$4@w@x@w+8+9+= ", "p$q$r$s$t$u$v$w$x$y$*$]#^#z$A$B$C$D$%#E$F$G$H$[@<@M@p@p@p@M@o@[@|@O@P@o$~$4@5@x@w+8+9+= ", "I$J$K$L$M$N$O$P$Q$R$c+]#S$T$U$V$W$X$i$Y$Z$`$ %<@<@M@p@p@p@M@o@[@|@O@2@o$Q@R@5@x@w+8+9+= ", ".%+%@%#%$%%%&%*%=%=@-%n#;%>%,%'%)%X$i$!%~%{%]%o@<@M@p@p@p@M@<@[@|@1@P@u@Q@R@5@x@.@8+9+= ", "^%/%(%_%:%<%[%}%|%x$E+1%2%3%4%5%6%7%%#8%|#9%0%}@<@M@p@p@p@M@<@}@N@1@P@u@Q@R@5@8@.@8+9+= ", " a%b%c%d%[ e%f%g%h%%#i%j%k%N@s@<@M@p@p@p@r@<@}@N@1@2@u@Q@3#x+8@.@l%9+= ", " m%n%o%p%I+q%f%r%h%%#s%t%u%v%s@<@M@p@p@p@r@<@}@N@1@2@3@v@3#x+8@0+y+w%= ", " x%y%z%A%B%C%D%E%F%i$G%H%I%v%s@<@M@p@p@p@r@<@}@N@1@2@3@v@3#x+8@0+J%w%= ", " K%L%M%B%C%D%N%F%%#O%P%Q%t@s@<@M@p@p@p@r@<@s@t@h#M#3@v@w@x+8@0+J%w%= ", " R%S%M%T%C%U%V%W%i$X%Y%Q%t@s@o@M@p@p@M@r@<@s@t@h#M#3@v@w@a+w+0+J%w%= ", " Z%S%M%T%`% &V%W%i$.&+&@&t@}@o@M@p@p@M@r@[@s@t@h#M#3@4@w@a+w+#&$&!+= ", " %&S%&&T%`%*&=&W%i$-&;&>&t@}@o@M@p@p@M@o@[@s@t@P@M#~$4@w@a+w+#&J%w%= ", " ,&'&&&T%`%)&!&~&i${&]&^&t@}@o@M@p@p@M@o@[@s@O@P@M#~$4@5@a+w+#&/&w%= ", " (&_&&&T%:&<&[&~&i$}&|&h#t@}@o@M@p@p@M@o@[@|@O@P@o$~$4@5@x@.@#&1&{.} ", " 2&_&3&T%4&5&-#6&i$7&8&]&9&0&a&b&p@p@M@o@}@|@O@h#M#3@v@3#a+w+#&c& @c& ", " d&e&3&T%4&f&g&h&i&j&k&l&6%m&n&o&p&q&r&s&t&u&v&w&x&y&z&A&B&w%!+C&D&0+ ", " E&F&T%G&H&I&J&K&1$L&M&N&O&P&N%Q&R&S&T&U&V&W&X&Y&w%v+7+0+.@w+.@5@Z& ", " `&= *D%.*+*@*#*K#0%$*%*&*} T%**I+{.7@0+w+.@6@=*-*;*>*,*'*)*!* ", " ~*e#{*]*^*/*t@2@~$w@.@`+(*_*:*<*[*}*|*1* ", " 2*3*4*5*6*7*8*9*0* ", " ", " ", " "}; tqsl-2.0/apps/delete_dis.xpm0000664000076400007640000001666012231073120016140 0ustar rmurphyrmurphy/* XPM */ static const char * delete_dis_xpm[] = { "48 48 171 2", " c None", ". c #898989", "+ c #5F5F5F", "@ c #989898", "# c #5C5C5C", "$ c #C3C3C3", "% c #6F6F6F", "& c #575757", "* c #676767", "= c #D7D7D7", "- c #646464", "; c #565656", "> c #B9B9B9", ", c #616161", "' c #5D5D5D", ") c #CCCCCC", "! c #5A5A5A", "~ c #555555", "{ c #A2A2A2", "] c #D8D8D8", "^ c #D0D0D0", "/ c #595959", "( c #C6C6C6", "_ c #DCDCDC", ": c #A7A7A7", "< c #545454", "[ c #9B9B9B", "} c #C5C5C5", "| c #BFBFBF", "1 c #CECECE", "2 c #585858", "3 c #C4C4C4", "4 c #C7C7C7", "5 c #D5D5D5", "6 c #A4A4A4", "7 c #535353", "8 c #949494", "9 c #BDBDBD", "0 c #B7B7B7", "a c #CACACA", "b c #525252", "c c #C2C2C2", "d c #D3D3D3", "e c #A3A3A3", "f c #B5B5B5", "g c #B0B0B0", "h c #515151", "i c #4D4D4D", "j c #505050", "k c #C0C0C0", "l c #A1A1A1", "m c #6E6E6E", "n c #AEAEAE", "o c #A9A9A9", "p c #4B4B4B", "q c #464646", "r c #474747", "s c #4F4F4F", "t c #BCBCBC", "u c #B8B8B8", "v c #E3E3E3", "w c #6A6A6A", "x c #969696", "y c #4C4C4C", "z c #454545", "A c #404040", "B c #3C3C3C", "C c #444444", "D c #B3B3B3", "E c #C8C8C8", "F c #9E9E9E", "G c #9A9A9A", "H c #434343", "I c #3D3D3D", "J c #3B3B3B", "K c #353535", "L c #3A3A3A", "M c #B2B2B2", "N c #ADADAD", "O c #4E4E4E", "P c #ACACAC", "Q c #B1B1B1", "R c #333333", "S c #303030", "T c #929292", "U c #939393", "V c #8E8E8E", "W c #8D8D8D", "X c #AAAAAA", "Y c #A5A5A5", "Z c #A0A0A0", "` c #8C8C8C", " . c #919191", ".. c #888888", "+. c #868686", "@. c #9D9D9D", "#. c #858585", "$. c #909090", "%. c #838383", "&. c #828282", "*. c #808080", "=. c #959595", "-. c #7F7F7F", ";. c #4A4A4A", ">. c #7E7E7E", ",. c #7D7D7D", "'. c #7C7C7C", "). c #818181", "!. c #B4B4B4", "~. c #494949", "{. c #7A7A7A", "]. c #7B7B7B", "^. c #B6B6B6", "/. c #484848", "(. c #777777", "_. c #6B6B6B", ":. c #656565", "<. c #8A8A8A", "[. c #696969", "}. c #5E5E5E", "|. c #8B8B8B", "1. c #6C6C6C", "2. c #626262", "3. c #606060", "4. c #6D6D6D", "5. c #707070", "6. c #636363", "7. c #8F8F8F", "8. c #424242", "9. c #727272", "0. c #686868", "a. c #737373", "b. c #414141", "c. c #767676", "d. c #797979", "e. c #878787", "f. c #0C0C0C", "g. c #717171", "h. c #121212", "i. c #111111", "j. c #101010", "k. c #747474", "l. c #151515", "m. c #1A1A1A", "n. c #282828", "o. c #181818", "p. c #A6A6A6", "q. c #848484", "r. c #1B1B1B", "s. c #2D2D2D", "t. c #2C2C2C", "u. c #191919", "v. c #ABABAB", "w. c #787878", "x. c #1D1D1D", "y. c #1C1C1C", "z. c #1E1E1E", "A. c #232323", "B. c #252525", "C. c #9F9F9F", "D. c #A8A8A8", "E. c #2A2A2A", "F. c #212121", "G. c #313131", "H. c #2E2E2E", "I. c #373737", "J. c #2F2F2F", "K. c #323232", "L. c #3F3F3F", "M. c #363636", "N. c #666666", " ", " ", " ", " ", " ", " ", " . + + @ ", " # $ % & & * = - ", " ; ; > , ; ; ; ; ' ) ! ; ", " ~ ~ { ] ^ / ~ ~ ~ ~ / ( _ : ~ ~ ", " < < [ } | 1 1 2 < < < < 2 3 4 | 5 6 < < ", " 7 7 8 9 0 0 0 a a & 7 7 b 7 & c c 0 0 0 d e 7 7 ", " b b . f g g g g g 3 4 ; b h i j ~ k 9 g g g g g ^ l b b ", " h h m n o o o o o o o | $ 7 i p q r s t u o o o o o o o v w h h ", " j j < x 6 { { { { { { { > | y z z A B C 0 D { { { { { { { 4 E < j j ", " s s 7 x F G G G G G G G D u H I I J K L M N G G G G G G G u $ 7 s s ", " O O b 8 @ 8 8 8 8 8 8 8 P Q L R S R P : 8 8 8 8 8 8 8 o t b O O ", " i i h T U V V V V V V W 6 X K R Y Z ` V V V V V V [ Q h i i ", " i y j .V ............+.@.e Z G #.............$.{ j y i ", " p p O $.. %.%.%.%.%.&.*.x =.-.&.%.%.%.%.T c n O p p ", " ;.;.i V #.-.-.-.-.>.,.'.'.,.>.-.).X | !.U i ;.;. ", " ~.~.y W ).{.{.{.{.{.{.{.].=.^.!.-.' #.y ~.~. ", " /./.p ` >.).-.(.% ].` G ` / ~ , +.p /./. ", " r r ;.=._./ / / / / / / / , ..p r r ", " r q ;...- # # # # # # # # :.. ;.q r ", " z z ~.<.[.+ + + + }.}.+ + + + w |.~.z z ", " C C /.` 1.2.2.2., , 3.3., 2.2.2.2.4.W /.C C ", " H H r W 5.:.:.:.:.:.6.2.2.- :.:.:.:.:.5.7.r H H ", " H 8.q $.9.0.0.0.0.0.* :.1.4.:.* 0.0.0.0.0.a. .q 8.H ", " 8.b.q .c._._._._._.w [.a.*.&.a.[.w _._._._._.c.@ q b.8. ", " b.A z =.d.m m m m m 4.1.c.e.f.f.. (.4.4.m m m m m {.@.z A b. ", " b.A z [ ,.g.g.g.g.g.g.5.].V h.i.j.h. .'.5.g.g.g.g.g.g.>.6 z A b. ", " C A z l ).k.k.k.k.k.k.k.-.x l.m.n.n.o.l.@ *.k.k.k.k.k.k.k.&.: q 8.% ", " z O y p.q.(.(.(.(.(.(.(.%.[ o.r.s. t.u.u.F %.(.(.(.(.(.(.(.#.v.(.%.& ", " q O w.: {.{.{.{.{.{.{.+.Z x.y.t. t.m.z.e e.{.{.{.{.{.{.{.v.V _.j ", " p z . F {.{.{.{.{.e.6 A.z.s. t.x.B.p.e.{.{.{.{.{.C.<.i h ", " A A <.C.{.{.{.e.D.E.F.s. t.F.t.o ..{.{.{.C.<.A A ", " A A <.C.{...o G.B.H. s.B.R X ..{.C.<.A A ", " A A <.X v.I.E.S J.t.L P P <.A A ", " A C (.H S K. R K.~.M p A ", " s ~.L.M. I.N.Y w ", " ;.q A 3.<. ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/delete.xpm0000664000076400007640000002673412231073120015304 0ustar rmurphyrmurphy/* XPM */ static const char * delete_xpm[] = { "48 48 430 2", " c None", ". c #C64D4D", "+ c #B00E0E", "@ c #AF0F0F", "# c #CE6262", "$ c #AC0D0D", "% c #DFA7A7", "& c #B22C2C", "* c #AF0000", "= c #AF2020", "- c #ECC2C2", "; c #AE1B1B", "> c #AC0000", ", c #AC0101", "' c #E5A38E", ") c #B11512", "! c #B00E0B", "~ c #EFBEAA", "{ c #AC0808", "] c #AB0000", "^ c #DC7E68", "/ c #FDB5B4", "( c #F3BAAD", "_ c #AE0604", ": c #F0AE9C", "< c #FDBCBB", "[ c #DE8470", "} c #A90000", "| c #D9765E", "1 c #F89592", "2 c #FC8383", "3 c #FD9F9F", "4 c #F2B8AA", "5 c #AC0604", "6 c #EFAB9A", "7 c #FC9292", "8 c #FBB2B0", "9 c #DC836D", "0 c #A70000", "a c #D56C53", "b c #F48B87", "c c #F47B7B", "d c #F99B9B", "e c #F1B5A4", "f c #AA0604", "g c #A60000", "h c #A40000", "i c #EEA997", "j c #F78F8E", "k c #F9B0AD", "l c #DB816B", "m c #A50000", "n c #D06043", "o c #EF807B", "p c #ED7474", "q c #F49695", "r c #EFB1A0", "s c #A80604", "t c #A20000", "u c #9B0000", "v c #A00000", "w c #A70604", "x c #EDA894", "y c #F28989", "z c #F7ADAA", "A c #D97E69", "B c #A30000", "C c #BD361F", "D c #EC7B70", "E c #E66D6D", "F c #EF9190", "G c #EDAD9A", "H c #A30603", "I c #970000", "J c #8C0000", "K c #8F0000", "L c #9C0603", "M c #EAA48F", "N c #ED8684", "O c #FBCDCB", "P c #BA331B", "Q c #A10000", "R c #A40704", "S c #DD7650", "T c #E26A67", "U c #DF6565", "V c #E98B89", "W c #EAA894", "X c #960603", "Y c #8A0000", "Z c #8B0000", "` c #810000", " . c #790000", ".. c #860603", "+. c #E6A189", "@. c #E7817F", "#. c #F19F9D", "$. c #EEB4A3", "%. c #9F0000", "&. c #A20604", "*. c #DD744F", "=. c #DC6461", "-. c #D85D5D", ";. c #E48582", ">. c #E5A38C", ",. c #830603", "'. c #7A0000", "). c #7B0000", "!. c #760000", "~. c #6B0000", "{. c #710603", "]. c #E09D84", "^. c #E07D7A", "/. c #E88B88", "(. c #ECAD9A", "_. c #9D0000", ":. c #A00604", "<. c #DB734D", "[. c #D85D59", "}. c #D35656", "|. c #DE7D7A", "1. c #DF9D84", "2. c #720603", "3. c #660000", "4. c #610000", "5. c #640603", "6. c #DA997E", "7. c #DA7774", "8. c #D25656", "9. c #E07672", "0. c #EAA58E", "a. c #9A0000", "b. c #9E0604", "c. c #DA724A", "d. c #D45853", "e. c #CF4E4E", "f. c #CE4E4E", "g. c #CC4E4E", "h. c #D67773", "i. c #DA967A", "j. c #670603", "k. c #630603", "l. c #D59376", "m. c #D2736F", "n. c #CB4E4E", "o. c #D76460", "p. c #E5997D", "q. c #990000", "r. c #9C0604", "s. c #DA7149", "t. c #D1514C", "u. c #CB4646", "v. c #CA4646", "w. c #C64646", "x. c #D06F6B", "y. c #D68F70", "z. c #D48D6D", "A. c #CD6D68", "B. c #C54646", "C. c #D2544F", "D. c #DF8665", "E. c #9A0603", "F. c #D97047", "G. c #CF4A44", "H. c #C93E3E", "I. c #C73E3E", "J. c #C23E3E", "K. c #CC6560", "L. c #CB6460", "M. c #C13E3E", "N. c #C63E3E", "O. c #C83E3E", "P. c #D05455", "Q. c #E99D9B", "R. c #E3967A", "S. c #950000", "T. c #980603", "U. c #D86F45", "V. c #CD453E", "W. c #C73737", "X. c #C63737", "Y. c #C43737", "Z. c #C13737", "`. c #C73B3B", " + c #DC797A", ".+ c #E49B9C", "++ c #DC908C", "@+ c #D67A50", "#+ c #920000", "$+ c #930000", "%+ c #D76E43", "&+ c #CB3E37", "*+ c #C53030", "=+ c #C43030", "-+ c #C53232", ";+ c #D25858", ">+ c #E18B8B", ",+ c #DD8B8C", "'+ c #BE4040", ")+ c #AF170C", "!+ c #D16B39", "~+ c #900000", "{+ c #910000", "]+ c #940603", "^+ c #D76D41", "/+ c #CB3931", "(+ c #C93A3A", "_+ c #C73839", ":+ c #C32C2C", "<+ c #BE2121", "[+ c #C33434", "}+ c #CA4F4F", "|+ c #CF6666", "1+ c #C75152", "2+ c #AD0606", "3+ c #B5170D", "4+ c #D26A3B", "5+ c #920603", "6+ c #D77B53", "7+ c #BE1F19", "8+ c #B20000", "9+ c #B9120A", "0+ c #D26C3E", "a+ c #920604", "b+ c #8E0000", "c+ c #8D0000", "d+ c #900604", "e+ c #BF120A", "f+ c #B80000", "g+ c #BF120B", "h+ c #D26D41", "i+ c #8E0604", "j+ c #D36D41", "k+ c #C5170E", "l+ c #BE0000", "m+ c #BD0000", "n+ c #C5180F", "o+ c #D36F43", "p+ c #890000", "q+ c #8C0604", "r+ c #D46F44", "s+ c #CA180F", "t+ c #C40000", "u+ c #C30000", "v+ c #C20000", "w+ c #C10000", "x+ c #CA1810", "y+ c #D47047", "z+ c #870000", "A+ c #8A0604", "B+ c #D01810", "C+ c #CB0000", "D+ c #CA0000", "E+ c #C70000", "F+ c #C50000", "G+ c #C80000", "H+ c #D4714B", "I+ c #860000", "J+ c #850000", "K+ c #880604", "L+ c #D5724B", "M+ c #D51810", "N+ c #D00000", "O+ c #CE0000", "P+ c #CC130D", "Q+ c #CD130D", "R+ c #D51811", "S+ c #D5734E", "T+ c #880605", "U+ c #840000", "V+ c #830000", "W+ c #870605", "X+ c #D6744D", "Y+ c #DB1811", "Z+ c #D60000", "`+ c #D50000", " @ c #D20000", ".@ c #D41912", "+@ c #B17350", "@@ c #B27452", "#@ c #D30000", "$@ c #DB1912", "%@ c #D6795A", "&@ c #870706", "*@ c #820000", "=@ c #850705", "-@ c #D67755", ";@ c #E01912", ">@ c #DC0000", ",@ c #DB0000", "'@ c #D90000", ")@ c #DA1913", "!@ c #B5775A", "~@ c #130605", "{@ c #B6785C", "]@ c #DB1A14", "^@ c #DA0000", "/@ c #E01A15", "(@ c #D67C65", "_@ c #850706", ":@ c #D87B5F", "<@ c #E61A14", "[@ c #E30000", "}@ c #E10000", "|@ c #E11A15", "1@ c #B97B64", "2@ c #1F0606", "3@ c #230000", "4@ c #210000", "5@ c #1E0606", "6@ c #BB7C68", "7@ c #E21B16", "8@ c #E61B17", "9@ c #D88270", "0@ c #7F0D09", "a@ c #EC1B16", "b@ c #E90000", "c@ c #E80000", "d@ c #E81B17", "e@ c #BE7F6E", "f@ c #250606", "g@ c #340000", "h@ c #500000", "i@ c #510000", "j@ c #300000", "k@ c #C08171", "l@ c #E81C18", "m@ c #EC1C19", "n@ c #D98576", "o@ c #850707", "p@ c #820303", "q@ c #A03E3E", "r@ c #7E110C", "s@ c #7B2D21", "t@ c #831E16", "u@ c #DA8473", "v@ c #F11C18", "w@ c #EF0000", "x@ c #EE0000", "y@ c #EE1C18", "z@ c #C48273", "A@ c #2B0606", "B@ c #360000", "C@ c #5A0000", "D@ c #580000", "E@ c #320000", "F@ c #2D0606", "G@ c #C68376", "H@ c #EE1C19", "I@ c #F11C19", "J@ c #DB897C", "K@ c #A54949", "L@ c #AD5959", "M@ c #8F1F1F", "N@ c #7F120D", "O@ c #A25E4F", "P@ c #F2675C", "Q@ c #F50000", "R@ c #F41C19", "S@ c #CA8577", "T@ c #350706", "U@ c #380000", "V@ c #590000", "W@ c #350000", "X@ c #370706", "Y@ c #CC857A", "Z@ c #F41C1A", "`@ c #F46B63", " # c #B96963", ".# c #9D3939", "+# c #8B1515", "@# c #7C251B", "## c #7F0F0B", "$# c #BD5E55", "%# c #F1534B", "&# c #CE867B", "*# c #400807", "=# c #3C0000", "-# c #3A0000", ";# c #440807", "># c #D0877D", ",# c #F51D1A", "'# c #F1544E", ")# c #BD6058", "!# c #891111", "~# c #8C1616", "{# c #BD5F58", "]# c #F1544D", "^# c #D3877E", "/# c #4E0807", "(# c #420000", "_# c #520807", ":# c #D4887E", "<# c #F51D1B", "[# c #D5887E", "}# c #5B0807", "|# c #4B0000", "1# c #5C0000", "2# c #5B0000", "3# c #600807", "4# c #D7887E", "5# c #F26A63", "6# c #D8897F", "7# c #680807", "8# c #550000", "9# c #600000", "0# c #5F0000", "a# c #6D0807", "b# c #D9897F", "c# c #F36C65", "d# c #7F0E0A", "e# c #A0594E", "f# c #741612", "g# c #650000", "h# c #821211", "i# c #E48681", "j# c #8B0B0B", "k# c #793426", "l# c #77251C", "m# c #70130E", "n# c #6C0000", "o# c #6E0000", "p# c #A12B2B", "q# c #E26868", "r# c #AA2B2B", "s# c #7C2319", "t# c #7C1811", "u# c #790908", "v# c #9D2323", "w# c #C84C4C", " ", " ", " ", " ", " ", " ", " . + @ # ", " $ % & * * = - ; ", " > , ' ) > > > > ! ~ { > ", " ] ] ^ / ( _ ] ] ] ] _ : < [ ] ] ", " } } | 1 2 3 4 5 } } } } 5 6 7 2 8 9 } } ", " 0 0 a b c c c d e f 0 g h 0 f i j c c c k l 0 0 ", " m m n o p p p p p q r s h t u v w x y p p p p p z A m m ", " t B C D E E E E E E E F G H u I J K L M N E E E E E E E O P B t ", " Q Q R S T U U U U U U U V W X Y Z ` ...+.@.U U U U U U U #.$.R Q Q ", " %.%.&.*.=.-.-.-.-.-.-.-.;.>.,.'.).!.~.{.].^.-.-.-.-.-.-.-./.(.&.%.%. ", " _._.:.<.[.}.}.}.}.}.}.}.|.1.2.3.4.5.6.7.8.}.}.}.}.}.}.9.0.:._._. ", " a.u b.c.d.e.e.e.e.e.f.g.h.i.j.k.l.m.n.f.e.e.e.e.e.o.p.b.u a. ", " a.q.r.s.t.u.u.u.u.u.v.w.x.y.z.A.B.v.u.u.u.u.u.C.D.r.q.a. ", " I I E.F.G.H.H.H.H.H.I.J.K.L.M.N.O.H.H.H.P.Q.R.E.I I ", " S.S.T.U.V.W.W.W.W.X.Y.Z.Z.Y.X.W.`. +.+++@+T.S.S. ", " #+$+X %+&+*+*+*+*+*+=+=+-+;+>+,+'+)+!+X $+#+ ", " ~+{+]+^+/+(+_+:+<+[+}+|+1+2+] 3+4+]+{+~+ ", " K K 5+6+7+8+8+8+8+8+8+8+8+9+0+a+K K ", " b+c+d+0+e+f+f+f+f+f+f+f+f+g+h+d+c+b+ ", " Z Z i+j+k+l+l+l+l+m+m+l+l+l+l+n+o+i+Z Z ", " p+p+q+r+s+t+t+t+u+v+w+w+u+t+t+t+t+x+y+q+p+p+ ", " z+z+A+y+B+C+C+C+D+D+E+F+F+G+D+C+C+C+C+B+H+A+z+z+ ", " I+J+K+L+M+N+N+N+N+N+O+C+P+Q+C+O+N+N+N+N+N+R+S+T+J+I+ ", " U+V+W+X+Y+Z+Z+Z+Z+Z+`+ @.@+@@@.@#@`+Z+Z+Z+Z+Z+$@%@&@V+U+ ", " *@` =@-@;@>@>@>@>@>@,@'@)@!@~@~@{@]@^@,@>@>@>@>@>@/@(@_@` *@ ", " *@` _@:@<@[@[@[@[@[@[@}@|@1@2@3@4@5@6@7@}@[@[@[@[@[@[@8@9@_@` *@ ", " 0@` _@A a@b@b@b@b@b@b@c@d@e@f@g@h@i@j@f@k@l@c@b@b@b@b@b@b@m@n@o@p@q@ ", " r@s@t@u@v@w@w@w@w@w@w@x@y@z@A@B@C@ D@E@F@G@H@x@w@w@w@w@w@w@I@J@K@L@M@ ", " N@s@O@P@Q@Q@Q@Q@Q@Q@Q@R@S@T@U@V@ D@W@X@Y@Z@Q@Q@Q@Q@Q@Q@Q@`@ #.#+# ", " @###$#%#Q@Q@Q@Q@Q@Z@&#*#=#C@ D@-#;#>#,#Q@Q@Q@Q@Q@'#)#!#~# ", " ` ` {#]#Q@Q@Q@,#^#/#(#C@ V@(#_#:#<#Q@Q@Q@'#)#` ` ", " ` ` )#'#Q@<#[#}#|#1# 2#|#3#4#<#Q@'#)#` ` ", " ` ` )#5#6#7#8#9# 0#D@a#b#c#)#` ` ", " ` d#e#f#4.g# 3.g#h#i#j#` ", " k#l#m#n# o#p#q#r# ", " s#t#u# v#w# ", " ", " ", " ", " ", " ", " "}; tqsl-2.0/apps/crqwiz.h0000664000076400007640000000737012231073120014777 0ustar rmurphyrmurphy/*************************************************************************** crqwiz.h - description ------------------- begin : Sat Jun 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __crqwiz_h #define __crqwiz_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "extwizard.h" #include "wx/radiobox.h" #include "wx/wxhtml.h" #include "certtree.h" #ifndef ADIF_BOOLEAN #define ADIF_BOOLEAN // Hack! #endif #include "tqsllib.h" #include class CRQ_Page; class CRQWiz : public ExtWizard { public: CRQWiz(TQSL_CERT_REQ *crq, tQSL_Cert cert, wxWindow* parent, wxHtmlHelpController *help = 0, const wxString& title = wxT("Request a New Callsign Certificate")); CRQ_Page *GetCurrentPage() { return (CRQ_Page *)wxWizard::GetCurrentPage(); } bool RunWizard(); // ProviderPage data TQSL_PROVIDER provider; // IntroPage data wxString callsign; tQSL_Date qsonotbefore, qsonotafter; int dxcc; // NamePage data wxString name, addr1, addr2, city, state, zip, country; // EmailPage data wxString email; // PasswordPage data wxString password; // SignPage data tQSL_Cert cert; TQSL_CERT_REQ *_crq; private: CRQ_Page *_first; }; class CRQ_Page : public ExtWizard_Page { public: CRQ_Page(CRQWiz* parent = NULL) : ExtWizard_Page(parent) {} CRQWiz *Parent() { return (CRQWiz *)_parent; } }; class CRQ_ProviderPage : public CRQ_Page { public: CRQ_ProviderPage(CRQWiz *parent, TQSL_CERT_REQ *crq = 0); virtual bool TransferDataFromWindow(); private: void DoUpdateInfo(); void UpdateInfo(wxCommandEvent&); std::vector providers; wxComboBox *tc_provider; wxStaticText *tc_provider_info; DECLARE_EVENT_TABLE() }; class CRQ_IntroPage : public CRQ_Page { public: CRQ_IntroPage(CRQWiz *parent, TQSL_CERT_REQ *crq = 0); virtual bool TransferDataFromWindow(); virtual const char *validate(); private: wxTextCtrl *tc_call; wxComboBox *tc_qsobeginy, *tc_qsobeginm, *tc_qsobegind, *tc_dxcc; wxComboBox *tc_qsoendy, *tc_qsoendm, *tc_qsoendd; wxStaticText *tc_status; bool initialized; // Set true when validating makes sense DECLARE_EVENT_TABLE() }; class CRQ_NamePage : public CRQ_Page { public: CRQ_NamePage(CRQWiz *parent, TQSL_CERT_REQ *crq = 0); virtual bool TransferDataFromWindow(); virtual const char *validate(); private: wxTextCtrl *tc_name, *tc_addr1, *tc_addr2, *tc_city, *tc_state, *tc_zip, *tc_country; wxStaticText *tc_status; bool initialized; DECLARE_EVENT_TABLE() }; class CRQ_EmailPage : public CRQ_Page { public: CRQ_EmailPage(CRQWiz *parent, TQSL_CERT_REQ *crq = 0); virtual bool TransferDataFromWindow(); virtual const char *validate(); private: wxTextCtrl *tc_email; wxStaticText *tc_status; bool initialized; DECLARE_EVENT_TABLE() }; class CRQ_PasswordPage : public CRQ_Page { public: CRQ_PasswordPage(CRQWiz *parent); virtual bool TransferDataFromWindow(); virtual const char *validate(); private: wxTextCtrl *tc_pw1, *tc_pw2; wxStaticText *tc_status; bool initialized; DECLARE_EVENT_TABLE() }; class CRQ_SignPage : public CRQ_Page { public: CRQ_SignPage(CRQWiz *parent); virtual bool TransferDataFromWindow(); void CertSelChanged(wxTreeEvent&); virtual const char *validate(); virtual void refresh(); private: wxRadioBox *choice; CertTree *cert_tree; wxStaticText *tc_status; bool initialized; DECLARE_EVENT_TABLE() }; inline bool CRQWiz::RunWizard() { return wxWizard::RunWizard(_first); } #endif // __crqwiz_h tqsl-2.0/apps/crqwiz.cpp0000664000076400007640000010022512231073120015323 0ustar rmurphyrmurphy/*************************************************************************** crqwiz.cpp - description ------------------- begin : Sat Jun 15 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include #include #include "crqwiz.h" #include "dxcc.h" #include "util.h" #include "tqslctrls.h" #include "tqsltrace.h" #include "wx/validate.h" #include "wx/datetime.h" #include "wx/config.h" #include "wx/tokenzr.h" #include "winstrdefs.h" #include #include using namespace std; CRQWiz::CRQWiz(TQSL_CERT_REQ *crq, tQSL_Cert xcert, wxWindow *parent, wxHtmlHelpController *help, const wxString& title) : ExtWizard(parent, help, title), cert(xcert), _crq(crq) { tqslTrace("CRQWiz::CRQWiz", "crq=%lx, xcert=%lx, title=%s", (void *)cert, (void *)xcert, _S(title)); int nprov = 1; tqsl_getNumProviders(&nprov); CRQ_ProviderPage *provider = new CRQ_ProviderPage(this, _crq); CRQ_IntroPage *intro = new CRQ_IntroPage(this, _crq); CRQ_NamePage *name = new CRQ_NamePage(this, _crq); CRQ_EmailPage *email = new CRQ_EmailPage(this, _crq); CRQ_PasswordPage *pw = new CRQ_PasswordPage(this); CRQ_SignPage *sign = new CRQ_SignPage(this); if (nprov != 1) wxWizardPageSimple::Chain(provider, intro); wxWizardPageSimple::Chain(intro, name); wxWizardPageSimple::Chain(name, email); wxWizardPageSimple::Chain(email, pw); if (!cert) wxWizardPageSimple::Chain(pw, sign); if (nprov == 1) _first = intro; else _first = provider; AdjustSize(); CenterOnParent(); } // Page constructors BEGIN_EVENT_TABLE(CRQ_ProviderPage, CRQ_Page) EVT_COMBOBOX(ID_CRQ_PROVIDER, CRQ_ProviderPage::UpdateInfo) END_EVENT_TABLE() static bool prov_cmp(const TQSL_PROVIDER& p1, const TQSL_PROVIDER& p2) { return strcasecmp(p1.organizationName, p2.organizationName) < 0; } CRQ_ProviderPage::CRQ_ProviderPage(CRQWiz *parent, TQSL_CERT_REQ *crq) : CRQ_Page(parent) { tqslTrace("CRQ_ProviderPage::CRQ_ProviderPage", "parent=%lx, crq=%lx", (void *)parent, (void *)crq); wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("M")); int em_h = st->GetSize().GetHeight(); int em_w = st->GetSize().GetWidth(); st->SetLabel(wxT("This will create a new callsign certificate request file.\n\n") wxT("Once you supply the requested information and the\n") wxT("request file has been created, you must send the\n") wxT("request file to the certificate issuer.")); st->SetSize(em_w * 30, em_h * 5); sizer->Add(st, 0, wxALL, 10); sizer->Add(new wxStaticText(this, -1, wxT("Certificate Issuer:")), 0, wxLEFT|wxRIGHT, 10); tc_provider = new wxComboBox(this, ID_CRQ_PROVIDER, wxT(""), wxDefaultPosition, wxDefaultSize, 0, 0, wxCB_DROPDOWN|wxCB_READONLY); sizer->Add(tc_provider, 0, wxLEFT|wxRIGHT|wxEXPAND, 10); tc_provider_info = new wxStaticText(this, ID_CRQ_PROVIDER_INFO, wxT(""), wxDefaultPosition, wxSize(0, em_h*5)); sizer->Add(tc_provider_info, 0, wxALL|wxEXPAND, 10); int nprov = 0; if (tqsl_getNumProviders(&nprov)) wxMessageBox(wxString(tqsl_getErrorString(), wxConvLocal), wxT("Error")); for (int i = 0; i < nprov; i++) { TQSL_PROVIDER prov; if (!tqsl_getProvider(i, &prov)) providers.push_back(prov); } sort(providers.begin(), providers.end(), prov_cmp); int selected = -1; for (int i = 0; i < (int)providers.size(); i++) { tc_provider->Append(wxString(providers[i].organizationName, wxConvLocal), (void *)i); if (crq && !strcmp(providers[i].organizationName, crq->providerName) && !strcmp(providers[i].organizationalUnitName, crq->providerUnit)) { selected = i; } } tc_provider->SetSelection((selected < 0) ? 0 : selected); if (providers.size() < 2 || selected >= 0) tc_provider->Enable(false); DoUpdateInfo(); AdjustPage(sizer, wxT("crq.htm")); } void CRQ_ProviderPage::DoUpdateInfo() { tqslTrace("CRQ_ProviderPage::DoUpdateInfo"); int sel = tc_provider->GetSelection(); if (sel >= 0) { long idx = (long)(tc_provider->GetClientData(sel)); if (idx >=0 && idx < (int)providers.size()) { Parent()->provider = providers[idx]; wxString info; info = wxString(Parent()->provider.organizationName, wxConvLocal); if (Parent()->provider.organizationalUnitName[0] != 0) info += wxString(wxT("\n ")) + wxString(Parent()->provider.organizationalUnitName, wxConvLocal); if (Parent()->provider.emailAddress[0] != 0) info += wxString(wxT("\nEmail: ")) + wxString(Parent()->provider.emailAddress, wxConvLocal); if (Parent()->provider.url[0] != 0) info += wxString(wxT("\nURL: ")) + wxString(Parent()->provider.url, wxConvLocal); tc_provider_info->SetLabel(info); } } } void CRQ_ProviderPage::UpdateInfo(wxCommandEvent&) { tqslTrace("CRQ_ProviderPage::UpdateInfo"); DoUpdateInfo(); } static wxDateTime::Month mons[] = { wxDateTime::Inv_Month, wxDateTime::Jan, wxDateTime::Feb, wxDateTime::Mar, wxDateTime::Apr, wxDateTime::May, wxDateTime::Jun, wxDateTime::Jul, wxDateTime::Aug, wxDateTime::Sep, wxDateTime::Oct, wxDateTime::Nov, wxDateTime::Dec }; BEGIN_EVENT_TABLE(CRQ_IntroPage, CRQ_Page) EVT_TEXT(ID_CRQ_CALL, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_DXCC, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QBYEAR, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QBMONTH, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QBDAY, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QEYEAR, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QEMONTH, CRQ_Page::check_valid) EVT_COMBOBOX(ID_CRQ_QEDAY, CRQ_Page::check_valid) END_EVENT_TABLE() CRQ_IntroPage::CRQ_IntroPage(CRQWiz *parent, TQSL_CERT_REQ *crq) : CRQ_Page(parent) { tqslTrace("CRQ_IntroPage::CRQ_IntroPage", "parent=%lx, crq=%lx", (void *)parent, (void *)crq); initialized = false; wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *dst = new wxStaticText(this, -1, wxT("DXCC entity:")); wxStaticText *st = new wxStaticText(this, -1, wxT("M"), wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE|wxALIGN_RIGHT); int em_h = st->GetSize().GetHeight(); int em_w = st->GetSize().GetWidth(); st->SetLabel(wxT("Call sign:")); st->SetSize(dst->GetSize()); wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(st, 0, wxRIGHT, 5); wxString cs; if (crq && crq->callSign) cs = wxString(crq->callSign, wxConvLocal); tc_call = new wxTextCtrl(this, ID_CRQ_CALL, cs, wxDefaultPosition, wxSize(em_w*15, -1)); hsizer->Add(tc_call, 0, wxEXPAND, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 10); if (crq && crq->callSign) tc_call->Enable(false); hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(dst, 0, wxRIGHT, 5); tc_dxcc = new wxComboBox(this, ID_CRQ_DXCC, wxT(""), wxDefaultPosition, wxSize(em_w*25, -1), 0, 0, wxCB_DROPDOWN|wxCB_READONLY); hsizer->Add(tc_dxcc, 1, 0, 0); sizer->Add(hsizer, 0, wxALL, 10); DXCC dx; bool ok = dx.getFirst(); while (ok) { tc_dxcc->Append(wxString(dx.name(), wxConvLocal), (void *)dx.number()); ok = dx.getNext(); } const char *ent = "NONE"; if (crq) { if (dx.getByEntity(crq->dxccEntity)) { ent = dx.name(); tc_dxcc->Enable(false); } } int i = tc_dxcc->FindString(wxString(ent, wxConvLocal)); if (i >= 0) tc_dxcc->SetSelection(i); struct { wxComboBox **cb; int id; } boxes[][3] = { { {&tc_qsobeginy, ID_CRQ_QBYEAR}, {&tc_qsobeginm, ID_CRQ_QBMONTH}, {&tc_qsobegind,ID_CRQ_QBDAY} }, { {&tc_qsoendy, ID_CRQ_QEYEAR}, {&tc_qsoendm, ID_CRQ_QEMONTH}, {&tc_qsoendd,ID_CRQ_QEDAY} } }; const char *labels[] = { "QSO begin date:", "QSO end date:" }; int year = wxDateTime::GetCurrentYear(); int sels[2][3]; int dates[2][3]; if (crq) { dates[0][0] = crq->qsoNotBefore.year; dates[0][1] = crq->qsoNotBefore.month; dates[0][2] = crq->qsoNotBefore.day; dates[1][0] = crq->qsoNotAfter.year; dates[1][1] = crq->qsoNotAfter.month; dates[1][2] = crq->qsoNotAfter.day; } for (int i = 0; i < int(sizeof labels / sizeof labels[0]); i++) { sels[i][0] = sels[i][1] = sels[i][2] = 0; sizer->Add(new wxStaticText(this, -1, wxString(labels[i], wxConvLocal)), 0, wxBOTTOM, 5); hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("Y")), 0, wxLEFT, 20); *(boxes[i][0].cb) = new wxComboBox(this, boxes[i][0].id, wxT(""), wxDefaultPosition, wxSize(em_w*8, -1), 0, 0, wxCB_DROPDOWN|wxCB_READONLY); hsizer->Add(*(boxes[i][0].cb), 0, wxLEFT, 5); hsizer->Add(new wxStaticText(this, -1, wxT("M")), 0, wxLEFT, 10); *(boxes[i][1].cb) = new wxComboBox(this, boxes[i][1].id, wxT(""), wxDefaultPosition, wxSize(em_w*5, -1), 0, 0, wxCB_DROPDOWN|wxCB_READONLY); hsizer->Add(*(boxes[i][1].cb), 0, wxLEFT, 5); hsizer->Add(new wxStaticText(this, -1, wxT("D")), 0, wxLEFT, 10); *(boxes[i][2].cb) = new wxComboBox(this, boxes[i][2].id, wxT(""), wxDefaultPosition, wxSize(em_w*5, -1), 0, 0, wxCB_DROPDOWN|wxCB_READONLY); hsizer->Add(*(boxes[i][2].cb), 0, wxLEFT, 5); int iofst = 0; if (i > 0) { iofst++; for (int j = 0; j < 3; j++) (*(boxes[i][j].cb))->Append(wxT("")); } for (int j = 1945; j <= year; j++) { wxString s; s.Printf(wxT("%d"), j); if (crq && dates[i][0] == j) sels[i][0] = j - 1945 + iofst; (*(boxes[i][0].cb))->Append(s); } year++; for (int j = 1; j <= 12; j++) { wxString s; s.Printf(wxT("%d"), j); if (crq && dates[i][1] == j) sels[i][1] = j - 1 + iofst; (*(boxes[i][1].cb))->Append(s); } for (int j = 1; j <= 31; j++) { wxString s; s.Printf(wxT("%d"), j); if (crq && dates[i][2] == j) sels[i][2] = j - 1 + iofst; (*(boxes[i][2].cb))->Append(s); } sizer->Add(hsizer, 0, wxLEFT|wxRIGHT, 10); } if (crq) { tc_qsobeginy->SetSelection(sels[0][0]); tc_qsobeginm->SetSelection(sels[0][1]); tc_qsobegind->SetSelection(sels[0][2]); wxDateTime now = wxDateTime::Now(); wxDateTime qsoEnd(crq->qsoNotAfter.day, mons[crq->qsoNotAfter.month], crq->qsoNotAfter.year, 23, 59, 59); if (qsoEnd < now) { // Looks like this is a cert for an expired call sign, // so keep the QSO end date as-is. Otherwise, leave it // blank so CA can fill it in. tc_qsoendy->SetSelection(sels[1][0]); tc_qsoendm->SetSelection(sels[1][1]); tc_qsoendd->SetSelection(sels[1][2]); } } else { tc_qsobeginy->SetSelection(0); tc_qsobeginm->SetSelection(10); // November 1945 tc_qsobegind->SetSelection(0); } tc_status = new wxStaticText(this, -1, wxT(""), wxDefaultPosition, wxSize(em_w*35, em_h*4)); sizer->Add(tc_status, 0, wxALL|wxEXPAND, 10); AdjustPage(sizer, wxT("crq0.htm")); initialized = true; } BEGIN_EVENT_TABLE(CRQ_NamePage, CRQ_Page) EVT_TEXT(ID_CRQ_NAME, CRQ_Page::check_valid) EVT_TEXT(ID_CRQ_ADDR1, CRQ_Page::check_valid) EVT_TEXT(ID_CRQ_CITY, CRQ_Page::check_valid) END_EVENT_TABLE() CRQ_NamePage::CRQ_NamePage(CRQWiz *parent, TQSL_CERT_REQ *crq) : CRQ_Page(parent) { tqslTrace("CRQ_NamePage::CRQ_NamePage", "parent=%lx, crq=%lx", (void *)parent, (void *)crq); initialized = false; wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *zst = new wxStaticText(this, -1, wxT("Zip/Postal")); wxStaticText *st = new wxStaticText(this, -1, wxT("M"), wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE|wxALIGN_RIGHT); int em_w = st->GetSize().GetWidth(); int def_w = em_w * 20; st->SetLabel(wxT("Name")); st->SetSize(zst->GetSize()); wxConfig *config = (wxConfig *)wxConfig::Get(); wxString val; wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(st, 0, wxRIGHT, 5); wxString s; if (crq && crq->name) s = wxString(crq->name, wxConvLocal); else if (config->Read(wxT("Name"), &val)) s = val; tc_name = new wxTextCtrl(this, ID_CRQ_NAME, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_name, 1, 0, 0); sizer->Add(hsizer, 0, wxALL, 10); tc_name->SetMaxLength(TQSL_CRQ_NAME_MAX); s = wxT(""); if (crq && crq->address1) s = wxString(crq->address1, wxConvLocal); else if (config->Read(wxT("Addr1"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("Address"), wxDefaultPosition, zst->GetSize(), wxST_NO_AUTORESIZE|wxALIGN_RIGHT), 0, wxRIGHT, 5); tc_addr1 = new wxTextCtrl(this, ID_CRQ_ADDR1, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_addr1, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_addr1->SetMaxLength(TQSL_CRQ_ADDR_MAX); s = wxT(""); if (crq && crq->address2) s = wxString(crq->address2, wxConvLocal); else if (config->Read(wxT("Addr2"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT(""), wxDefaultPosition, zst->GetSize(), wxST_NO_AUTORESIZE|wxALIGN_RIGHT), 0, wxRIGHT, 5); tc_addr2 = new wxTextCtrl(this, ID_CRQ_ADDR2, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_addr2, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_addr2->SetMaxLength(TQSL_CRQ_ADDR_MAX); s = wxT(""); if (crq && crq->city) s = wxString(crq->city, wxConvLocal); else if (config->Read(wxT("City"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("City"), wxDefaultPosition, zst->GetSize(), wxST_NO_AUTORESIZE|wxALIGN_RIGHT), 0, wxRIGHT, 5); tc_city = new wxTextCtrl(this, ID_CRQ_CITY, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_city, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_city->SetMaxLength(TQSL_CRQ_CITY_MAX); s = wxT(""); if (crq && crq->state) s = wxString(crq->state, wxConvLocal); else if (config->Read(wxT("State"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("State"), wxDefaultPosition, zst->GetSize(), wxST_NO_AUTORESIZE|wxALIGN_RIGHT), 0, wxRIGHT, 5); tc_state = new wxTextCtrl(this, ID_CRQ_STATE, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_state, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_state->SetMaxLength(TQSL_CRQ_STATE_MAX); s = wxT(""); if (crq && crq->postalCode) s = wxString(crq->postalCode, wxConvLocal); else if (config->Read(wxT("ZIP"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(zst, 0, wxRIGHT, 5); tc_zip = new wxTextCtrl(this, ID_CRQ_ZIP, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_zip, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_zip->SetMaxLength(TQSL_CRQ_POSTAL_MAX); s = wxT(""); if (crq && crq->country) s = wxString(crq->country, wxConvLocal); else if (config->Read(wxT("Country"), &val)) s = val; hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT("Country"), wxDefaultPosition, zst->GetSize(), wxST_NO_AUTORESIZE|wxALIGN_RIGHT), 0, wxRIGHT, 5); tc_country = new wxTextCtrl(this, ID_CRQ_COUNTRY, s, wxDefaultPosition, wxSize(def_w, -1)); hsizer->Add(tc_country, 1, 0, 0); sizer->Add(hsizer, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_country->SetMaxLength(TQSL_CRQ_COUNTRY_MAX); tc_status = new wxStaticText(this, -1, wxT("")); sizer->Add(tc_status, 0, wxALL|wxEXPAND, 10); AdjustPage(sizer, wxT("crq1.htm")); initialized = true; } BEGIN_EVENT_TABLE(CRQ_EmailPage, CRQ_Page) EVT_TEXT(ID_CRQ_EMAIL, CRQ_Page::check_valid) END_EVENT_TABLE() CRQ_EmailPage::CRQ_EmailPage(CRQWiz *parent, TQSL_CERT_REQ *crq) : CRQ_Page(parent) { tqslTrace("CRQ_EmailPage::CRQ_EmailPage", "parent=%lx, crq=%lx", (void *)parent, (void *)crq); initialized = false; wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("M")); int em_w = st->GetSize().GetWidth(); st->SetLabel(wxT("Your e-mail address")); wxConfig *config = (wxConfig *)wxConfig::Get(); wxString val; wxString s; if (crq && crq->emailAddress) s = wxString(crq->emailAddress, wxConvLocal); else if (config->Read(wxT("Email"), &val)) s = val; sizer->Add(st, 0, wxLEFT|wxRIGHT|wxTOP, 10); tc_email = new wxTextCtrl(this, ID_CRQ_EMAIL, s, wxDefaultPosition, wxSize(em_w*30, -1)); sizer->Add(tc_email, 0, wxLEFT|wxRIGHT|wxBOTTOM, 10); tc_email->SetMaxLength(TQSL_CRQ_EMAIL_MAX); sizer->Add(new wxStaticText(this, -1, wxT("Note: The e-mail address you provide here is the\n") wxT("address to which the issued certificate will be sent.\n") wxT("Make sure it's the correct address!\n")), 0, wxALL, 10); tc_status = new wxStaticText(this, -1, wxT("")); sizer->Add(tc_status, 0, wxALL|wxEXPAND, 10); AdjustPage(sizer, wxT("crq2.htm")); initialized = true; } BEGIN_EVENT_TABLE(CRQ_PasswordPage, CRQ_Page) EVT_TEXT(ID_CRQ_PW1, CRQ_Page::check_valid) EVT_TEXT(ID_CRQ_PW2, CRQ_Page::check_valid) END_EVENT_TABLE() CRQ_PasswordPage::CRQ_PasswordPage(CRQWiz *parent) : CRQ_Page(parent) { tqslTrace("CRQ_PasswordPage::CRQ_PasswordPage", "parent=%lx", (void *)parent); initialized = false; wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxStaticText *st = new wxStaticText(this, -1, wxT("M")); int em_w = st->GetSize().GetWidth(); int em_h = st->GetSize().GetHeight(); st->SetLabel( wxT("You may protect this callsign certificate using a password.\n") wxT("If you are using a computer system that is shared with\n") wxT("others, you should specify a password to protect this\n") wxT("callsign certificate. However, if you are using a computer\n") wxT("in a private residence, no password need be specified.\n\n") wxT("Leave the password blank and click 'Next' unless you want to\n") wxT("use a password.\n\n") wxT("Password:") ); st->SetSize(em_w * 30, em_h * 5); sizer->Add(st, 0, wxLEFT|wxRIGHT|wxTOP, 10); tc_pw1 = new wxTextCtrl(this, ID_CRQ_PW1, wxT(""), wxDefaultPosition, wxSize(em_w*20, -1), wxTE_PASSWORD); sizer->Add(tc_pw1, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("Enter the password again for verification:")), 0, wxLEFT|wxRIGHT|wxTOP, 10); tc_pw2 = new wxTextCtrl(this, ID_CRQ_PW2, wxT(""), wxDefaultPosition, wxSize(em_w*20, -1), wxTE_PASSWORD); sizer->Add(tc_pw2, 0, wxLEFT|wxRIGHT, 10); sizer->Add(new wxStaticText(this, -1, wxT("DO NOT lose the password you choose!\n") wxT("You will be unable to use the certificate\nwithout this password!")), 0, wxALL, 10); tc_status = new wxStaticText(this, -1, wxT("")); sizer->Add(tc_status, 0, wxALL|wxEXPAND, 10); AdjustPage(sizer, wxT("crq3.htm")); initialized = true; } BEGIN_EVENT_TABLE(CRQ_SignPage, CRQ_Page) EVT_TREE_SEL_CHANGED(ID_CRQ_CERT, CRQ_SignPage::CertSelChanged) EVT_RADIOBOX(ID_CRQ_SIGN, CRQ_Page::check_valid) END_EVENT_TABLE() void CRQ_SignPage::CertSelChanged(wxTreeEvent& event) { tqslTrace("CRQ_SignPage::CertSelChanged"); if (cert_tree->GetItemData(event.GetItem())) choice->SetSelection(1); wxCommandEvent dummy; check_valid(dummy); } CRQ_SignPage::CRQ_SignPage(CRQWiz *parent) : CRQ_Page(parent) { tqslTrace("CRQ_SignPage::CRQ_SignPage", "parent=%lx", (void *)parent); initialized = false; wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(new wxStaticText(this, -1, wxT("If the requested certificate is for your personal callsign, then you\n" "should select 'Signed' and choose a callsign certificate for another of\n" "your personal callsigns from the list below to be used to sign this request.\n\n" "If you don't have a Callsign Certificate for another personal callsign, or\n" "if the requested Callsign Certificate is for a club station or for use by a\n" "QSL manager on behalf of another operator, select 'Unsigned'."))); wxStaticText* text_sizer = new wxStaticText(this, -1, wxT("M")); int em_h = text_sizer->GetSize().GetHeight(); int em_w = text_sizer->GetSize().GetWidth(); text_sizer->Show(false); tc_status = new wxStaticText(this, -1, wxT(""), wxDefaultPosition, wxSize(em_w*35, em_h*3)); wxString choices[] = { wxT("Unsigned"), wxT("Signed") }; choice = new wxRadioBox(this, ID_CRQ_SIGN, wxT("Sign Request"), wxDefaultPosition, wxSize(em_w*30, -1), 2, choices, 1, wxRA_SPECIFY_COLS); sizer->Add(choice, 0, wxALL|wxEXPAND, 10); cert_tree = new CertTree(this, ID_CRQ_CERT, wxDefaultPosition, wxSize(em_w*30, em_h*10), wxTR_HAS_BUTTONS | wxSUNKEN_BORDER); sizer->Add(cert_tree, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND); cert_tree->SetBackgroundColour(wxColour(255, 255, 255)); sizer->Add(tc_status, 0, wxALL|wxEXPAND, 10); // Default to 'signed' unless there's no valid certificates to use for signing. if (cert_tree->GetNumCerts() == 0) { choice->SetSelection(0); } else { choice->SetSelection(1); } AdjustPage(sizer, wxT("crq4.htm")); initialized = true; } void CRQ_SignPage::refresh() { tqslTrace("CRQ_SignPage::refresh"); if (cert_tree->Build(0, &(Parent()->provider)) > 0) choice->SetSelection(1); else choice->SetSelection(0); } // Page validation bool CRQ_ProviderPage::TransferDataFromWindow() { // Nothing to validate return true; } const char * CRQ_IntroPage::validate() { tqslTrace("CRQ_IntroPage::validate"); if (!initialized) return 0; wxString val = tc_call->GetValue(); bool ok = true; int sel; wxString msg(wxT("You must enter a valid call sign.")); static wxCharBuffer msg_buf(1); if (val.Len() < 3) ok = false; if (ok) { bool havealpha = false, havenumeric = false; const wxWX2MBbuf tmp_buf = val.mb_str(); const char *cp = (const char *)tmp_buf; while (ok && *cp) { char c = toupper(*cp++); if (isalpha(c)) havealpha = true; else if (isdigit(c)) havenumeric = true; else if (c != '/') ok = false; } ok = (ok && havealpha && havenumeric); } if (!ok) goto notok; sel = tc_dxcc->GetSelection(); if (sel >= 0) Parent()->dxcc = (long)(tc_dxcc->GetClientData(sel)); if (sel < 0 || Parent()->dxcc < 0) { msg = wxT("You must select a DXCC entity."); ok = false; goto notok; } Parent()->qsonotbefore.year = strtol(tc_qsobeginy->GetStringSelection().mb_str(), NULL, 10); Parent()->qsonotbefore.month = strtol(tc_qsobeginm->GetStringSelection().mb_str(), NULL, 10); Parent()->qsonotbefore.day = strtol(tc_qsobegind->GetStringSelection().mb_str(), NULL, 10); Parent()->qsonotafter.year = strtol(tc_qsoendy->GetStringSelection().mb_str(), NULL, 10); Parent()->qsonotafter.month = strtol(tc_qsoendm->GetStringSelection().mb_str(), NULL, 10); Parent()->qsonotafter.day = strtol(tc_qsoendd->GetStringSelection().mb_str(), NULL, 10); if (!tqsl_isDateValid(&Parent()->qsonotbefore)) { msg = wxT("QSO begin date: You must choose proper values for\nYear, Month and Day."); ok = false; } else if (!tqsl_isDateNull(&Parent()->qsonotafter) && !tqsl_isDateValid(&Parent()->qsonotafter)) { msg = wxT("QSO end date: You must either choose proper values\nfor Year, Month and Day or leave all three blank."); ok = false; } else if (tqsl_isDateValid(&Parent()->qsonotafter) && tqsl_compareDates(&Parent()->qsonotbefore, &Parent()->qsonotafter) > 0) { msg = wxT("QSO end date cannot be before QSO begin date."); ok = false; } if (!ok) goto notok; // Data looks okay, now let's make sure this isn't a duplicate request // (unless it's a renewal). if (!Parent()->_crq) { val.MakeUpper(); tQSL_Cert *certlist = 0; int ncert = 0; tqsl_selectCertificates(&certlist, &ncert, val.mb_str(), Parent()->dxcc, 0, &(Parent()->provider), TQSL_SELECT_CERT_WITHKEYS); //cerr << "ncert: " << ncert << endl; if (ncert > 0) { char cert_before_buf[40], cert_after_buf[40]; for (int i = 0; i < ncert; i++) { // See if this cert overlaps the user-specified date range tQSL_Date cert_not_before, cert_not_after; int cert_dxcc = 0; tqsl_getCertificateQSONotBeforeDate(certlist[i], &cert_not_before); tqsl_getCertificateQSONotAfterDate(certlist[i], &cert_not_after); tqsl_getCertificateDXCCEntity(certlist[i], &cert_dxcc); //cerr << "dxcc: " << cert_dxcc << endl; if (cert_dxcc == Parent()->dxcc && ((tqsl_isDateValid(&Parent()->qsonotafter) && !(tqsl_compareDates(&Parent()->qsonotbefore, &cert_not_after) == 1 || tqsl_compareDates(&Parent()->qsonotafter, &cert_not_before) == -1)) || (!tqsl_isDateValid(&Parent()->qsonotafter) && !(tqsl_compareDates(&Parent()->qsonotbefore, &cert_not_after) == 1)) )) { ok = false; // Overlap! tqsl_convertDateToText(&cert_not_before, cert_before_buf, sizeof cert_before_buf); tqsl_convertDateToText(&cert_not_after, cert_after_buf, sizeof cert_after_buf); } tqsl_freeCertificate(certlist[i]); } if (ok == false) { DXCC dxcc; dxcc.getByEntity(Parent()->dxcc); msg = wxString::Format(wxT("You have an overlapping certificate for %s (DXCC=%hs) having QSO dates: "), val.c_str(), dxcc.name()); msg += wxString(cert_before_buf, wxConvLocal) + wxT(" to ") + wxString(cert_after_buf, wxConvLocal); } } wxString pending = wxConfig::Get()->Read(wxT("RequestPending")); wxStringTokenizer tkz(pending, wxT(",")); while (tkz.HasMoreTokens()) { wxString pend = tkz.GetNextToken(); if (pend == val) { msg = wxString::Format(wxT("There is an outstanding certificate request for %s\n") wxT("Please wait until this is processed by LoTW or delete\n") wxT("the certificate request."), val.c_str()); ok = false; } } } notok: if (!ok) { tc_status->SetLabel(msg); msg_buf = msg.mb_str(); return (const char *)msg_buf; } tc_status->SetLabel(wxT("")); return 0; } bool CRQ_IntroPage::TransferDataFromWindow() { tqslTrace("CRQ_IntroPage::TransferDataFromWindow"); if (validate()) // Should only happen when going Back return true; if (Parent()->dxcc == 0) wxMessageBox( wxT("You have selected DXCC Entity NONE\n\n") wxT("QSO records signed using the certificate will not\n") wxT("be valid for DXCC award credit (but will be valid \n") wxT("for other applicable awards). If the certificate is\n") wxT("to be used for signing QSOs from maritime/marine\n") wxT("mobile, shipboard, or air mobile operations, that is\n") wxT("the correct selection. Otherwise, you probably\n") wxT("should use the \"Back\" button to return to the DXCC\n") wxT("page after clicking \"OK\""), wxT("TQSL Warning")); if (!tqsl_isDateNull(&Parent()->qsonotafter) && tqsl_isDateValid(&Parent()->qsonotafter)) { if (wxMessageBox( wxT("You have chosen a QSO end date for this Callsign Certificate. ") wxT("The 'QSO end date' should ONLY be set if that date is the date when that callsign's license ") wxT("expired or the license was replaced by a new callsign.\n\n") wxT("If you set an end date, you will not be able to sign ") wxT("QSOs past that date, even if the callsign certificate ") wxT("itself is still valid.\n\n") wxT("If you still hold this callsign (or if you plan to renew the license for the ") wxT("callsign), you should not set a 'QSO end date'.\n") wxT("Do you really want to keep this 'QSO end date'?"), wxT("Warning"), wxYES_NO|wxICON_EXCLAMATION) == wxNO) { tc_qsoendy->SetSelection(0); tc_qsoendm->SetSelection(0); tc_qsoendd->SetSelection(0); return false; } } Parent()->callsign = tc_call->GetValue(); Parent()->callsign.MakeUpper(); tc_call->SetValue(Parent()->callsign); return true; } static bool cleanString(wxString &str) { str.Trim(); str.Trim(FALSE); int idx; while ((idx = str.Find(wxT(" "))) > 0) { str.Remove(idx, 1); } return str.IsEmpty(); } const char * CRQ_NamePage::validate() { tqslTrace("CRQ_NamePage::validate()"); if (!initialized) return 0; Parent()->name = tc_name->GetValue(); Parent()->addr1 = tc_addr1->GetValue(); Parent()->city = tc_city->GetValue(); const char *errmsg = 0; if (cleanString(Parent()->name)) errmsg = "You must enter your name"; if (!errmsg && cleanString(Parent()->addr1)) errmsg = "You must enter your address"; if (!errmsg && cleanString(Parent()->city)) errmsg = "You must enter your city"; tc_status->SetLabel(errmsg ? wxString(errmsg, wxConvLocal) : wxT("")); return errmsg; } bool CRQ_NamePage::TransferDataFromWindow() { tqslTrace("CRQ_NamePage::TransferDataFromWindow"); Parent()->name = tc_name->GetValue(); Parent()->addr1 = tc_addr1->GetValue(); Parent()->addr2 = tc_addr2->GetValue(); Parent()->city = tc_city->GetValue(); Parent()->state = tc_state->GetValue(); Parent()->zip = tc_zip->GetValue(); Parent()->country = tc_country->GetValue(); if (validate()) return true; cleanString(Parent()->name); cleanString(Parent()->addr1); cleanString(Parent()->addr2); cleanString(Parent()->city); cleanString(Parent()->state); cleanString(Parent()->zip); cleanString(Parent()->country); tc_name->SetValue(Parent()->name); tc_addr1->SetValue(Parent()->addr1); tc_addr2->SetValue(Parent()->addr2); tc_city->SetValue(Parent()->city); tc_state->SetValue(Parent()->state); tc_zip->SetValue(Parent()->zip); tc_country->SetValue(Parent()->country); wxConfig *config = (wxConfig *)wxConfig::Get(); config->Write(wxT("Name"), Parent()->name); config->Write(wxT("Addr1"), Parent()->addr1); config->Write(wxT("Addr2"), Parent()->addr2); config->Write(wxT("City"), Parent()->city); config->Write(wxT("State"), Parent()->state); config->Write(wxT("ZIP"), Parent()->zip); config->Write(wxT("Country"), Parent()->country); return true; } const char * CRQ_EmailPage::validate() { tqslTrace("CRQ_EmailPage::validate()"); const char *errmsg = 0; if (!initialized) return 0; Parent()->email = tc_email->GetValue(); cleanString(Parent()->email); int i = Parent()->email.First('@'); int j = Parent()->email.Last('.'); if (i < 1 || j < i+2 || j == (int)Parent()->email.length()-1) errmsg = "You must enter a valid email address"; tc_status->SetLabel(errmsg ? wxString(errmsg, wxConvLocal) : wxT("")); return errmsg; } bool CRQ_EmailPage::TransferDataFromWindow() { tqslTrace("CRQ_EmailPage::TransferDataFromWindow"); if (validate()) return true; Parent()->email = tc_email->GetValue(); cleanString(Parent()->email); wxConfig *config = (wxConfig *)wxConfig::Get(); config->Write(wxT("Email"), Parent()->email); return true; } const char * CRQ_PasswordPage::validate() { tqslTrace("CRQ_PasswordPage::validate"); const char *errmsg = 0; if (!initialized) return 0; wxString pw1 = tc_pw1->GetValue(); wxString pw2 = tc_pw2->GetValue(); if (pw1 != pw2) errmsg = "The two copies of the password do not match."; tc_status->SetLabel(errmsg ? wxString(errmsg, wxConvLocal) : wxT("")); return errmsg; } bool CRQ_PasswordPage::TransferDataFromWindow() { tqslTrace("CRQ_PasswordPage::TransferDataFromWindow"); if (validate()) return true; Parent()->password = tc_pw1->GetValue(); return true; } const char * CRQ_SignPage::validate() { tqslTrace("CRQ_SignPage::validate"); const char *errmsg = 0; if (!initialized) return 0; wxString nextprompt=wxT("Click 'Finish' to complete this callsign certificate request."); cert_tree->Enable(choice->GetSelection()==0?false:true); if (choice->GetSelection()==0 && Parent()->dxcc == 0) errmsg = "This request MUST be signed since DXCC Entity is set to NONE"; if (choice->GetSelection()==1) { if (!cert_tree->GetSelection().IsOk() || cert_tree->GetItemData(cert_tree->GetSelection())==NULL) { errmsg = "Please select a callsign certificate to sign your request"; } else { char callsign[512]; tQSL_Cert cert = cert_tree->GetItemData(cert_tree->GetSelection())->getCert(); if (0==tqsl_getCertificateCallSign(cert, callsign, sizeof callsign)) { nextprompt+=wxString::Format(wxT("\n\nYou are saying that the requested certificate for %s\n") wxT("belongs to the same person as %hs and are using\n") wxT("the selected certificate to prove %hs's identity."), Parent()->callsign.c_str(), callsign, callsign); } } } tc_status->SetLabel(errmsg ? wxString(errmsg, wxConvLocal) : nextprompt); return errmsg; } bool CRQ_SignPage::TransferDataFromWindow() { tqslTrace("CRQ_SignPage::TransferDataFromWindow"); if (validate()) return true; Parent()->cert = 0; if (choice->GetSelection() == 0) { if (cert_tree->GetNumCerts() > 0) { int rval = wxMessageBox( wxT("You have one or more callsign certificates that could be used\n") wxT("to sign this certificate request.\n\n") wxT("It is strongly recommended that you sign the request\n") wxT("unless the callsign certificates shown are not actually yours.\n") /*wxT("Certificate issuers may choose not to permit unsigned\n") wxT("certificate requests from existing certificate holders.\n\n") */ wxT("Do you want to sign the certificate request?\n") wxT("Select \"Yes\" to sign the request, \"No\" to continue without signing."), wxT("Warning"), wxYES_NO, this); if (rval == wxYES) return false; } } else { CertTreeItemData *data = (CertTreeItemData *)cert_tree->GetItemData(cert_tree->GetSelection()); if (data) Parent()->cert = data->getCert(); } return true; } tqsl-2.0/apps/certtree.h0000664000076400007640000000310612231073120015266 0ustar rmurphyrmurphy/*************************************************************************** certtree.h - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #ifndef __certtree_h #define __certtree_h #ifdef HAVE_CONFIG_H #include "sysconfig.h" #endif #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include "wx/wx.h" #endif #include "tqsllib.h" #include "wx/treectrl.h" class CertTreeItemData : public wxTreeItemData { public: CertTreeItemData(tQSL_Cert cert) : _cert(cert) {} ~CertTreeItemData(); tQSL_Cert getCert() { return _cert; } private: tQSL_Cert _cert; }; class CertTree : public wxTreeCtrl { public: CertTree(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); virtual ~CertTree(); int Build(int flags = TQSL_SELECT_CERT_WITHKEYS, const TQSL_PROVIDER *provider = 0); void OnItemActivated(wxTreeEvent& event); void OnRightDown(wxMouseEvent& event); bool useContextMenu; CertTreeItemData *GetItemData(wxTreeItemId id) { return (CertTreeItemData *)wxTreeCtrl::GetItemData(id); } int GetNumCerts() const { return _ncerts; } int GetNumIssuers() const { return _nissuers; } void SelectCert(tQSL_Cert cert); private: int _ncerts; int _nissuers; DECLARE_EVENT_TABLE() }; #endif // __certtree_h tqsl-2.0/apps/certtree.cpp0000664000076400007640000001445412231073120015631 0ustar rmurphyrmurphy/*************************************************************************** certtree.cpp - description ------------------- begin : Sun Jun 23 2002 copyright : (C) 2002 by ARRL author : Jon Bloom email : jbloom@arrl.org revision : $Id$ ***************************************************************************/ #include "certtree.h" #include #include #include #include "tqslctrls.h" #include "util.h" #include "dxcc.h" #include "tqslerrno.h" #include "tqsltrace.h" #include #include #include using namespace std; #include "cert.xpm" #include "nocert.xpm" #include "broken-cert.xpm" #include "folder.xpm" #include "expired.xpm" #include "replaced.xpm" enum { CERT_ICON = 0, NOCERT_ICON = 1, BROKEN_ICON = 2, EXPIRED_ICON = 3, REPLACED_ICON = 4, FOLDER_ICON = 5 }; ///////////// Certificate Tree Control //////////////// BEGIN_EVENT_TABLE(CertTree, wxTreeCtrl) EVT_TREE_ITEM_ACTIVATED(-1, CertTree::OnItemActivated) EVT_RIGHT_DOWN(CertTree::OnRightDown) END_EVENT_TABLE() CertTree::CertTree(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxTreeCtrl(parent, id, pos, size, style), _ncerts(0) { tqslTrace("CertTree::CertTree"); useContextMenu = true; wxBitmap certbm(cert_xpm); wxBitmap no_certbm(nocert_xpm); wxBitmap broken_certbm(broken_cert_xpm); wxBitmap folderbm(folder_xpm); wxBitmap expiredbm(expired_xpm); wxBitmap replacedbm(replaced_xpm); wxImageList *il = new wxImageList(16, 16, false, 5); il->Add(certbm); il->Add(no_certbm); il->Add(broken_certbm); il->Add(expiredbm); il->Add(replacedbm); il->Add(folderbm); SetImageList(il); } CertTree::~CertTree() { tqslTrace("CertTree::~CertTree"); } CertTreeItemData::~CertTreeItemData() { tqslTrace("CertTreeItemData::~CertTreeItemData"); if (_cert) tqsl_freeCertificate(_cert); } typedef pair certitem; typedef vector certlist; static bool cl_cmp(const certitem& i1, const certitem& i2) { return i1.first < i2.first; } int CertTree::Build(int flags, const TQSL_PROVIDER *provider) { tqslTrace("CertTree::Build", "flags=%d, provider=%lx", flags, (void *)provider); typedef map issmap; issmap issuers; DeleteAllItems(); wxTreeItemId rootId = AddRoot(wxT("tQSL Certificates"), FOLDER_ICON); tQSL_Cert *certs; if (tqsl_selectCertificates(&certs, &_ncerts, 0, 0, 0, provider, flags)) { if (tQSL_Error != TQSL_SYSTEM_ERROR || tQSL_Errno != ENOENT) displayTQSLError("Error while accessing certificate store"); return _ncerts; } // Separate certs into lists by issuer for (int i = 0; i < _ncerts; i++) { char issname[129]; if (tqsl_getCertificateIssuerOrganization(certs[i], issname, sizeof issname)) { displayTQSLError("Error parsing certificate for issuer"); return _ncerts; } char callsign[129] = ""; if (tqsl_getCertificateCallSign(certs[i], callsign, sizeof callsign - 4)) { displayTQSLError("Error parsing certificate for call sign"); return _ncerts; } strncat(callsign, " - ", sizeof callsign - strlen(callsign)-1); DXCC dxcc; int dxccEntity; if (tqsl_getCertificateDXCCEntity(certs[i], &dxccEntity)) { displayTQSLError("Error parsing certificate for DXCC entity"); return _ncerts; } const char *entityName; if (dxcc.getByEntity(dxccEntity)) entityName = dxcc.name(); else entityName = ""; strncat(callsign, entityName, sizeof callsign - strlen(callsign)-1); callsign[sizeof callsign-1] = 0; issuers[wxString(issname, wxConvLocal)].push_back(make_pair(wxString(callsign, wxConvLocal),i)); } // Sort each issuer's list and add items to tree issmap::iterator iss_it; wxTreeItemId id; _nissuers = issuers.size(); for (iss_it = issuers.begin(); iss_it != issuers.end(); iss_it++) { if (_nissuers > 1) { id = AppendItem(rootId, iss_it->first, FOLDER_ICON); } certlist& list = iss_it->second; sort(list.begin(), list.end(), cl_cmp); for (int i = 0; i < (int)list.size(); i++) { CertTreeItemData *cert = new CertTreeItemData(certs[list[i].second]); int keyonly = 1; int exp = 0, sup = 0; int icon_type; int keytype = tqsl_getCertificatePrivateKeyType(certs[list[i].second]); tqsl_isCertificateExpired(certs[list[i].second], &exp); tqsl_isCertificateSuperceded(certs[list[i].second], &sup); tqsl_getCertificateKeyOnly(certs[list[i].second], &keyonly); if (keytype == TQSL_PK_TYPE_ERR) icon_type = BROKEN_ICON; else if (keyonly) icon_type = NOCERT_ICON; else if (sup) icon_type = REPLACED_ICON; else if (exp) icon_type = EXPIRED_ICON; else icon_type = CERT_ICON; AppendItem(_nissuers > 1 ? id : rootId, list[i].first, icon_type, -1, cert); } if (id) Expand(id); } Expand(rootId); return _ncerts; } void CertTree::SelectCert(tQSL_Cert cert) { long serial; if (tqsl_getCertificateSerial(cert, &serial)) return; // Iterate the tree, looking for a matching certificate wxTreeItemId root = GetRootItem(); wxTreeItemIdValue issCookie; wxTreeItemIdValue certCookie; wxTreeItemId top; if (_nissuers > 1) { top = GetFirstChild(root, issCookie); } else { top = root; } while (top.IsOk()) { wxTreeItemId item = GetFirstChild(top, certCookie); while (item.IsOk()) { tQSL_Cert cert = GetItemData(item)->getCert(); long s; tqsl_getCertificateSerial(cert, &s); if (s == serial) { // found it SelectItem(item); return; } item = GetNextChild(top, certCookie); } if (_nissuers > 1) { top = GetNextChild(root, issCookie); } else { break; } } return; // Not found } void CertTree::OnItemActivated(wxTreeEvent& event) { tqslTrace("CertTree::OnItemActivated"); wxTreeItemId id = event.GetItem(); displayCertProperties((CertTreeItemData *)GetItemData(id), this); } void CertTree::OnRightDown(wxMouseEvent& event) { tqslTrace("CertTree::OnRightDown"); if (!useContextMenu) return; wxTreeItemId id = HitTest(event.GetPosition()); if (id && GetItemData(id)) { SelectItem(id); tQSL_Cert cert = GetItemData(id)->getCert(); int keyonly = 1; if (cert) tqsl_getCertificateKeyOnly(cert, &keyonly); wxMenu *cm = makeCertificateMenu(true, (keyonly != 0)); PopupMenu(cm, event.GetPosition()); delete cm; } } tqsl-2.0/apps/cert.xpm0000664000076400007640000000117012231073120014762 0ustar rmurphyrmurphy/* XPM */ static const char * cert_xpm[] = { "16 16 17 1", " c None", ". c #616112", "+ c #7B7B4E", "@ c #999991", "# c #D4D402", "$ c #ABABAA", "% c #A9A902", "& c #C1C1C1", "* c #CFCFCF", "= c #D7D7D7", "- c #E0E002", "; c #818105", "> c #DEDEDE", ", c #FDFDFD", "' c #979702", ") c #F7F702", "! c #BBBB02", ",,,,,,,=*>,,,,,,", ",,,,,+;%!%;@,,,,", ",,,=+)%;;;!#+,,,", ",,,;-;#-%)!;)+,,", ",,@-'-#;#.)!!%=,", ",,+););))-%);-@,", ",,@)')'))#%)'#$,", ",,&!'-).;;)!!'>,", ",,,+-;#)))!;#@,,", ",,,,+%%;';!'@,,,", ",,,,,$'%%%.*,,,,", ",,,,,@#';;#$,,,,", ",,,,,+!#;'-+,,,,", ",,,,&!');#%#$,,,", ",,,,+%.;.;.!+,,,", ",,,,=&>*>*>*>,,,"}; tqsl-2.0/apps/broken-cert.xpm0000664000076400007640000000135012231073120016240 0ustar rmurphyrmurphy/* XPM */ static const char * broken_cert_xpm[] = { "16 16 17 1", " c #FDFDFDFDFDFD", ". c #D7D7D7D7D7D7", "X c #FFFFFFFFFFFF", "o c #DEDEDEDEDEDE", "O c #7B7B7B7B4E4E", "+ c #818181810505", "@ c #A9A9A9A90202", "# c #999999999191", "$ c #F7F7F7F70202", "% c #BBBBBBBB0202", "& c #D4D4D4D40202", "* c #E0E0E0E00202", "= c #979797970202", "- c #616161611212", "; c #ABABABABAAAA", ": c #C1C1C1C1C1C1", "> c #CFCFCFCFCFCF", " .Xo ", " O+XX@+# ", " .O$@X++%&O ", " +*+XX@$%+$O ", " #*=XX+&-$%%@. ", " O$+XXX$*@$+*# ", " #$=$=XXX@$=&; ", " :%=*$-+XX%%=o ", " O*+&$XXX+&# ", " O@@XX+%=# ", " ;XX@@-> ", " #&XX+&; ", " O%&XX*O ", " :%=$+X@&; ", " O@-+-X-%O ", " .:o>o>o>o "}; tqsl-2.0/apps/bottom.xpm0000664000076400007640000000116712231073120015337 0ustar rmurphyrmurphy/* XPM */ static const char *bottom_xpm[]={ "10 10 29 1", ". c None", "d c #000000", "h c #020202", "y c #050505", "k c #070707", "v c #0d0d0d", "n c #111111", "s c #171617", "p c #212021", "c c #323132", "g c #474647", "x c #595859", "j c #5d5b5d", "u c #696869", "m c #727172", "r c #797779", "# c #8a888a", "o c #8b898b", "e c #939193", "b c #9e9b9e", "a c #9f9d9f", "A c #a6a4a6", "z c #adabad", "f c #aeabae", "w c #b7b4b7", "i c #bab7ba", "t c #bdbabd", "l c #c1bec1", "q c #c3c0c3", "d.......#.", "d.....bcd.", "d...fghdd.", "d.ijkdddd.", "dmndddddd.", "dopdddddd.", "d.qrsdddd.", "d...tuvdd.", "d.....wxy.", "d.......z."}; tqsl-2.0/apps/TrustedQSL.spec.in0000664000076400007640000000207312231073120016575 0ustar rmurphyrmurphySummary: TrustedQSL ham-radio applications Name: TrustedQSL Version: @VERSION@ Release: 1 Copyright: Custom BSD-like Group: Applications/Ham Radio Source: %{name}-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-buildroot Requires: tqsllib >= 2.3, wxwin BuildPrereq: tqsllib-devel %description The TrustedQSL applications are used for generating digitally signed QSO records (records of Amateur Radio contacts). This package contains the GUI application tqsl. %prep %setup -q -n TrustedQSL-%{version} %build cmake -DCMAKE_INSTALL_PREFIX=/usr ${TQSL_CONFIG_OPTS} . make %install rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install mkdir -p $RPM_BUILD_ROOT/usr/share/applications cp tqsl.desktop $RPM_BUILD_ROOT/usr/share/applications/TrustedQSL-tqsl.desktop mkdir -p $RPM_BUILD_ROOT/usr/share/pixmaps cp icons/key48.png $RPM_BUILD_ROOT/usr/share/pixmaps/TrustedQSL.png %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc LICENSE /usr/bin/tqsl /usr/share/TrustedQSL/help/tqslapp /usr/share/applications/TrustedQSL-tqsl.desktop /usr/share/pixmaps/TrustedQSL.png tqsl-2.0/apps/LICENSE.rtf0000664000076400007640000000546412231073120015110 0ustar rmurphyrmurphy{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Times New Roman;}} {\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\qc\lang1033\f0\fs22 License Terms and Conditions\par \par Copyright (C) 2001-2003 American Radio Relay League, Inc. All rights\par reserved.\par \par Portions (C) 2013 The TrustedQSL Developers\par \par Redistribution and use in source and binary forms, with or without\par modification, are permitted provided that the following conditions\par are met:\par \par 1. Any redistribution of source code must retain the above copyright\par notice, this list of conditions and the disclaimer shown in\par Paragraph 5 (below).\par \par 2. Redistribution in binary form must reproduce the above copyright\par notice, this list of conditions and the disclaimer shown in\par Paragraph 5 (below) in the documentation and/or other materials\par provided with the distribution.\par \par 3. Products derived from or including this software may not use\par "Logbook of the World" or "LoTW" or any other American Radio Relay\par League, Incorporated trademarks or servicemarks in their names\par without prior written permission of the ARRL. See Paragraph 6\par (below) for contact information.\par \par 4. Use of this software does not imply endorsement by ARRL of\par products derived from or including this software and vendors may not\par claim such endorsement. \par \par 5. Disclaimer: This software is provided "as-is" without\par representation, guarantee or warranty of any kind, either express or\par implied, including but not limited to the implied warranties of\par merchantability or of fitness for a particular purpose. The entire\par risk as to the quality and performance of the software is solely\par with you. Should the software prove defective, you (and not the\par American Radio Relay League, its officers, directors, employees or\par agents) assume the entire cost of all necessary servicing, repair or\par correction. In no event will ARRL be liable to you or to any third\par party for any damages, whether direct or indirect, including lost\par profits, lost savings, or other incidental or consequential damages\par arising out of the use or inability to use such software, regardless\par of whether ARRL has been advised of the possibility of such damages.\par \par 6. Contact information:\par \par American Radio Relay League, Inc.\par Attn: Logbook of the World Manager\par 225 Main St\par Newington, CT 06111\par voice: 860-594-0200\par fax: 860-594-0259\par email: logbook@arrl.org\par Worldwide Web: www.arrl.org\par \par This software consists of voluntary contributions made by many\par individuals on behalf of the ARRL. More information on the "Logbook\par of The World" project and the ARRL is available from the ARRL Web\par site at www.arrl.org.\par \par } tqsl-2.0/apps/ChangeLog.txt0000664000076400007640000004526412231073120015703 0ustar rmurphyrmurphyTQSL/TQSLCERT changes ===================== 2.0 ---------- Major feature Additions: Merge tqslcert into tqsl. Update the UI to be more user friendly. For the Callsign Certificaates tree display, don't display the certificate provider list if there's only one provider. Allow users to back up and restore their TQSL configuration in a portable file. Automatically back up the configuration to a user-specified directory (or to a default one) unless this is disabled. Add diagnostic logging capability. This is used to store a verbose log from cURL and to write a trace log that can be used by the developers to help determine the source of defects. Display unique icons in the certificate tree to allow expired and superseded certificates can be distinguished. Detect and report invalid frequencies in ADIF files (outside of ham bands, entered in KHz versus MHz.) Validate the format of Grid Squares when they're entered for a station location. This also fixes the case to be normal, upper case for the Field, lower case for the subsquare (FM18ju, for example). Other changes: Correct the defect that could cause invalid QSOs (bad call signs, for example) to result in a cancellation message from an attempt to sign the log but not provide detail on what QSO failed. Automatically back up the user's configuration whenever TQSL closes. Display the versions of the major software packages built into TQSL as part of the "Help/About" text. Don't ask the user to choose the file type for certificate load operations, just provide a file open dialog and allow them to choose. When issuing a callsign certificate request, default to "signed" unless there are no usable certificates to be used to sign the request. Add text to the dialog box explaining when unsigned requests should be used. Remove the initial "Certificate Providers" page from the certificate request wizard as it serves no current purpose. Always display all callsign certificates, including expired and superseded certficates. Use consistent terminology throughout - "Callsign Certificate" and "Station Location". Replace atoi() calls with strtol() to correct parsing of strings like '012' so they are not treated as octal. Enforce frequency entry in the ADIF editor, ensuring that frequencies are entered correctly (in MHz) and within an amateur band. Reject frequencies that are not consistent with the BAND setting. Correct the exit code for circumstances when -a abort is used and an bad QSO is detected. Display the error information on that QSO before exiting. Detect new verions of the TQSL configuration file when performing the "check for updates" operation (manual or automatic) and allow the user to update the configuration file if there is a newer one available. Add new command line options "-b" to select the start date for QSOs to be signed (begin) and "-e" to select the end date for QSOs to be signed. Warn users on startup when they have a certificate that's going to expire soon (in less than 60 days). Back up certificate details (address, entity) when backing up as .p12 file. Change title of certificate request window to reflect new or renewed certificate. Add the ability to automatically upload a certificate request. Make the preferences window a top-level window so it doesn't block activity in the help screen, etc. Delete obsolete mode maps when signing a log. When creating a station location, default to the callsign selected on the locations tree if one is selected. Add a button to the Log Operations window that opens the Logbook of the world website. Add a new command line option, -n, which checks for new versions of critical TQSL files then exits. This is designed for use by logging programs that operate TQSL on behalf of the user. Add network proxy preference settings to allow users to use the TQSL network based functions on networks that require all traffic to use a proxy. Grab window focus when prompting for the certificate password to ensure that the password window appears on top of the calling logger. Simplify the messages displayed on certificate import (relegate the details to the diagnostic log). Detect additional cURL errors and translate them into more user-friendly text. Don't use "Private Key" in certificate load error messages - use certificate request. Provide the callsign associated with certificate loading errors. Display detailed error on certificate import errors. Display system error reason when attempts to update the TrustedQSL configuration file fail. Track multiple pending certificate requests and warn the user when they try to ask for a new or renewed certificate for callsigns where requests are already pending. Fix pathname separators so Windows always uses "\" for folder/directory names, not mixed forward and backward slashes. Add more information to signing progress display including processed, error, and duplicate counts. Recover from invalid ADIF files by ignoring invalid data until the next EOR (end of record) field is seen. Add working directory string to diagnostic log. Update documentation to reference differences for Mac OS X menus. Delete pending log file when signing cancelled. Fix crash when location entity data is missing. Display the DXCC entity name in location properties, not the entity number. Correct Grid Square parsing to allow 'a' and 'z' in subsquare fields. Update documentation to reference Mac OS X GUI fields and menu layout. Move Diagnostic Mode menu to File menu - the OS X Help menu doesn't allow checked items. Correct other instances of DXCC entity number being used in user messages to emit entity name, not the number. Generate an error message on startup when stale mode maps are in place. Don't allow a user to redefine a standard mode. When the user chooses to not ignore errors in a log, don't save or upload it. Fix the way user dialog boxes (for things like date range, passwords, and requests for how to handle errors) get instantiated so that the windows can appear on top of logging programs using command line log signing. Attempt to determine the field containing the call-worked data in unknown Cabrillo contests without requiring the user to define a custom contest. Update the "Ignore Errors" dialog to have "Ignore" and "Cancel" options and to describe what each of those does. Correct batch/quiet mode (-q or -x command line options) to avoid unexpected windows from popping up before a dialog (password, errors, date range, etc.) Always print out the TQSL version number at the beginning of output for command line applications. Use new application icons contributed by K1GQ. Correct regression where duplicate QSOs would result in an action prompt even though "-a abort" was specified on the command line. Don't display the TQSL version number when "-n" is used on the command line. Strip leading and trailing spaces from the location name passed on the command line. Properly handle and report upload errors displayed by the LoTW website. Install TQSL icon when "make install" used on Linux. Make the new icons optional. Correct the suppression of the TQSL version number when "-n" is used on the commmand line. Report errors when critical files cannot be opened (station data, certificates, etc.) Correct the behavior when the user selects a callsign or a location in the station location pane then clicks "Create new station location". The callsign selected was used in the location setup, but the DXCC entity was not properly selected. Only display the DXCC entity once in the station location page. This fixes the display when there are multiple callsign certificates for a given callsign (one valid and one expired, for example). This defect would cause TQSL to show a pulldown menu with multiple copies of the same entity name. Suppress warning messages when the user has no locations defined or callsign certificates installed as this is normal for an initial setup. When "Sign and Save" or "Sign and Upload" are used, first check if the user has any callsign certificates installed. The former behavior would ask for the input and output files, then try to select a station location. Since there are none, offering to create a station location would then fail. Trim extra spaces from station location fields. These could cause signing to fail as LoTW was removing these but TQSL was not. Update TQSL to provide the current LoTW configuration file (v2.5) Correct error messages on version update website failures, so that it's clear that it was the check that failed, not the download. Increase the version check timeout slightly to limit premature check failures. When performing the automatic update check at startup, wait for the main GUI window to appear. Provide a status message in the window until the update check completes. This keeps TQSL from appearing to hang at startup if the update check is slow. Correct command line behavior to not pop up a window when invoked then close that window. Fix duplicate handling error introduced at RC6. 1.14.3 ------ On Windows, use a newer verions of libcurl that doesn't suffer from the defect fixed by http://support.microsoft.com/kb/975858. This defect causes an error message "schannel: failed to setup extended errors". On all platforms: show some additional libraries' versions in the about screen Correct a defect when tqsl is used as a command line tool to sign a user's log for their logging program. If while signing that log, tqsl detected that a newer version of tqsl was available, it would exit without signing or uploading those QSOs. 1.14.2 ------ Fixed an error when the TrustedQSL directory had Unicode characters, don't prompt for updates when called silently, fail properly when the user chooses to not ignore signing errors 1.14.1 ------ Minor bug fixes to internet functions and the command line parser, hang fixed on OSX, removed unnecessary field from upload 1.14 ---- Major feature additions: - Upload log files directly from TrustedQSL! Simply choose "sign and upload" from the File menu and your log will signed and uploaded automatically with no extra work. - Command line flag '-u' has been added to expose this functionality to tools authors. - The return value from tqsl can be used to determine whether the signing or upload succeeded or failed, and why 0=success; log signed and uploaded and accepted without incident 1=Cancelled by user 2=The log was rejected by the LoTW server 3=The response from the LoTW server was unexpected or unrecognized 4=An error occurred in tqsl 5=An error occurred in tqsllib (probably a bad filename) 6=Unable to open input file 7=Unable to open output file 8=All QSOs were duplicate or out of date range (no QSOs written) 9=Some QSOs were duplicate or out of date range (some QSOs written) 10=Command syntax error 11=LoTW network connection failed (no network or LoTW is unreachable) The exit status is also written to Standard Error (stderr) in an easily recognized format. - Automatically check for updates. If a new version is available, you will be periodically prompted to download and install it. You can also check manually - Duplicate checking. Any QSOs that have been successfully uploaded to Logbook of the World or saved to a file are registered in a database. Any exact duplicates are automatically stripped from future logs. This can be disabled on a case-by-case basis, in case a log was signed but never uploaded, or there was a server issue that led to an upload going unprocessed. - TQSL will now ensure that the CQ and ITU zones, and subdivisions if any (US state/county, Canadian province, Russian oblast) are valid with respect to each other. This should reduce the incidence of swapped CQ/ITU zones and in general should help ensure that more accurate location data is uploaded. When an attempt is made to use a location with errors (such as CQ/ITU zones being reversed) the user is notified to correct the errors. - Installer on Windows is now a Microsoft Windows Installer package, instead of an executable. This will allow for easier and cleaner upgrades - Added a new command line option, '-a', to allow command line users to control user interaction. This option takes a value from the set ask, abort, compliant, or all. For '-a ask', TQSL will ask users how to handle duplicates and date mismatches. '-a abort' will cause signing to terminate immediately when an error occurs. '-a compliant' will cause only correct (new or in date range) records to be output, and '-a all' will cause all of the input records (including duplicates) to be signed. Prompts for errors (date ranges bad, bad callsigns) will be suppressed for '-a compliant' or '-a all', but cause immediate aborts when '-a abort' is used. '-a ask' prompts the user in those cases. Minor changes: - TQSL/TQSLCERT now have window icons - Double-clicking an entry in the "Choose station location" window for signing now selects it, instead of opening it for editing - Command line parsing has been rewritten and should be more robust. Also, command-line documentation is available with '-h' - Files to sign and save are now prompted before location and date range - The build number is now shown in the About box; please include this when asking for help - The final confirmation before signing includes the signing station location - Output files on Unix systems are provided with a default .tq8 extension - The "Edit station location" window title now contains the callsign and station location name - Station locations can no longer be defined using expired or superceded certificates - Users are no longer prompted for a password while importing a .p12 file unless the file has a password set - When importing a certificate, detailed information is provided on the progress of the operation as well as the reason for any errors - Dozens of bug fixes and potential or real crashes fixed. TQSL/TQSLCERT and the rest of TrustedQSL now built with the CMake build system TQSL/TQSLCERT are now built with MSVC on Windows. ** Windows 98 support has been dropped. This will be one of the last releases to support Windows 2000. ** This will be one of the last releases to support OS X on PowerPC systems. 1.13 ---- No functional changes. Update to sync to updated tqsllib; updated build tools. 1.12 ---- When asking for the password to unlock a private key, say what callsign it's for. Remember certificate requests and assist the user with importing the .tq6. Prompt user to save their certificate after importing a .tq6 signed certificate. Suppress display of superseded certificates, controlled by a tqslcert preference setting. Fix windows wxWidgets crashes with several wizards (cert renew, new cert, etc.) Add checkbox to allow bypassing state selection. Fix crash on Windows when new certificate request wizard is started. Added support for validating zone numbers and requiring them. Allowed batch mode (-x) without displaying windows When double-clicking an entry on the "Edit Station Locations" dialog, open that entry for edit, don't just close the modal dialog. Change the "OK" button on the "Edit Station Locations" dialog to "Close" as that's what it does. Update password dialogs to enable "enter" to activate when possible. Add "-p " and "-o " arguments to tqsl. 1.11 ---- Added command-line option -d. (See on-line help for details.) Modified string handling to be compatible with Unicode versions of wxWindows/wxWidgets. Certificate request wizard now checks for date overlap of request with existing certificates. This allows non-overlapping requests to be generated. (TQSLCERT) Help-contents file tags now contain "type" parameter so that packages built with wxWindows >= 2.4 will show the help contents properly. 1.10 ---- Added command-line parameters and help page for same. (TQSL) Windows build now links the expat library statically, eliminating the need for libexpat.dll. (TQSL/TQSLCERT) 1.09 ---- ADIF editor now handles seconds in the TIME_ON field. (TQSL) User now gets chance to re-enter failed password during signing. (TQSL) Expanded explanation of QSO date-range dialog during signing. (TQSL) After loading new configuration data, DXCC list in CRQ wizard was hosed. (TQSLCERT) 1.08 ---- Added start-up warning if beta-test certificates are present. (TQSLCERT) Added version ident to outgoing .tq8 file. (TQSL) Added display of certificate info to getPassword dialog. (TQSL) 1.07 ---- Fixed GetPassword bug that kept the password from being accepted when trying to unlock the key during Certificate/Save. (TQSLCERT) 1.06 ---- Added support for new QSO data fields (propagation, satellite, rx band and rx freq. (TQSL) Added support for DXCC=NONE. (TQSLCERT) 1.05 ---- Now using TQSLLIB V1.2 Added QSO Date Range dialog. (TQSL) 1.04 ---- "Delete" button in Preferences/ADIF_Modes wasn't getting enabled (Windows only). (TQSL) Assertion error when adding Cabrillo mode to empty list in Preferences/Cabrillo_Specs (Windows only). (TQSL) Completed help files. 1.03 ---- Changed File menu items to be more descriptive (TQSL) Added optional call-sign format checking during signing. (TQSL) Added user-editable table of Cabrillo CONTEST specifications. (TQSL) Improved error reporting during log signing. (TQSL) Errors in log caused signing to be noncancellable. (TQSL) After signing error, same output file couldn't be reused. (TQSL) Added user data pointer to tqsllib callback functions. (TQSLLIB) Added PKCS#12 import and export. (TQSLLIB) Refactored wizard code for more consistent display. (TQSLCERT/TQSL) Added Certificate/Save and Certificate/Delete and added PKCS#12 support to File/Load_Certificate_File. (TQSLCERT) Added broken-certificate indicator to certificate list. (TQSLCERT) Improved error trapping and reporting in certificate-request wizard (TQSLCERT) 1.02 ---- TQSL now gives the user the option of ignoring errors that occur during signing. Errors are still reported, however. Fixed ADIF parser zero-length-field problem. (TQSLLIB) Fixed certificate request wizard State field focus problem. (TQSLCERT) Added "Edit Locations" command to Station menu. (TQSL) Fixed mishandling of ITU zone and CQ zone data in station location. (TQSLLIB) Improved MODE handling in both TQSL and TQSLLIB. There is now a table of mode aliases that can be added to by the user, allowing the user to map nonstandard ADIF MODE values to ones acceptable to TQSL. This is applied both during File/Sign and File/Open operations. Fixed Cabrillo converter typo in ARRL-VHF-JAN contest. (TQSLLIB) 1.01 ---- Fixed error-return value when certificate not found during signing. (TQSLLIB) Fixed certificate selection criteria during signing and add station location. (Was allowing use of certificates not yet loaded.) Added ADIF frequency-to-band conversion. (TQSLLIB) tqsl-2.0/apps/CMakeLists.txt0000664000076400007640000001156312231073120016046 0ustar rmurphyrmurphyproject(tqsl) set(OSX_ARCH i386 CACHE STRING "Architectures to build for OSX") string(REPLACE " " ";" CMAKE_OSX_ARCHITECTURES ${OSX_ARCH}) if(WIN32) set(wxWidgets_USE_STATIC ON) add_definitions(-DCURL_STATICLIB) add_definitions(-DXML_STATIC) endif() find_package(CURL REQUIRED) find_package(EXPAT REQUIRED) find_package(wxWidgets COMPONENTS core base adv html REQUIRED) find_package(ZLIB REQUIRED) include(${wxWidgets_USE_FILE}) if(APPLE) find_library(CARBON_LIBRARY Carbon) find_path(CARBON_INCLUDE_DIR Carbon.h) endif() include_directories(${tqsllib_SOURCE_DIR} ${ZLIB_INCLUDE_DIR} ${EXPAT_INCLUDE_DIR} ${CURL_INCLUDE_DIR} ${CARBON_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${BDB_INCLUDE_DIR}) #get version from file file(STRINGS "tqslversion.ver" TQSLVERSION) string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\1" TQSL_VERSION_MAJOR TQSLVERSION) string(REGEX REPLACE "([0-9]+)\\.([0-9]+)" "\\2" TQSL_VERSION_MINOR TQSLVERSION) #get build # with git find_program(GIT_PROG git "C:\\Program Files (x86)\\Git\\bin" "C:\\Program Files\\Git\\bin") if(GIT_PROG) #we can use git execute_process(COMMAND ${GIT_PROG} describe RESULT_VARIABLE GITERROR ERROR_QUIET OUTPUT_VARIABLE HEAD_COMMIT OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT GITERROR) #git ran alright set(BUILD ${HEAD_COMMIT}) else() # Git error - hope this is a source distro if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h BUILDSTR REGEX "\\[.*\\]") string(REGEX REPLACE ".*\\[(.*)\\].*" "\\1" BUILD ${BUILDSTR}) endif() endif() else() # No git, again grab from source if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h BUILDSTR REGEX "\\[.*\\]") string(REGEX REPLACE ".*\\[(.*)\\].*" "\\1" BUILD ${BUILDSTR}) endif() endif() # If BUILD is set (we have a version) and BUILDSTR is not (we got that build from # git), then write a tqslbuild.h. Else leave it alone. if(BUILD AND NOT BUILDSTR) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h") else() #hope this is a source distribution, which will always include a correct tqslbuild if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h") #but otherwise someone downloaded a snapshot without a buildfile set(BUILD "unknown") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/tqslbuild.h") endif() endif() set(TQSL_VERSION_MAJOR 2) set(TQSL_VERSION_MINOR 0) set(TQSLVERSION "${TQSL_VERSION_MAJOR}.${TQSL_VERSION_MINOR}") if(WIN32) set(TQSLLIB_NAME tqsllib2) set(srcdir ${CMAKE_CURRENT_SOURCE_DIR}) set(TQSL_RCFILE "tqsl.rc") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TQSL_RCFILE}.in" "${CMAKE_CURRENT_SOURCE_DIR}/${TQSL_RCFILE}") else() set(TQSLLIB_NAME tqsllib) endif() if(APPLE) set(OSX_ICONFILE "tqslicons.icns") set(MACOSX_BUNDLE_INFO_STRING "tqsl") set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.arrl.tqsl") set(MACOSX_BUNDLE_LONG_VERSION_STRING "TQSL V ${TQSLVERSION} build ${BUILD}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${TQSLVERSION}") set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2001-2013 American Radio Relay League") set(MACOSX_BUNDLE_ICON_FILE ${OSX_ICONFILE}) SET_SOURCE_FILES_PROPERTIES(${OSX_ICONFILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) set(TQSL_RCFILE ${OSX_ICONFILE}) endif() if(NOT WIN32) #rpath setup SET(CMAKE_SKIP_BUILD_RPATH FALSE) SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif() set(TQSL_SRC tqsl.cpp extwizard.cpp tqslwiz.cpp dxcc.cpp stationdial.cpp qsodatadialog.cpp tqslvalidator.cpp tqsl_prefs.cpp wxutil.cpp tqslhelp.cpp crqwiz.cpp certtree.cpp getpassword.cpp loadcertwiz.cpp loctree.cpp) set(TQSL_HDR tqslapp.h tqslwiz.h qsodatadialog.h tqslexcept.h tqslpaths.h stationdial.h dxcc.h tqsl_prefs.h extwizard.h certtree.h tqslvalidator.h tqslbuild.h tqslhelp.h certtree.h tqslctrls.h util.h getpassword.h extwizard.h loadcertwiz.h wxutil.h loctree.h tqsltrace.h) set(TQSL_XPM left.xpm right.xpm bottom.xpm top.xpm key.xpm cert.xpm nocert.xpm broken-cert.xpm folder.xpm replaced.xpm expired.xpm home.xpm delete.xpm edit.xpm loc_add_dis.xpm properties.xpm download_dis.xpm loc_add.xpm upload_dis.xpm download.xpm file_edit_dis.xpm upload.xpm delete_dis.xpm edit_dis.xpm file_edit.xpm properties_dis.xpm save.xpm import.xpm lotw.xpm) add_executable(tqsl WIN32 MACOSX_BUNDLE ${TQSL_SRC} ${TQSL_HDR} ${TQSL_XPM} ${TQSL_RCFILE}) target_link_libraries(tqsl ${TQSLLIB_NAME} ${wxWidgets_LIBRARIES} ${ZLIB_LIBRARIES} ${CURL_LIBRARIES} ${CARBON_LIBRARY} ${EXPAT_LIBRARIES}) if(NOT APPLE AND NOT WIN32) add_definitions("-DCONFDIR=\"${CMAKE_INSTALL_PREFIX}/share/TrustedQSL/\"") install(TARGETS tqsl DESTINATION bin) install(DIRECTORY help DESTINATION share/TrustedQSL) install(FILES tqsl.5 DESTINATION share/man/man5) install(FILES icons/key48.png DESTINATION share/pixmaps RENAME TrustedQSL.png) endif() tqsl-2.0/apps/.project0000664000076400007640000000031312231073120014744 0ustar rmurphyrmurphy TrustedQSL tqsl-2.0/apps/.gitignore0000664000076400007640000000017012231073120015266 0ustar rmurphyrmurphytqslbuild.h !tqslbuild.h.in #Linux binaries tqsl tqslcert #Windows build artifacts Debug Release #OSX binaries *.app tqsl-2.0/WindowsBuildSetup.txt0000664000076400007640000003365012231073120016540 0ustar rmurphyrmurphy== Windows Build System setup for TrustedQSL == - By Robert, KC2YWE - Written 2/14/2013 - v1.0 - Initial writing V1.1 - Update to newer library versions, 7/25/2013 -- Conventions -- -- is a header - is a sub-item 'command' means type that command without the quotes; when quotes are needed, I use "" CAPS means extra important, not shouting When you need to get a file, I say: Download and run from: http://example.url/product "Link text on page to follow" (comment about which one to choose, maybe) If I don't mention something about an installer, leave it at the default unless you have a reason to change it. -- Prerequisites -- This is a Windows-specific tutorial. You must be running a version of Windows. These instructions were written for a clean install of Windows 7 64-bit in a virtual machine with all updates applied; any places where the instructions will differ based on Windows version or 32/64 bit will be noted to the best of my knowledge. I don't believe the setup is too sensitive to specific versions. You must read the whole document. I know it's long, but don't try to skim it or you might miss something that ends up breaking things later (there's a lot of potential pitfalls) -- Abbreviations -- TQSL = TrustedQSL VC, VC++ = Microsoft Visual C++ VS, VS2008, VS2010, VS2012 = Microsoft Visual Studio (includes VC++) and a version -- Assumptions -- The build system should be very flexible and should work with many versions of libraries, compilers, and platforms. But for simplicity's sake, the instructions given will be as specific as possible. In particular, this tutorial will focus on Visual Studio at the expense of MinGW (but it should work fine with MinGW). You should have familiarity with building software from source on Windows. Unix (including OSX) experience will mostly translate, and I'll give specific commands, but there's a lot of different ways this can go wrong and some troubleshooting experience will be helpful. You should have a lot of experience with C++ in particular. Most problems you run into will be in the form of compiler and linker errors. I will be using exact library versions, and even URLs. If you are reading this in several months, this will be out of date. YOU ARE ENCOURAGED TO USE NEWER VERSIONS, even if the instructions don't quite work - most of the instructions come from READMEs. I will store things directly in the C:\ directory. You can put them wherever you want, but you may need to help cmake find them. -- Variables -- This document will use VS2012 Express, which is free. It seems to be the nicest Visual Studio IDE, once you fix the menus. They will also work with VS2010 and VS2008, but I've only tested them with paid versions so I can't help with any express-only limitations. HOWEVER VS2012 WILL NOT TARGET WINDOWS 2000. It just won't work because the last version to target Win2K was VS2008. We still support Windows 2000, at least for a little longer, so "official" builds still need to be made with VS2008. I have it set up to use the 2008 compiler and runtimes as a "platform" in VS2012, but those directions are above the scope of this document. Feel free to use a "paid" version of Visual Studio, but the instructions may be slightly different. YOU MUST DECIDE IN ADVANCE WHAT RUNTIME YOU WILL USE. You can either statically link the Microsoft runtime, or dynamically link it. For distribution, I have everything statically linked, but if you are just running on your own personal machine(s) a dynamic runtime dependency may not bother you. It's just a DLL file that needs to be installed, and it is when you install Visual Studio, or you can install it separately (or may already have it). Whatever you decide, you need to decide before you start compiling stuff or else you'll have to re-compile *everything* due to weird linker errors. YOU MUST DECIDE IN ADVANCE WHAT COMPILER YOU WILL USE. Like the above, you will find yourself recompiling a lot if you try to switch compilers. In particular, much of the STL stuff is incompatible between versions. YOU MUST DECIDE IN ADVANCE WHETHER YOU WILL STATICALLY OR DYNAMICALLY LINK. All the libraries need to be compiled differently depending on your decision. Just like the runtime, this determines whether you have to schlep a bunch of DLLs along with you or not. NONE OF THESE AFFECT THE CODE. Static or dynamic runtimes or libraries, or compiler versions - the code will (should, in the case of compilers) be independent of these choices. These all affect YOUR setup, and most are irrelevant unless you try to move a binary somewhere else. DEFAULTS - this document is written for using a dynamic VC++ runtime and static libraries. -- Outline -- 1) Visual Studio, cmake, git, tqsl 2) Getting the source 3) Libraries (order irrelevant!) - openssl - zlib - curl - wxWidgets 2.8 4) Running cmake 5) Building -- 1) Visual Studio, cmake, git, tqsl -- These downloads and installs should run in parallel. If you find yourself waiting, cycle to the next item. - git * This installer "pauses" the VS2012 installer, even though it doesn't work while the VS2012 installer is running anyway. So maybe wait until it's done before starting VS2012 Express, or else you'll have to wait until VS2012 is done. Download msysgit as a prerequisite for TortoiseGit. TortoiseGit is optional if you're comfortable with the command line, but msysgit is required. Download and run from: http://code.google.com/p/msysgit/downloads/list?can=2&q="Full+installer+for+official+Git+for+Windows" Git-1.8.1.2-preview20130201.exe Next, etc. Uncheck 'Windows Explorer integration' if you're using TortoiseGit. You may find it convenient to have git in your command line (option 2). You should leave the line ending conversion as-is (checkout Windows/commit Unix, option 1). Download and run from: http://code.google.com/p/tortoisegit/wiki/Download "Download TortoiseGit 1.8.1.0 - 64-bit" (or 32 bit as appropriate) TortoiseGitPLink is probably the best choice. - Visual Studio 2012 Express Download and run from: http://www.microsoft.com/visualstudio/eng#downloads "Visual Studio Express 2012 for Windows Desktop" (not Windows 8!) - "Install now" When the installer loads, read and agree to the license terms, then 'Install' and accept the prompt. While it downloads, work on the other stuff. Next, etc. Add cmake to the current user path (3rd option); create an icon at your preference. - CMake Download and run from: http://www.cmake.org/cmake/resources/software.html cmake-2.8.10.2-win32-x86.exe - TrustedQSL Yes, for now you should have TrustedQSL installed. It's the fastest way to get the correct folder structure, config files, registry entries, etc. Download and run from: http://www.arrl.org/instructions "Step 1 - Download and install the software" > "Download the software for Windows here" -- 2) Get the source -- Decide where you want your source folder. I have mine in Documents\src. Right click in that folder and choose "Git clone...". Enter git://git.code.sf.net/p/trustedqsl/tqsl, click OK, and wait. It should create a folder called 'tqsl' in the folder you right-clicked in. Check it out and observe the folder structure. You'll see this document in there too ('WindowsBuildSetup.txt') - open it to make sure you're using the newest version. You should see a lot of Git options if you right-click in this folder; a Git tutorial will come later but you can play around for now. You can always delete the folder and re-clone it if you mess anything up. -- 3) Libraries (order is irrelevant) -- Now that you have the source, let's install the libraries needed to make it work. Most of these happen from the "Developer Command Prompt for VS2012". Open it and run 'nmake' and 'cl'; for 'cl' make sure it says "for x86". 64-bit builds should work (they do on Linux) but I've never tested it on Windows so I don't recommend it for now. - openssl You'll need Perl, sorry. Download and run from: http://www.activestate.com/activeperl/downloads "Download ActivePerl 5.16.2 for Windows (64-bit, x64)" (or 32 bit as appropriate) - you don't have to fill out the survey. Leave it at the defaults. While that's going, you'll also need something to open a .tar.gz, if you don't have anything. I recommend 7zip Download and run from: http://www.7-zip.org/ "64-bit x64" (or 32 bit as appropriate) - the install can't run at the same time as Perl. You'll also need the Netwide Assembler (nasm). It's not strictly required, but the assembly routines in OpenSSL only work with it, and apparently they're rather a lot faster. Download and run from: http://www.nasm.us/ "2.10.07/win32/nasm-2.10.07-installer.exe" Once you can open a .tar.gz, download OpenSSL - Download and extract to C:\openssl-src: http://www.openssl.org/source/ "openssl-1.0.1e.tar.gz" Go to the developer command prompt. Run 'set path=%localappdata%\nasm;%path%'. Make sure you can run 'nasm' and 'perl' (Ctrl-C to exit Perl). 'cd \openssl-src\openssl-1.0.1e' The below comes from "INSTALL.W32". Read it for more details if needed 'perl Configure VC-WIN32 --prefix=c:\openssl' 'ms\do_nasm' - observe a half-dozen 'perl' commands 'nmake -f ms\nt.mak' (for dynamic, ntdll.mak). It should build without error. 'nmake -f ms\nt.mak test' (can be skipped but might avoid a headache). Look for "passed all tests" 'nmake -f ms\nt.mak install' Make a new directory called "VC" and move "libeay32.lib" and "ssleay32.lib" into it. This is a CMake problem that will hopefully go away pretty soon, but it hasn't happened yet. - wxWidgets YOU NEED TO USE WXWIDGETS 2.8 for now; 2.9 has been tried and almost works but there are still some problems. Download and run from: http://wxwidgets.org/downloads/ "wxMSW" (under "Current Stable Release: wxWidgets 2.8.12") The below comes (mostly) from "BuildCVS.txt". Read it for more details if needed. In your developer command prompt, 'cd \wxWidgets-2.8.12\' You need to edit a file to fix a bug; comment out line 110 in src\msw\window.cpp ("//#include ") - Ref https://groups.google.com/d/msg/wx-dev/SFpDUR89zgY/et1UjdbAfO4J 'cd build\msw' 'nmake -f makefile.vc BUILD=release SHARED=0' (these should be the defaults, but specify them anyway) 'nmake -f makefile.vc BUILD=debug SHARED=0' (you need this or else debug builds won't link) !! You need to do work here if you want to use a static runtime !! as this builds with a dynamic one by default. !! See the wxWidgets wiki at !! wiki.wxWidgets.org/Compiling_WxWidgets_with_MSVC_(2) for !! info on how to do this. - curl Download and extract to C:\ (will make a new folder): http://curl.haxx.se/download.html "curl-7.31.0.tar.gz" The below comes from winbuild\BUILD.WINDOWS In your developer command prompt, 'cd \curl-7.31.0\winbuild' 'nmake -f Makefile.vc mode=static ENABLE_WINSSL=yes' Verify that a folder called 'builds\libcurl-vc-x86-release-static-ipv6-sspi-spnego-winssl' has been created. The 'winssl' part of that string is the most important because it means it will use the Windows APIs (and thus certificates) for SSL. - expat Download and run from: http://sourceforge.net/projects/expat/ "Download: expat-win32bin-2.1.0.exe" - Change the install folder to "C:\expat" to match our naming scheme Unfortunately, the binaries are DLLs. Go to C:\expat\Source and open the file 'expat.dsw'. Agree to convert it. Switch to the release config. Open the properties for 'expat_static', go to Librarian - General and change Output file to '..\..\Bin\libexpat.lib'. Go to the expat\Bin directory and verify that libexpat is about 500KB, which means it's statically linked. Delete all but libexpat.lib. - zlib Download and extract to C:\ (will make a new folder): http://zlib.net/ "zlib source code, version 1.2.8, tar.gz format" - "US (zlib.net)" ZLIB seems to disagree with running a release version in a debug build and crashes. So you'll want both. cmake will automatically set up the correct one to link based on the build type. Also, we'll get our first taste of cmake. - Open your developer command prompt; 'cd \zlib-1.2.8'. - Type 'cmake .' - Type 'msbuild /p:Configuration=Debug ALL_BUILD.vcxproj' - Type 'msbuild /p:Configuration=Release ALL_BUILD.vcxproj' - Berkeley DB Download from http://download.oracle.com/berkeley-db/db-6.0.20.NC.zip and unzip to c:\db-6.0.20.NC. From Visual Studio, open the build_windows\Berkeley_DB.sln project and upgrade it when prompted. Update the project to build static libraries (Configuration Properties/General/ Configuration Type). You can now build the Debug and Release libraries. Only the 'db' project needs to be built. -- 4) Running cmake -- Almost there! Open a command prompt and run cmake . -DCMAKE_LIBRARY_PATH="C:\expat\Bin" -DCMAKE_INCLUDE_PATH="C:\expat\Source\lib" -DwxWidgets_ROOT_DIR="C:\wxWidgets-2.8.12" -DBDB_INCLUDE_DIR="C:\db-6.0.20.NC\build_windows" -DBDB_LIBRARY="C:\db-6.0.20.NC\build_windows\Win32\Release\db.lib" -- 5) Building -- Whew! You thought this would be hard after all the rest, didn't you? Nope. Open TrustedQSL.sln and build. Both debug (default) and release will work. You'll find the binaries in tqsl\bin\Debug or tqsl\bin\Release as appropriate. == Final Thoughts == This is actually a lot simpler than the old process (even though it doesn't seem simpler!) because you still had to get all the libraries, but you also had to set up the compiler itself, which was rather more unpleasant than installing VS2012 Express. If you hate the all-caps menus in VS2012, you can turn them off easily. Create a key in HKEY_CURRENT_USER\Software\Microsoft\WDExpress\11.0\General\ called "SuppressUppercaseConversion", type DWORD, value 1 The cmake command line should be a lot shorter. I'm working on that. If you want to run any of these binaries on a new machine, all you have to do is install the 2012 redistributable: http://www.microsoft.com/en-us/download/details.aspx?id=30679 if it's not already installed. Please let me know if you have any trouble and I'll try to improve the document. Thanks for reading and I hope it helped! tqsl-2.0/LICENSE.txt0000664000076400007640000000465412231073120014171 0ustar rmurphyrmurphyLicense Terms and Conditions Copyright (C) 2001-2013 American Radio Relay League, Inc. All rights reserved. Portions (C) 2003-2013 The TrustedQSL Developers. Please see the AUTHORS.txt file for contributors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Any redistribution of source code must retain the above copyright notice, this list of conditions and the disclaimer shown in Paragraph 5 (below). 2. Redistribution in binary form must reproduce the above copyright notice, this list of conditions and the disclaimer shown in Paragraph 5 (below) in the documentation and/or other materials provided with the distribution. 3. Products derived from or including this software may not use "Logbook of the World" or "LoTW" or any other American Radio Relay League, Incorporated trademarks or servicemarks in their names without prior written permission of the ARRL. See Paragraph 6 (below) for contact information. 4. Use of this software does not imply endorsement by ARRL of products derived from or including this software and vendors may not claim such endorsement. 5. Disclaimer: This software is provided "as-is" without representation, guarantee or warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability or of fitness for a particular purpose. The entire risk as to the quality and performance of the software is solely with you. Should the software prove defective, you (and not the American Radio Relay League, its officers, directors, employees or agents) assume the entire cost of all necessary servicing, repair or correction. In no event will ARRL be liable to you or to any third party for any damages, whether direct or indirect, including lost profits, lost savings, or other incidental or consequential damages arising out of the use or inability to use such software, regardless of whether ARRL has been advised of the possibility of such damages. 6. Contact information: American Radio Relay League, Inc. Attn: Logbook of the World Manager 225 Main St Newington, CT 06111 voice: 860-594-0200 fax: 860-594-0259 email: logbook@arrl.org Worldwide Web: www.arrl.org This software consists of voluntary contributions made by many individuals on behalf of the ARRL. More information on the "Logbook of The World" project and the ARRL is available from the ARRL Web site at www.arrl.org. tqsl-2.0/INSTALL0000664000076400007640000001211112231073120013362 0ustar rmurphyrmurphyTQSL/tqsllib ================== TQSL is the TrustedQSL application suite and tqsllib is the TrustedQSL library. These are the two major components of the TrustedQSL project: http://sourceforge.net/projects/trustedqsl/ =================================================================== Contents 1) Prerequisites 2) Building the Library under Linux/Unix 3) Building the Library under Mac OS X 4) Building the Library under Windows. =================================================================== 1) Prerequisites The TQSL applications depend upon the tqsllib library. First you should build and install that library and its prerequisites. The TrustedQSL library depends on several other libraries: OpenSSL (http://www.openssl.org/) - OpenSSL 1.0.1e was used for TQSL 1.14. expat 1.x XML parser library (http://expat.sourceforge.net/) - expat 2.1.0 zlib (http://zlib.net/) zlib 1.2.7 Berkeley DB (http://www.oracle.com/technetwork/products/berkeleydb/downloads/index.html) - BDb 5.3.21 wxWidgets (http://wxwidgets.org/downloads) - wxWidgets 2.8.12. curl - (http://curl.haxx.se/download.html) - curl 7.29.0 Most Unix and unix-like workstations will have these available. For those systems that do not, the packages are easily built. Instructions for building under the Windows environment are given below under "Building under Windows." In the instructions that follow, the versions of other packages that were used to build the tqsllib package as of the date this document was last updated are given in parentheses. =================================================================== 2) Building under Linux/Unix The quick answer: From the parent directory cmake . make make install That will install the library and applications under /usr/local. It also will install the needed header files under /usr/local/include. Configuration and help files will be installed in /usr/local/share. You can change the install location via: cmake -DCMAKE_INSTALL_PREFIX=/foo/bar . By default, only a shared version of the library is built. CMake option TQSLLIB_STATIC can be set to cause a static library to be built, either by using 'cmake -i' or by adding '-DTQSLLIB_STATIC=YES' to the cmake command above. If you installed the tqsllib library or its dependent libraries in locations that configure can't find, you'll need to specify those locations to cmake. For example, you can define the location for the Berkeley Database headers using BDB_PREFIX. (That points to the top-level directory, with /include for headers and /lib for libraries assumed below it.) =================================================================== 3) Building under Mac OS X You'll need to have the Mac developer's tools, Xcode 1.5, installed. This is done in much the same manner as building under Linux/Unix, above. You will need to download and compile Berkeley DB 5.3 or later. The version of Berkeley DB shipped with OS X (as of 10.8) is out of date. You also may not want to install the library into system directories: cmake -DBDB_PREFIX=$HOME/bdb -DCMAKE_INSTALL_PREFIX=$HOME/tqsllib . make sudo make install To build a universal binary with compatibility from MacOS 10.4 upwards, use the following shell script: #!/bin/sh # # Adjust this to where you've installed wxWidgets # PATH=$HOME/wx/bin:$PATH # # Adjust this to where you've installed Berkeley DB 5.x # bdb=$HOME/bdb arch_flags="-arch ppc -arch i386" # # You need to download and install the OSX 10.4 universal SDK # to build a universal binary. gcc 4.0 is also needed. # sdk="/Developer/SDKs/MacOSX10.4u.sdk" ver_min="10.4" cmake \ -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_OSX_ARCHITECTURES="ppc;i386" \ -DCMAKE_LINKER=/usr/bin/gcc-4.0 \ -DCMAKE_CXX_COMPILER=/usr/bin/c++-4.0 \ -DCMAKE_C_COMPILER=/usr/bin/gcc-4.0 \ -DBDB_PREFIX=$bdb \ -DCMAKE_OSX_SYSROOT=$sdk \ -DCMAKE_CXX_FLAGS=" -I $HOME/bdb/include -I /usr/include/c++/4.0.0 \ -I $sdk/System/Library/Frameworks/Carbon.framework/Headers \ -isysroot $sdk -mmacosx-version-min=$ver_min \ -fno-stack-protector $arch_flags" \ -DCMAKE_C_FLAGS=" -I $HOME/bdb/include -I /usr/include/c++/4.0.0 \ -I $sdk/System/Library/Frameworks/Carbon.framework/Headers \ -isysroot $sdk -mmacosx-version-min=$ver_min \ -fno-stack-protector $arch_flags" \ -DCMAKE_EXE_LINKER_FLAGS=" -Wl,-syslibroot,$sdk \ -mmacosx-version-min=$ver_min $arch_flags " \ -DCMAKE_SHARED_LINKER_FLAGS=" -Wl,-syslibroot,$sdk \ -mmacosx-version-min=$ver_min $arch_flags " \ $* . make The build will result in the directory apps/tqsl.app, which contains the complete Mac OS X application. You can simply move that folder to your system's Applications folder or the location of your choice, then launch the application from Finder. If you want to distribute the built application: ./osx_createdmg.sh will make TrustedQSL-2.0.dmg, a Mac distributable disk image containing the TrustedQSL applications folder and document files. =================================================================== 4) Building under Windows See file WindowsBuildSetup.txt in the top-level directory for details on how to set up MSVC to compile TQSL. tqsl-2.0/CMakeLists.txt0000664000076400007640000000171212231073120015076 0ustar rmurphyrmurphycmake_minimum_required (VERSION 2.8 FATAL_ERROR) project(TrustedQSL) if(WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) # just windows for now... unix knows how to find libraries better set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) endif() set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmakemodules/") option(USE_STATIC_MSVCRT "Use a static Visual C++ Runtime when building with MSVC") if(MSVC AND USE_STATIC_MSVCRT) foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) if(${flag_var} MATCHES "/MD") string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") endif(${flag_var} MATCHES "/MD") endforeach(flag_var) endif() add_subdirectory(src) #tqsllib add_subdirectory(apps) tqsl-2.0/AUTHORS.txt0000664000076400007640000000013012231073120014215 0ustar rmurphyrmurphyKnown contributors (listed roughly in order by date) WA1GON K1MK KE3Z K1MU KC2YWE AA6YQtqsl-2.0/.gitignore0000664000076400007640000000045112231073120014325 0ustar rmurphyrmurphy#cmake-generated files CMakeCache.txt CMakeFiles/ cmake_install.cmake install_manifest.txt #emacs junk *~ #windows-specific products *.vcxproj* *.dir *.sln *.suo *.*sdf Win32 ipch *.rc !*.rc.in bin/ lib/ #linux-specific products Makefile tqsl-*.tar.gz #OSX-specific cruft .DS_Store tqsl-*.dmg