SVN-fs-dump-format-version: 2 UUID: b259dc2b-b81d-0410-99b0-d7ad1173cfa7 Revision-number: 0 Prop-content-length: 56 Content-length: 56 K 8 svn:date V 27 2006-09-18T10:52:33.891867Z PROPS-END Revision-number: 1 Prop-content-length: 134 Content-length: 134 K 7 svn:log V 23 Created folder remotely K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:01:37.213153Z PROPS-END Node-path: trunk Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Revision-number: 2 Prop-content-length: 111 Content-length: 111 K 7 svn:log V 1 K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:02:10.658575Z PROPS-END Node-path: branches Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Revision-number: 3 Prop-content-length: 134 Content-length: 134 K 7 svn:log V 23 Created folder remotely K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:02:16.881578Z PROPS-END Node-path: tags Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Revision-number: 4 Prop-content-length: 134 Content-length: 134 K 7 svn:log V 23 Added a folder remotely K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:06:40.567935Z PROPS-END Node-path: trunk/cga-new Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga-new/cga.sln Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1043 Text-content-md5: a398556dda44bbbc60e9722da6efeb93 Content-length: 1053 PROPS-END Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cga", "cga\cga.vcproj", "{7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}" ProjectSection(ProjectDependencies) = postProject EndProjectSection ProjectSection(ProjectDependencies) = postProject EndProjectSection ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.ActiveCfg = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.Build.0 = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.ActiveCfg = Release|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal Node-path: trunk/cga-new/simple_arch.xml Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 867 Text-content-md5: 77e1d962f7d0e47a68874ccef6a11bd3 Content-length: 877 PROPS-END Revision-number: 5 Prop-content-length: 127 Content-length: 127 K 7 svn:log V 16 Renamed remotely K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:06:46.191732Z PROPS-END Node-path: trunk/cga Node-kind: dir Node-action: add Node-copyfrom-rev: 4 Node-copyfrom-path: trunk/cga-new Node-path: trunk/cga-new Node-action: delete Revision-number: 6 Prop-content-length: 130 Content-length: 130 K 7 svn:log V 19 Removed file/folder K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:06:54.644393Z PROPS-END Node-path: trunk/cga Node-action: delete Revision-number: 7 Prop-content-length: 139 Content-length: 139 K 7 svn:log V 28 Initial import to repository K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:09:58.390308Z PROPS-END Node-path: trunk/cga Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/cga.vcproj Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 18954 Text-content-md5: 7d58e31e57693101db6e2302a2f012b9 Content-length: 18964 PROPS-END Node-path: trunk/cga/config.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 229 Text-content-md5: 05c786d4324747f0268983f0e3759daf Content-length: 239 PROPS-END #ifndef CONFIG_H #define CONFIG_H //#pragma warning(disable : 4267) #include #include #define UNDEF_ID UINT_MAX #define PRINT(x) std::cout << x << std::endl << std::flush; #endif // CONFIG_H Node-path: trunk/cga/doc Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exception.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 511 Text-content-md5: 54a44d514927795e31be107dff72c18e Content-length: 521 PROPS-END #include "exception.h" namespace CGA { Exception::Exception(const QString msg) : message_(msg) { } QString Exception::getMessage() { return message_; } FileException::FileException(const QString msg) : Exception(msg) { } DataBaseException::DataBaseException(const QString msg) : Exception(msg) { } XMLException::XMLException(const QString msg) : Exception(msg) { } TraceFileException::TraceFileException(const QString msg) : Exception(msg) { } } // namespace CGA Node-path: trunk/cga/exception.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 886 Text-content-md5: bb5cda83e3693d68354ff640e9d60f8b Content-length: 896 PROPS-END #ifndef EXCEPTION_H #define EXCEPTION_H #include namespace CGA { /** * Base class for Exceptions */ class Exception { public: Exception(const QString msg = ""); QString getMessage(); private: QString message_; }; /** * Exception handling file errors */ class FileException : public Exception { public: FileException(const QString msg = ""); }; /** * Exception handling data base errors */ class DataBaseException : public Exception { public: DataBaseException(const QString msg = ""); }; /** * Exception handling XML errors */ class XMLException : public Exception { public: XMLException(const QString msg = ""); }; /** * Exception handling TraceFile errors */ class TraceFileException : public Exception { public: TraceFileException(const QString msg = ""); }; } // namespace CGA #endif // EXCEPTION_H Node-path: trunk/cga/exploration Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/controller Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/model Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/view Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/view/sourcecode Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/view/startfunc Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/exploration/view/subgraph Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/extraction Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/extraction/architecture Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/extraction/architecture/archmodel.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 9779 Text-content-md5: 4e6bcb3b5348fbd4d675b38272cfcdae Content-length: 9789 PROPS-END #include "../../config.h" #include "archmodel.h" #include "archmodelxmlreader.h" #include "dirmodel.h" #include "../../exception.h" #include #include #include using VRS::SO; namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { // //////////////////////////////////////////////////////////////////////// // static factory methods // //////////////////////////////////////////////////////////////////////// VRS::SO ArchModel::convertDirModelToArchModel(VRS::SO dirModel) { unsigned int archRootID = UNDEF_ID; SO > archID2name = new VRS::NonPersistentDictionary; SO > > > archID2children = new VRS::NonPersistentDictionary > >; unsigned int dirRootID = UNDEF_ID; SO > dirID2name = new VRS::NonPersistentDictionary; SO > > > dirID2children = new VRS::NonPersistentDictionary > >; SO > dirID2archID = new VRS::NonPersistentDictionary; dirRootID = archRootID = dirModel->getRootID(); SO > queue = new VRS::NonPersistentDeque; queue->append(dirRootID); while (!queue->isEmpty()) { // // process next dir // unsigned int currentDirID = queue->getElement(0); unsigned int currentArchID = currentDirID; queue->removeFirst(); // // dir -> arch mapping // dirID2archID->insert(currentDirID, currentArchID); // // name // QString name = dirModel->getName(currentDirID); dirID2name->insert(currentDirID, name.ascii()); archID2name->insert(currentArchID, name.ascii()); // // children // SO > dirChildrenQueue = new VRS::NonPersistentDeque; SO > archChildrenQueue = new VRS::NonPersistentDeque; dirID2children->insert(currentDirID, dirChildrenQueue); archID2children->insert(currentArchID, archChildrenQueue); SO > it = dirModel->getChildren(currentDirID); unsigned int i, iMax = it->size(); for (i=0; iget(i); unsigned int archChild = dirChild; dirChildrenQueue->append(dirChild); archChildrenQueue->append(archChild); queue->append(dirChild); } } SO archModel = new ArchModel( archRootID, archID2name, archID2children, dirRootID, dirID2name, dirID2children, dirID2archID); return archModel; } VRS::SO ArchModel::loadFromXML(QString file) { unsigned int archRootID; SO > archID2name = new VRS::NonPersistentDictionary; SO > > > archID2children = new VRS::NonPersistentDictionary > >; unsigned int dirRootID; SO > dirID2name = new VRS::NonPersistentDictionary; SO > > > dirID2children = new VRS::NonPersistentDictionary > >; SO > dirID2archID = new VRS::NonPersistentDictionary; ArchModelXMLReader::read( file, &archRootID, archID2name, archID2children, &dirRootID, dirID2name, dirID2children, dirID2archID); SO model = new ArchModel( archRootID, archID2name, archID2children, dirRootID, dirID2name, dirID2children, dirID2archID); return model; } // //////////////////////////////////////////////////////////////////////// // methods to save // //////////////////////////////////////////////////////////////////////// void ArchModel::saveToXML(QString file) { // check file QFile f(file); if (!f.open(IO_WriteOnly)) { throw FileException("Can not open file for writing: " + file); } QTextStream stream(&f); stream.precision(9); // // head // stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n"; // // arch componentes // stream << "\n"; // use stack of stacks to keep oriented in hierarchy of architecture components SO > > > stackstack = new VRS::Stack > >; SO > children; unsigned int i, iMax; SO > entryTagDic = new VRS::NonPersistentDictionary(); SO > stack = new VRS::Stack; stackstack->push(stack); stack->push(getArchRootID()); entryTagDic->insert(getArchRootID(), true); unsigned int intend = 1; while (!stackstack->isEmpty()) { stack = stackstack->top(); while (!stack->isEmpty()) { // get current architecture component and pop it from stack unsigned int current = stack->top(); // // start element -> // if (entryTagDic->getValue(current)) { entryTagDic->insert(current, false); // write architecture component data for (i=0; i\n"; intend += 1; // recurse on children children = getArchChildren(current); iMax = children->size(); if (iMax > 0) { SO > children_stack = new VRS::Stack; stackstack->push(children_stack); for (i=0; iget(i); children_stack->push(child); entryTagDic->insert(child, true); } } } else { // // end element -> // stack->pop(); // close architecture component element intend -= 1; for (i=0; i\n"; } stack = stackstack->top(); } stackstack->pop(); } stream << "\n"; // // directories // stream << "\n"; // use stack of stacks to keep oriented in hierarchy of directories stackstack = new VRS::Stack > >; entryTagDic = new VRS::NonPersistentDictionary(); stack = new VRS::Stack; stackstack->push(stack); stack->push(getDirRootID()); entryTagDic->insert(getDirRootID(), true); intend = 1; while (!stackstack->isEmpty()) { stack = stackstack->top(); while (!stack->isEmpty()) { // get current directory and pop it from stack unsigned int current = stack->top(); // // start element -> // if (entryTagDic->getValue(current)) { entryTagDic->insert(current, false); // write directory data for (i=0; i\n"; intend += 1; // recurse on children children = getDirChildren(current); iMax = children->size(); if (iMax > 0) { SO > children_stack = new VRS::Stack; stackstack->push(children_stack); for (i=0; iget(i); children_stack->push(child); entryTagDic->insert(child, true); } } } else { // // end element -> // stack->pop(); // close dir element intend -= 1; for (i=0; i\n"; } stack = stackstack->top(); } stackstack->pop(); } stream << "\n"; stream << "\n"; // // close file // f.close(); } // //////////////////////////////////////////////////////////////////////// // private factory methods // //////////////////////////////////////////////////////////////////////// ArchModel::ArchModel( unsigned int archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID) : archRootID_(archRootID), archID2name_(archID2name), archID2children_(archID2children), dirRootID_(dirRootID), dirID2name_(dirID2name), dirID2children_(dirID2children), dirID2archID_(dirID2archID) { } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/archmodel.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4166 Text-content-md5: cb4f8db1aaf47eaf012c99fb9e0c5807 Content-length: 4176 PROPS-END #ifndef EXTRACTION_ARCHITECTURE_ARCHMODEL_H #define EXTRACTION_ARCHITECTURE_ARCHMODEL_H #include #include #include #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { class DirModel; /** * ArchModel represents the static system architecture of the analyzed software system. * It consists of * a) a tree of architecture components * b) a tree of directories * c) for each directory a mapping to an architecture component */ class ArchModel : public VRS::SharedObj { public: // //////////////////////////////////////////////////////////////////////// // static factory methods // //////////////////////////////////////////////////////////////////////// static VRS::SO convertDirModelToArchModel(VRS::SO); /// throws FileException or XMLException static VRS::SO loadFromXML(QString file); // //////////////////////////////////////////////////////////////////////// // methods to save // //////////////////////////////////////////////////////////////////////// /// throws FileException void saveToXML(QString file); // //////////////////////////////////////////////////////////////////////// // methods to access attributes // //////////////////////////////////////////////////////////////////////// unsigned int getArchRootID() const {return archRootID_;} QString getArchName(unsigned int id) const {VRS_CheckArg(archID2name_->contains(id), "bad id"); return archID2name_->getValue(id).c_str();} VRS::SO > getArchChildren(unsigned int id) {VRS_CheckArg(archID2children_->contains(id), "bad id"); return archID2children_->getValue(id)->newIterator();} unsigned int getDirRootID() const {return dirRootID_;} QString getDirName(unsigned int id) const {VRS_CheckArg(dirID2name_->contains(id), "bad id"); return dirID2name_->getValue(id).c_str();} VRS::SO > getDirChildren(unsigned int id) {VRS_CheckArg(dirID2children_->contains(id), "bad id"); return dirID2children_->getValue(id)->newIterator();} unsigned int getArchAssociatedWithDir(unsigned int dirID) {VRS_CheckArg(dirID2archID_->contains(dirID), "bad id"); return dirID2archID_->getValue(dirID);} // //////////////////////////////////////////////////////////////////////// // methods to modify attributes // //////////////////////////////////////////////////////////////////////// // TODO private: // //////////////////////////////////////////////////////////////////////// // private factory methods // //////////////////////////////////////////////////////////////////////// ArchModel( unsigned int archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID); // //////////////////////////////////////////////////////////////////////// // private methods to modify attributes // //////////////////////////////////////////////////////////////////////// // TODO unsigned int archRootID_; VRS::SO > archID2name_; VRS::SO > > > archID2children_; unsigned int dirRootID_; VRS::SO > dirID2name_; VRS::SO > > > dirID2children_; VRS::SO > dirID2archID_; }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif //EXTRACTION_ARCHITECTURE_ARCHMODEL_H Node-path: trunk/cga/extraction/architecture/archmodelxmlhandler.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4521 Text-content-md5: f5cb7597d545c4f5143e56ad97edc60f Content-length: 4531 PROPS-END #include "../../config.h" #include "archmodelxmlhandler.h" #include "../../exception.h" #include "../../xmlutil.h" #include using VRS::SO; namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { ArchModelXMLHandler::ArchModelXMLHandler( unsigned int* archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int* dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID) : archRootID_(archRootID), archID2name_(archID2name), archID2children_(archID2children), dirRootID_(dirRootID), dirID2name_(dirID2name), dirID2children_(dirID2children), dirID2archID_(dirID2archID) { *archRootID_ = UNDEF_ID; *dirRootID_ = UNDEF_ID; parentArchID_ = UNDEF_ID; parentDirID_ = UNDEF_ID; archID2parentArchID_ = new VRS::NonPersistentDictionary; dirID2parentDirID_ = new VRS::NonPersistentDictionary; } void ArchModelXMLHandler::endDocument() { } void ArchModelXMLHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { QString e = XMLUtil::transcode(localname); if (e == "comp") { parentArchID_ = archID2parentArchID_->getValue(parentArchID_); return; } if (e == "dir") { parentDirID_ = dirID2parentDirID_->getValue(parentDirID_); return; } } void ArchModelXMLHandler::characters(const XMLCh* const chars, const unsigned int length) { } void ArchModelXMLHandler::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { } void ArchModelXMLHandler::processingInstruction(const XMLCh* const target, const XMLCh* const data) { } void ArchModelXMLHandler::startDocument() { } void ArchModelXMLHandler::startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const xercesc::Attributes& attributes) { QString e = XMLUtil::transcode(localname); if (e == "comp") { QString name = XMLUtil::transcode(attributes.getValue((unsigned int)0)); unsigned int id = XMLUtil::transcode(attributes.getValue((unsigned int)1)).toUInt(); // set root if (parentArchID_ == UNDEF_ID) *archRootID_ = id; // remember parent archID2parentArchID_->insert(id, parentArchID_); // add to parent's list of children if (parentArchID_ != UNDEF_ID) { archID2children_->getValue(parentArchID_)->append(id); } // create children list for current arch comp archID2children_->insert(id, new VRS::NonPersistentDeque); // name archID2name_->insert(id, name.ascii()); // current is now parent parentArchID_ = id; return; } if (e == "dir") { QString name = XMLUtil::transcode(attributes.getValue((unsigned int)0)); unsigned int id = XMLUtil::transcode(attributes.getValue((unsigned int)1)).toUInt(); unsigned int arch = XMLUtil::transcode(attributes.getValue((unsigned int)2)).toUInt(); // set root if (parentDirID_ == UNDEF_ID) *dirRootID_ = id; // remember parent dirID2parentDirID_->insert(id, parentDirID_); // add to parent's list of children if (parentDirID_ != UNDEF_ID) { dirID2children_->getValue(parentDirID_)->append(id); } // create children list for current arch comp dirID2children_->insert(id, new VRS::NonPersistentDeque); // name dirID2name_->insert(id, name.ascii()); // dir -> arch mapping dirID2archID_->insert(id, arch); // current is now parent parentDirID_ = id; return; } } void ArchModelXMLHandler::warning(const xercesc::SAXParseException& exc) { throw XMLException("XML warning: " + XMLUtil::transcode(exc.getMessage())); } void ArchModelXMLHandler::error(const xercesc::SAXParseException& exc) { throw XMLException("XML error: " + XMLUtil::transcode(exc.getMessage())); } void ArchModelXMLHandler::fatalError(const xercesc::SAXParseException& exc) { throw XMLException("XML fatalError: " + XMLUtil::transcode(exc.getMessage())); } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/archmodelxmlhandler.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2782 Text-content-md5: c21a2a464cb914f4125b1373985d0759 Content-length: 2792 PROPS-END #ifndef EXTRACTION_ARCHITECTURE_ARCHMODELXMLHANDLER_H #define EXTRACTION_ARCHITECTURE_ARCHMODELXMLHANDLER_H #include "../../config.h" #include #include #include #include #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * ArchModelXMLHandler is used by ArchModelXMLReader to create an ArchModel from an XML file */ class ArchModelXMLHandler : public xercesc::DefaultHandler { public: ArchModelXMLHandler( unsigned int* archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int* dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID); private: void endDocument(); void endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname); void characters(const XMLCh* const chars, const unsigned int length); void ignorableWhitespace(const XMLCh* const chars, const unsigned int length); void processingInstruction(const XMLCh* const target, const XMLCh* const data); void startDocument(); void startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const xercesc::Attributes& attributes); void warning(const xercesc::SAXParseException& exc); void error(const xercesc::SAXParseException& exc); void fatalError(const xercesc::SAXParseException& exc); private: unsigned int* archRootID_; VRS::SO > archID2name_; VRS::SO > > > archID2children_; unsigned int* dirRootID_; VRS::SO > dirID2name_; VRS::SO > > > dirID2children_; VRS::SO > dirID2archID_; unsigned int parentArchID_; VRS::SO > archID2parentArchID_; unsigned int parentDirID_; VRS::SO > dirID2parentDirID_; }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif // EXTRACTION_ARCHITECTURE_ARCHMODELXMLHANDLER_H Node-path: trunk/cga/extraction/architecture/archmodelxmlreader.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2219 Text-content-md5: b5485820b38a16945ebf5321cc963780 Content-length: 2229 PROPS-END #include "../../config.h" #include "archmodelxmlreader.h" #include "archmodelxmlhandler.h" #include "../../exception.h" #include #include #include #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { ArchModelXMLReader::ArchModelXMLReader() { VRS_Error(false, "no instance creation"); } void ArchModelXMLReader::read( QString file, unsigned int* archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int* dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID) { // check file QFile f(file); if (!f.exists() || !f.open(IO_ReadOnly)) { throw FileException("Can not open file " + file); } // Initialize the XML4C2 system try { xercesc::XMLPlatformUtils::Initialize(); } catch (const xercesc::XMLException&) { throw XMLException("Can not initialize XML parser."); } xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader(); parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, false); parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, true); parser->setFeature(xercesc::XMLUni::fgXercesSchema, false); parser->setFeature(xercesc::XMLUni::fgXercesSchemaFullChecking, false); parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpacePrefixes, false); ArchModelXMLHandler handler( archRootID, archID2name, archID2children, dirRootID, dirID2name, dirID2children, dirID2archID); parser->setContentHandler(&handler); parser->parse(file.ascii()); delete parser; xercesc::XMLPlatformUtils::Terminate(); // return values are passed in method parameters return; } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/archmodelxmlreader.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1210 Text-content-md5: 6840861c222e186070958b79e4848e35 Content-length: 1220 PROPS-END #ifndef EXTRACTION_ARCHITECTURE_ARCHMODELXMLREADER_H #define EXTRACTION_ARCHITECTURE_ARCHMODELXMLREADER_H #include #include #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * ArchModelXMLReader has the static method read to create an ArchModel from an XML file */ class ArchModelXMLReader { public: // throws FileException, XMLException static void read( QString file, unsigned int* archRootID, VRS::SO > archID2name, VRS::SO > > > archID2children, unsigned int* dirRootID, VRS::SO > dirID2name, VRS::SO > > > dirID2children, VRS::SO > dirID2archID); private: ArchModelXMLReader(); }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif // EXTRACTION_ARCHITECTURE_ARCHMODELXMLREADER_H Node-path: trunk/cga/extraction/architecture/dialogcreate.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1822 Text-content-md5: 0cc7a2d7314cda79cc65dc75686d4c82 Content-length: 1832 PROPS-END #include "../../config.h" #include "dialogcreate.h" #include "archmodel.h" #include "diranalyzer.h" #include "dirmodel.h" #include "../../exception.h" #include #include #include #include #include #include using VRS::SO; namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { DialogCreate::DialogCreate() : DialogCreateGUI(NULL, "", true) { } void DialogCreate::create() { if (lineEditDir->text().isEmpty() || lineEditFile->text().isEmpty()) { QMessageBox::information(this, "Directory or XML file missing", "Fill all fields."); return; } // // create DirModel // SO dirmodel; SO archmodel; try { dirmodel = DirAnalyzer::createDirModel(lineEditDir->text()); // // convert to ArchModel // archmodel = ArchModel::convertDirModelToArchModel(dirmodel); archmodel->saveToXML(lineEditFile->text()); } catch (Exception* e) { QMessageBox::information(this, "Error", e->getMessage()); return; } // // save ArchModel // accept(); } void DialogCreate::chooseDir() { QString dir = QFileDialog::getExistingDirectory( QDir::currentDirPath(), this, "getDirDialog", "Choose directory to analyze"); if (dir == QString::null) return; lineEditDir->setText(dir); } void DialogCreate::chooseFile() { QString file = QFileDialog::getSaveFileName( QDir::currentDirPath(), "architecture xml file (*_arch.xml)", this, "saveFileDialog", "Choose XML filename to save architecture model under"); if (file == QString::null) return; lineEditFile->setText(file); } void DialogCreate::cancel() { reject(); } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/dialogcreate.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 557 Text-content-md5: 075b2a19bf594a92db8a948d42e358fc Content-length: 567 PROPS-END #ifndef EXTRACION_ARCHITECTURE_DIALOGCREATE_H #define EXTRACION_ARCHITECTURE_DIALOGCREATE_H #include "uic/dialogcreategui.h" #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * */ class DialogCreate : public DialogCreateGUI { Q_OBJECT public: DialogCreate(); public slots: void create(); void cancel(); void chooseDir(); void chooseFile(); private: }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif // EXTRACION_ARCHITECTURE_DIALOGCREATE_H Node-path: trunk/cga/extraction/architecture/dialogcreategui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 8339 Text-content-md5: d13bc9cff13184111680aa12a13c08b1 Content-length: 8349 PROPS-END DialogCreateGUI DialogCreateGUI 0 0 406 103 5 5 0 0 Create Architecture Model From Directory Structure unnamed 3 textLabel2 0 0 0 0 XML File to Save Model textLabel1 0 0 0 0 Directory to Analyze pushButtonCreate 0 0 0 0 Create pushButtonCancel 0 0 0 0 Cancel spacer1 Horizontal Expanding 32000 21 spacer2 Vertical Expanding 400 16 lineEditDir NoFocus LineEditPanel Sunken true lineEditFile NoFocus true toolButtonDir 0 0 0 0 TabFocus ... toolButtonFile 0 0 0 0 TabFocus ... pushButtonCancel clicked() DialogCreateGUI cancel() pushButtonCreate clicked() DialogCreateGUI create() toolButtonDir clicked() DialogCreateGUI chooseDir() toolButtonFile clicked() DialogCreateGUI chooseFile() toolButtonDir toolButtonFile pushButtonCreate pushButtonCancel lineEditDir lineEditFile create() cancel() chooseDir() chooseFile() Node-path: trunk/cga/extraction/architecture/dialogmodify.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 413 Text-content-md5: 8bde4e9dc5dedc438160e6de5a157919 Content-length: 423 PROPS-END #include "../../config.h" #include "dialogmodify.h" #include "dialogcreate.h" namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { DialogModify::DialogModify() : DialogModifyGUI(NULL, "", true) { } void DialogModify::foo() { DialogCreate* dialog = new DialogCreate(); dialog->exec(); delete dialog; } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/dialogmodify.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 478 Text-content-md5: 7d41d7dc1c65c99bb725c6bb4a2cb1f8 Content-length: 488 PROPS-END #ifndef EXTRACION_ARCHITECTURE_DIALOGMODIFY_H #define EXTRACION_ARCHITECTURE_DIALOGMODIFY_H #include "uic/dialogmodifygui.h" namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * */ class DialogModify : public DialogModifyGUI { Q_OBJECT public: DialogModify(); public slots: void foo(); private: }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif // EXTRACION_ARCHITECTURE_DIALOGMODIFY_H Node-path: trunk/cga/extraction/architecture/dialogmodifygui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2515 Text-content-md5: 838fa15e8d9ff5826c2c6e80ea0c329f Content-length: 2525 PROPS-END DialogModifyGUI DialogModifyGUI 0 0 481 154 5 5 0 0 Architecture Model Modification unnamed 3 pushButtonFoo IchBinEinButtonZumErzeugenEinesInitialmodellsDurchVerzeichnisParsen pushButtonCancel 0 0 0 0 Cancel pushButtonCancel clicked() DialogModifyGUI cancel() pushButtonFoo clicked() DialogModifyGUI foo() pushButtonCancel foo() cancel() Node-path: trunk/cga/extraction/architecture/diranalyzer.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2994 Text-content-md5: d52980bb81d6860d61e344fa603c55c7 Content-length: 3004 PROPS-END #include "../../config.h" #include "diranalyzer.h" #include "../../exception.h" #include #include #include #include #include #include #include #include using VRS::SO; namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { DirAnalyzer::DirAnalyzer() { VRS_Error(false, "no instances of DirAnalyzer possible"); } VRS::SO DirAnalyzer::createDirModel(QString directory) { // // analyze directory // QDir dir(directory); if (!dir.exists()) { throw FileException("Directory " + directory + " does not exist!"); } unsigned int nextUnusedID = 0; QProgressDialog* progress = new QProgressDialog("Analyzing: "+directory, "Abort", 200, NULL, "progress", TRUE); progress->show(); unsigned int steps = 0; SO > fullPathDic = new VRS::NonPersistentDictionary(); SO > pathDic = new VRS::NonPersistentDictionary(); SO > > > childrenQueueDic = new VRS::NonPersistentDictionary > >(); SO > dirQueue = new VRS::NonPersistentDeque(); // root dir unsigned int rootID = nextUnusedID++; QString absPath = dir.absPath(); QString dirName = dir.dirName(); fullPathDic->insert(rootID, dir.absPath().ascii()); pathDic->insert(rootID, dir.dirName().ascii()); dirQueue->append(rootID); // get all directories while (!dirQueue->isEmpty()) { progress->setProgress(steps++); if (steps == 200) steps = 0; unsigned int currentID = dirQueue->getElement(0); dirQueue->removeFirst(); SO > childrenQueue = new VRS::NonPersistentDeque(); childrenQueueDic->insert(currentID, childrenQueue); QString fullPath = fullPathDic->getValue(currentID).c_str(); dir.setPath(fullPath); dir.setFilter(QDir::Dirs); const QFileInfoList* list = dir.entryInfoList(); for (QFileInfoList::Iterator it = list->begin(); it != list->end(); it++) { if ( (*it)->fileName() != "." && (*it)->fileName() != ".." && (*it)->fileName() != "CVS" && (*it)->fileName() != ".svn") { unsigned int id = nextUnusedID++; childrenQueue->append(id); fullPathDic->insert(id, (*it)->filePath().ascii()); pathDic->insert(id, (*it)->fileName().ascii()); dirQueue->append(id); } } } // // create DirModel // SO model = new DirModel( rootID, pathDic, childrenQueueDic); delete progress; return model; } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/diranalyzer.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 610 Text-content-md5: e829bff21b9480bdcc55042293d24750 Content-length: 620 PROPS-END #ifndef EXTRACTION_ARCHITECTURE_DIRANALYZER_H #define EXTRACTION_ARCHITECTURE_DIRANALYZER_H #include "dirmodel.h" namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * DirAnalyzer provides a static method to analyze all subdirectories of a given directory and converting them into * a DirModel. */ class DirAnalyzer { public: // throws FileException static VRS::SO createDirModel(QString directory); private: DirAnalyzer(); }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif //EXTRACTION_ARCHITECTURE_DIRANALYZER_H Node-path: trunk/cga/extraction/architecture/dirmodel.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 530 Text-content-md5: d6f9b5b561dc9075b46554188f90a75d Content-length: 540 PROPS-END #include "../../config.h" #include "dirmodel.h" using VRS::SO; namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { DirModel::DirModel( unsigned int rootID, VRS::SO > id2name, VRS::SO > > > id2children) : rootID_(rootID), id2name_(id2name), id2children_(id2children) { } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/dirmodel.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1303 Text-content-md5: 6dfeaed61b4387117136536b4a79f3de Content-length: 1313 PROPS-END #ifndef EXTRACTION_ARCHITECTURE_DIRMODEL_H #define EXTRACTION_ARCHITECTURE_DIRMODEL_H #include #include #include #include namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * DirModel */ class DirModel : public VRS::SharedObj { public: DirModel( unsigned int rootID, VRS::SO > id2name, VRS::SO > > > id2children); unsigned int getRootID() const {return rootID_;} QString getName(unsigned int id) const {VRS_CheckArg(id2name_->contains(id), "bad id"); return id2name_->getValue(id).c_str();} VRS::SO > getChildren(unsigned int id) {VRS_CheckArg(id2children_->contains(id), "bad id"); return id2children_->getValue(id)->newIterator();} private: unsigned int rootID_; VRS::SO > id2name_; VRS::SO > > > id2children_; }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif //EXTRACTION_ARCHITECTURE_DIRMODEL_H Node-path: trunk/cga/extraction/callgraph Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/extraction/extractiongui.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 422 Text-content-md5: 620f919ff8b1786929730c752a93bdc0 Content-length: 432 PROPS-END #include "../config.h" #include "extractiongui.h" #include "architecture/dialogmodify.h" namespace CGA { namespace EXTRACTION { ExtractionGui::ExtractionGui(QFrame* frame) : ExtractionGuiUI(frame) { } void ExtractionGui::startArchitecture() { ARCHITECTURE::DialogModify* dialog = new ARCHITECTURE::DialogModify(); dialog->exec(); delete dialog; } } // namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/extractiongui.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 431 Text-content-md5: 54c21739c12ca999e3b839462c551a3f Content-length: 441 PROPS-END #ifndef EXTRACTION_H #define EXTRACTION_H #include "uic/extractionguiui.h" #include #include namespace CGA { namespace EXTRACTION { /** * ExtractionGui */ class ExtractionGui : public ExtractionGuiUI { Q_OBJECT public: ExtractionGui(QFrame*); public slots: void startArchitecture(); private: }; } // namespace EXTRACTION } // namespace CGA #endif // EXTRACTION_H Node-path: trunk/cga/extraction/extractionguiui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1888 Text-content-md5: 85cb2170388c5ced70808ab8433a8e89 Content-length: 1898 PROPS-END ExtractionGuiUI ExtractionGuiUI 0 0 424 86 ExtractionGuiUI unnamed pushButtonArchitecture 0 0 0 0 start textLabel1 Create new or modify existing architecture model pushButtonArchitecture clicked() ExtractionGuiUI startArchitecture() startArchitecture() Node-path: trunk/cga/extraction/mapping Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/extraction/repository Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/main.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 652 Text-content-md5: 898f8652b04cb3239eca02889e82d459 Content-length: 662 PROPS-END #include #include #include #include "project/uic/projectgui.h" #include "exception.h" /** * Entry point */ int main(int argc, char** argv) { QApplication* app = new QApplication( argc, argv ); if (!QGLFormat::hasOpenGL()) { QMessageBox::warning(NULL, "OpenGL error", "This system has no OpenGL support. Exiting."); return -1; } ProjectGui* gui = new ProjectGui(); gui->show(); app->setMainWidget(gui); int ret; try { ret = app->exec(); } catch (CGA::Exception* e) { QMessageBox::warning(NULL, "Exception thrown", e->getMessage()); return -2; } return ret; } Node-path: trunk/cga/project Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/project/controller.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2590 Text-content-md5: 7e62515207bc0bb7acab629c61001db4 Content-length: 2600 PROPS-END #include "../config.h" #include "controller.h" #include "dialognewproject.h" #include "uic/projectgui.h" #include "../extraction/extractiongui.h" #include #include #include #include #include #include namespace CGA { namespace PROJECT { Controller* Controller::instance_ = NULL; Controller::Controller() : guiMenuBar_(NULL), guiWidgetStack_(NULL), guiFrameNoProject_(NULL), guiFrameExtraction_(NULL), guiFrameExploration_(NULL), mode_(UNDEF) { } Controller* Controller::instance() { if (!instance_) instance_ = new Controller(); return instance_; } void Controller::registerProjectGui( QMenuBar* menu, QWidgetStack* widgetStack, QFrame* noproject, QFrame* extraction, QFrame* exploration) { guiMenuBar_ = menu; guiWidgetStack_ = widgetStack; guiFrameNoProject_ = noproject; guiFrameExtraction_ = extraction; guiFrameExploration_ = exploration; QGridLayout* layout = new QGridLayout(guiFrameExtraction_, 3, 3, 0, 3); EXTRACTION::ExtractionGui* extractionGui = new EXTRACTION::ExtractionGui(guiFrameExtraction_); layout->addWidget(extractionGui, 1, 1); // TODO: add widget for call graph exploration //layout = new QGridLayout(guiFrameExploration_, 3, 3, 0, 3); //EXTRACTION::ExplorationGui* explorationGui = new EXTRACTION::ExtractionGui(guiFrameExploration_); //layout->addWidget(explorationGui, 1, 1); setMode(NOPROJECT); } void Controller::destroy() { // FIXME: disconnect from database } void Controller::modeExtraction() { setMode(EXTRACTION); } void Controller::modeExploration() { setMode(EXPLORATION); } void Controller::newProject() { DialogNewProject* dialog = new DialogNewProject(); dialog->exec(); int result = dialog->result(); delete dialog; if (result == QDialog::Accepted) { guiMenuBar_->setItemEnabled(3, true); guiMenuBar_->setItemEnabled(4, true); } } void Controller::openProject() { PRINT("openProject"); } void Controller::setMode(Mode mode) { if (mode == NOPROJECT && mode_ != NOPROJECT) { guiMenuBar_->setItemEnabled(3, false); guiMenuBar_->setItemEnabled(4, false); guiWidgetStack_->raiseWidget(0); } else if (mode == EXTRACTION && mode_ != EXTRACTION) { guiWidgetStack_->raiseWidget(1); } else if (mode == EXPLORATION && mode_ != EXPLORATION) { guiWidgetStack_->raiseWidget(2); } mode_ = mode; } void Controller::foo() { PRINT("Controller::foo()"); } } //namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/controller.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 955 Text-content-md5: df5e979e81a41a61856a93cc2ee4cd8a Content-length: 965 PROPS-END #ifndef PROJECT_CONTROLLER_H #define PROJECT_CONTROLLER_H #include #include #include namespace CGA { namespace PROJECT { /** * Controller */ class Controller : public QObject { Q_OBJECT public: static Controller* instance(); void registerProjectGui(QMenuBar* menu, QWidgetStack* widgetStack, QFrame* noproject, QFrame* extraction, QFrame* exploration); void destroy(); public slots: void modeExtraction(); void modeExploration(); void newProject(); void openProject(); void foo(); private: enum Mode {UNDEF, NOPROJECT, EXTRACTION, EXPLORATION}; Controller(); void setMode(Mode); static Controller* instance_; QMenuBar* guiMenuBar_; QWidgetStack* guiWidgetStack_; QFrame* guiFrameNoProject_; QFrame* guiFrameExtraction_; QFrame* guiFrameExploration_; Mode mode_; }; } //namespace PROJECT } // namespace CGA #endif //PROJECT_CONTROLLER_H Node-path: trunk/cga/project/projectgui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 7499 Text-content-md5: 4b22c87b56314fd5d73f95e41f0cfddc Content-length: 7509 PROPS-END ProjectGui ProjectGui 0 0 971 904 3 3 0 0 21 172 CGA - Call Graph Analyzer unnamed widgetStack WStackPage 0 unnamed frameNoProject StyledPanel Raised WStackPage 1 unnamed frameExtraction StyledPanel Raised WStackPage 2 unnamed frameExploration StyledPanel Raised MenuBar true projectNewAction New &New Ctrl+N projectOpenAction Open &Open... Ctrl+O projectExitAction Exit E&xit fooFooAction &Foo modeData_ExtractionAction Data &Extraction modeData_ExplorationAction Data E&xploration projectExitAction activated() ProjectGui close() projectgui.ui.h init() destroy() Node-path: trunk/cga/project/projectgui.ui.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1358 Text-content-md5: 07cb1535c7043ca28f4908f6ddd0e0fd Content-length: 1368 PROPS-END /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ #include "controller.h" void ProjectGui::init() { qWarning("init GUI ..."); CGA::PROJECT::Controller* instance = CGA::PROJECT::Controller::instance(); instance->registerProjectGui(MenuBar, widgetStack, frameNoProject, frameExtraction, frameExploration); // signals and slots connections connect(projectOpenAction, SIGNAL(activated()), instance, SLOT(openProject())); connect(projectNewAction, SIGNAL(activated()), instance, SLOT(newProject())); connect(fooFooAction, SIGNAL(activated()), instance, SLOT(foo())); connect(modeData_ExtractionAction, SIGNAL(activated()), instance, SLOT(modeExtraction())); connect(modeData_ExplorationAction, SIGNAL(activated()), instance, SLOT(modeExploration())); } void ProjectGui::destroy() { qWarning("destroy GUI, disconnect from data base..."); CGA::PROJECT::Controller::instance()->destroy(); } Node-path: trunk/cga/storage Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/xmlutil.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 267 Text-content-md5: 461b10189c858c979fdbf28ad42edfab Content-length: 277 PROPS-END #include "xmlutil.h" namespace CGA { QString XMLUtil::transcode(const XMLCh* const chars) { QString result; char* temp = xercesc::XMLString::transcode(chars); result = temp; xercesc::XMLString::release(&temp); return result; } } // namespace CGA Node-path: trunk/cga/xmlutil.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 381 Text-content-md5: 13f3e53d3bf8d5b47e41778e0f68143f Content-length: 391 PROPS-END #ifndef XMLUTIL_H #define XMLUTIL_H #include #include namespace CGA { /** * This is a simple class providing easy (though not terribly * efficient) trancoding of XMLCh data to QString data. */ class XMLUtil { public: static QString transcode(const XMLCh* const chars); }; } // namespace CGA #endif // XMLUTIL_H Node-path: trunk/cga.sln Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1043 Text-content-md5: a398556dda44bbbc60e9722da6efeb93 Content-length: 1053 PROPS-END Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cga", "cga\cga.vcproj", "{7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}" ProjectSection(ProjectDependencies) = postProject EndProjectSection ProjectSection(ProjectDependencies) = postProject EndProjectSection ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.ActiveCfg = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.Build.0 = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.ActiveCfg = Release|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal Node-path: trunk/simple_arch.xml Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 867 Text-content-md5: 77e1d962f7d0e47a68874ccef6a11bd3 Content-length: 877 PROPS-END Revision-number: 8 Prop-content-length: 156 Content-length: 156 K 7 svn:log V 45 remove annotation library for initial version K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:15:33.606555Z PROPS-END Node-path: trunk/cga/cga.vcproj Node-kind: file Node-action: change Text-content-length: 18922 Text-content-md5: 2a016b35956956750f8fa5f04472131d Content-length: 18922 Node-path: trunk/cga/project/controller.cpp Node-kind: file Node-action: change Text-content-length: 2454 Text-content-md5: 564254fea6a814cd3b5268331e41eb26 Content-length: 2454 #include "../config.h" #include "controller.h" #include "uic/projectgui.h" #include "../extraction/extractiongui.h" #include #include #include #include #include #include namespace CGA { namespace PROJECT { Controller* Controller::instance_ = NULL; Controller::Controller() : guiMenuBar_(NULL), guiWidgetStack_(NULL), guiFrameNoProject_(NULL), guiFrameExtraction_(NULL), guiFrameExploration_(NULL), mode_(UNDEF) { } Controller* Controller::instance() { if (!instance_) instance_ = new Controller(); return instance_; } void Controller::registerProjectGui( QMenuBar* menu, QWidgetStack* widgetStack, QFrame* noproject, QFrame* extraction, QFrame* exploration) { guiMenuBar_ = menu; guiWidgetStack_ = widgetStack; guiFrameNoProject_ = noproject; guiFrameExtraction_ = extraction; guiFrameExploration_ = exploration; QGridLayout* layout = new QGridLayout(guiFrameExtraction_, 3, 3, 0, 3); EXTRACTION::ExtractionGui* extractionGui = new EXTRACTION::ExtractionGui(guiFrameExtraction_); layout->addWidget(extractionGui, 1, 1); // TODO: add widget for call graph exploration //layout = new QGridLayout(guiFrameExploration_, 3, 3, 0, 3); //EXTRACTION::ExplorationGui* explorationGui = new EXTRACTION::ExtractionGui(guiFrameExploration_); //layout->addWidget(explorationGui, 1, 1); setMode(NOPROJECT); } void Controller::destroy() { // FIXME: disconnect from database } void Controller::modeExtraction() { setMode(EXTRACTION); } void Controller::modeExploration() { setMode(EXPLORATION); } void Controller::newProject() { PRINT("new project: dummy impl"); guiMenuBar_->setItemEnabled(3, true); guiMenuBar_->setItemEnabled(4, true); setMode(EXTRACTION); } void Controller::openProject() { PRINT("openProject"); } void Controller::setMode(Mode mode) { if (mode == NOPROJECT && mode_ != NOPROJECT) { guiMenuBar_->setItemEnabled(3, false); guiMenuBar_->setItemEnabled(4, false); guiWidgetStack_->raiseWidget(0); } else if (mode == EXTRACTION && mode_ != EXTRACTION) { guiWidgetStack_->raiseWidget(1); } else if (mode == EXPLORATION && mode_ != EXPLORATION) { guiWidgetStack_->raiseWidget(2); } mode_ = mode; } void Controller::foo() { PRINT("Controller::foo()"); } } //namespace PROJECT } // namespace CGA Revision-number: 9 Prop-content-length: 127 Content-length: 127 K 7 svn:log V 16 Initial revision K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T11:22:14.725947Z PROPS-END Node-path: tags/cga-0.1-060918 Node-kind: dir Node-action: add Node-copyfrom-rev: 8 Node-copyfrom-path: trunk Revision-number: 10 Prop-content-length: 119 Content-length: 119 K 7 svn:log V 11 Test-Commit K 10 svn:author V 12 Stefan_Voigt K 8 svn:date V 27 2006-09-18T11:39:07.752517Z PROPS-END Node-path: trunk/cga/extraction/architecture/dialogmodify.cpp Node-kind: file Node-action: change Text-content-length: 415 Text-content-md5: 4b689ae23f17c9e9d24fe6dc3055bd6e Content-length: 415 #include "../../config.h" #include "dialogmodify.h" #include "dialogcreate.h" namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { DialogModify::DialogModify() : DialogModifyGUI(NULL, "", true) { } void DialogModify::foo() { DialogCreate* dialog = new DialogCreate(); dialog->exec(); delete dialog; } } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA Node-path: trunk/cga/extraction/architecture/dialogmodify.h Node-kind: file Node-action: change Text-content-length: 479 Text-content-md5: be826307158a16feea26bf14048a8d6a Content-length: 479 #ifndef EXTRACION_ARCHITECTURE_DIALOGMODIFY_H #define EXTRACION_ARCHITECTURE_DIALOGMODIFY_H #include "uic/dialogmodifygui.h" namespace CGA { namespace EXTRACTION { namespace ARCHITECTURE { /** * */ class DialogModify : public DialogModifyGUI { Q_OBJECT public: DialogModify(); public slots: void foo(); private: }; } //namespace ARCHITECTURE } //namespace EXTRACTION } // namespace CGA #endif // EXTRACION_ARCHITECTURE_DIALOGMODIFY_H Revision-number: 11 Prop-content-length: 197 Content-length: 197 K 7 svn:log V 86 projectmodel added gui for new, open, close project added database communication added K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-18T14:03:22.355982Z PROPS-END Node-path: trunk/HOWTO-postgresql.txt Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 842 Text-content-md5: 267f15721e4cf8acc1f67fffa5a5a7db Content-length: 852 PROPS-END Installation: ------------- Installation instructions for PostgreSQL are found here: http://www.postgresql.org/docs/8.1/interactive/installation.html Afterwards, a database server is running on port 5432 and an initial database named "postgres" is created. Now PostgreSQL needs to be configured for working with CGA: ------------------------------------------------------------------- 1) Change method access for local users (-> 127.0.0.1/32) to "password". Standard was md5. For this, you need to edit the "data/pg_hba.conf" file in the PostgreSQL installation directory. 2) Create a user called "cga" with password "cga". For this, use the command line tool "createuser": createuser -Upostgres -S -d -R -P cga You need to type in the "cga" password twice and the password for the superuser "postgres" once. Node-path: trunk/cga/cga.vcproj Node-kind: file Node-action: change Text-content-length: 26177 Text-content-md5: 679549604604dedf98d8d476a0d0eb16 Content-length: 26177 Node-path: trunk/cga/exception.cpp Node-kind: file Node-action: change Text-content-length: 629 Text-content-md5: c44837602cde11058de99da710ec3c08 Content-length: 629 #include "exception.h" namespace CGA { Exception::Exception(const QString msg) : message_(msg) { } QString Exception::getMessage() { return message_; } FileException::FileException(const QString msg) : Exception(msg) { } DatabaseException::DatabaseException(const QString msg) : Exception(msg) { } DatabaseAlreadyExistsException::DatabaseAlreadyExistsException(const QString msg) : DatabaseException(msg) { } XMLException::XMLException(const QString msg) : Exception(msg) { } TraceFileException::TraceFileException(const QString msg) : Exception(msg) { } } // namespace CGA Node-path: trunk/cga/exception.h Node-kind: file Node-action: change Text-content-length: 1135 Text-content-md5: d918df12e29c7e1584669fc9a318a0e4 Content-length: 1135 #ifndef EXCEPTION_H #define EXCEPTION_H #include namespace CGA { /** * Base class for Exceptions */ class Exception { public: Exception(const QString msg = ""); QString getMessage(); private: QString message_; }; /** * Exception handling file errors */ class FileException : public Exception { public: FileException(const QString msg = ""); }; /** * Exception handling database errors */ class DatabaseException : public Exception { public: DatabaseException(const QString msg = ""); }; /** * Exception handling database error, that occurs if trying to create a database that already exists */ class DatabaseAlreadyExistsException : public DatabaseException { public: DatabaseAlreadyExistsException(const QString msg = ""); }; /** * Exception handling XML errors */ class XMLException : public Exception { public: XMLException(const QString msg = ""); }; /** * Exception handling TraceFile errors */ class TraceFileException : public Exception { public: TraceFileException(const QString msg = ""); }; } // namespace CGA #endif // EXCEPTION_H Node-path: trunk/cga/project/controller.cpp Node-kind: file Node-action: change Text-content-length: 2637 Text-content-md5: be95f40008a37449aa8edb772015f0ce Content-length: 2637 #include "../config.h" #include "controller.h" #include "dialognewproject.h" #include "dialogopenproject.h" #include "projectmodel.h" #include "uic/projectgui.h" #include "../extraction/extractiongui.h" #include "../storage/databasewrapper.h" #include // for debugging purposes #include "../extraction/architecture/dialogmodify.h" using VRS::SO; namespace CGA { namespace PROJECT { Controller* Controller::instance_ = NULL; Controller::Controller() : projectGui_(NULL), mode_(UNDEF) { } Controller* Controller::instance() { if (!instance_) instance_ = new Controller(); return instance_; } void Controller::destroyController() { STORAGE::DatabaseWrapper::disconnectDB(); if (instance_) delete instance_; } void Controller::registerProjectGui(ProjectGui* projectGui) { projectGui_ = projectGui; QFrame* frame = projectGui_->getFrameExtraction(); QGridLayout* layout = new QGridLayout(frame, 3, 3, 0, 3); EXTRACTION::ExtractionGui* extractionGui = new EXTRACTION::ExtractionGui(frame); layout->addWidget(extractionGui, 1, 1); setMode(NOPROJECT); } void Controller::modeExtraction() { setMode(EXTRACTION); } void Controller::modeExploration() { setMode(EXPLORATION); } void Controller::newProject() { closeProject(); DialogNewProject* dialog = new DialogNewProject(); SO model = dialog->createNewProject(); if (model != NULL) { projectGui_->setCaption("CGA - Call Graph Analyzer : " + model->getProjectName()); setMode(EXTRACTION); } } void Controller::openProject() { closeProject(); DialogOpenProject* dialog = new DialogOpenProject(); SO model = dialog->openProject(); if (model != NULL) { projectGui_->setCaption("CGA - Call Graph Analyzer : " + model->getProjectName()); setMode(EXPLORATION); } } void Controller::closeProject() { STORAGE::DatabaseWrapper::disconnectDB(); setMode(NOPROJECT); } void Controller::setMode(Mode mode) { if (mode == NOPROJECT && mode_ != NOPROJECT) { projectGui_->setCaption("CGA - Call Graph Analyzer : no project"); projectGui_->setMode(0 /*no project*/); } else if (mode == EXTRACTION && mode_ != EXTRACTION) { projectGui_->setMode(1 /*extraction*/); } else if (mode == EXPLORATION && mode_ != EXPLORATION) { projectGui_->setMode(2 /*exploration*/); } mode_ = mode; } void Controller::foo() { PRINT("Controller::foo()"); EXTRACTION::ARCHITECTURE::DialogModify* dialog = new EXTRACTION::ARCHITECTURE::DialogModify(); dialog->exec(); delete dialog; } } //namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/controller.h Node-kind: file Node-action: change Text-content-length: 802 Text-content-md5: 1091b46f75566c363d2a6a54d8096c1a Content-length: 802 #ifndef PROJECT_CONTROLLER_H #define PROJECT_CONTROLLER_H #include #include #include class ProjectGui; namespace CGA { namespace PROJECT { /** * Controller */ class Controller : public QObject { Q_OBJECT public: static Controller* instance(); static void destroyController(); void registerProjectGui(ProjectGui*); public slots: void modeExtraction(); void modeExploration(); void newProject(); void openProject(); void closeProject(); void foo(); private: enum Mode {UNDEF, NOPROJECT, EXTRACTION, EXPLORATION}; Controller(); void setMode(Mode); static Controller* instance_; ProjectGui* projectGui_; Mode mode_; }; } //namespace PROJECT } // namespace CGA #endif //PROJECT_CONTROLLER_H Node-path: trunk/cga/project/dialognewproject.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2340 Text-content-md5: 3692b5a866df8397772a97045aa3e5b1 Content-length: 2350 PROPS-END #include "../config.h" #include "dialognewproject.h" #include "projectmodel.h" #include "../storage/extraction/databaseinitializer.h" #include "../exception.h" #include #include #include #include #include using VRS::SO; namespace CGA { namespace PROJECT { const QString DialogNewProject::CGAUSER = "cga"; const QString DialogNewProject::CGAPASS = "cga"; DialogNewProject::DialogNewProject() : DialogNewProjectGUI(NULL, "", true) { QRegExp exp("^[a-z][a-z0-9]{0,32}$"); lineEditName->setValidator(new QRegExpValidator(exp, this)); QRegExp exp2("^[0-9]{1,6}$"); lineEditPort->setValidator(new QRegExpValidator(exp2, this)); // default values lineEditHost->setText("localhost"); lineEditPort->setText("5432"); } VRS::SO DialogNewProject::createNewProject() { exec(); if (result() == Rejected) return NULL; // else SO model = new ProjectModel( lineEditName->text(), lineEditFolder->text(), lineEditHost->text(), lineEditPort->text().toUInt(), CGAUSER, CGAPASS); return model; } void DialogNewProject::folder() { QString dir = QFileDialog::getExistingDirectory( QDir::currentDirPath(), this, "getDirDialog", "Choose project folder"); if (dir == QString::null) return; lineEditFolder->setText(dir); } void DialogNewProject::ok() { if (lineEditFolder->text().isEmpty() || lineEditName->text().isEmpty() || lineEditHost->text().isEmpty() || lineEditPort->text().isEmpty()) { QMessageBox::information(this, "Information missing", "Fill out all fields."); return; } try { STORAGE::EXTRACTION::DatabaseInitializer::createAndInitialize( lineEditName->text(), lineEditHost->text(), lineEditPort->text().toUInt(), CGAUSER, CGAPASS); } catch (DatabaseAlreadyExistsException* ) { QMessageBox::information(this, "Database error", "Database named '"+lineEditName->text()+"' already exists.\nChoose a different name."); return; } catch (DatabaseException* e) { QMessageBox::information(this, "Database error", "Database error:\n"+ e->getMessage()); return; } accept(); } void DialogNewProject::cancel() { reject(); } } //namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/dialognewproject.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 614 Text-content-md5: 651ffa466e9edf38dfd6d42366ab90da Content-length: 624 PROPS-END #ifndef PROJECT_DIALOGNEWPROJECT_H #define PROJECT_DIALOGNEWPROJECT_H #include "uic/dialognewprojectgui.h" #include namespace CGA { namespace PROJECT { class ProjectModel; /** * DialogNewProject */ class DialogNewProject : public DialogNewProjectGUI { Q_OBJECT public: DialogNewProject(); VRS::SO createNewProject(); public slots: void folder(); void ok(); void cancel(); private: static const QString CGAUSER; static const QString CGAPASS; }; } //namespace EXTRACTION } // namespace CGA #endif // PROJECT_DIALOGNEWPROJECT_H Node-path: trunk/cga/project/dialognewprojectgui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 11667 Text-content-md5: b3d1923b617075724066d14d35f78545 Content-length: 11677 PROPS-END DialogNewProjectGUI DialogNewProjectGUI 0 0 331 277 5 5 0 0 New Project unnamed 3 textLabel1 5 0 0 0 project settings textLabel7 0 5 0 0 port textLabel6 0 5 0 0 host toolButtonFolder 0 0 0 0 StrongFocus ... textLabel3 0 5 0 0 name lineEditName LineEditPanel Sunken textLabel4 0 5 0 0 folder lineEditFolder NoFocus true lineEditHost lineEditPort line2 HLine Sunken Horizontal spacer3 Horizontal Expanding 170 21 pushButtonOK 0 0 0 0 OK pushButtonCancel 0 0 0 0 Cancel spacer1 Horizontal Expanding 32000 20 line1 HLine Sunken Horizontal textLabel2 5 0 0 0 database server settings spacer2 Horizontal Expanding 170 20 pushButtonCancel clicked() DialogNewProjectGUI cancel() pushButtonOK clicked() DialogNewProjectGUI ok() toolButtonFolder clicked() DialogNewProjectGUI folder() lineEditName toolButtonFolder lineEditHost lineEditPort pushButtonOK pushButtonCancel lineEditFolder ok() cancel() folder() Node-path: trunk/cga/project/dialogopenproject.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1339 Text-content-md5: 470974d520a6d6ed736204d14c887715 Content-length: 1349 PROPS-END #include "../config.h" #include "dialogopenproject.h" #include "projectmodel.h" #include "../storage/extraction/databaseinitializer.h" #include "../exception.h" #include #include #include using VRS::SO; namespace CGA { namespace PROJECT { DialogOpenProject::DialogOpenProject() : DialogOpenProjectGUI(NULL, "", true) { } VRS::SO DialogOpenProject::openProject() { exec(); if (result() == Rejected) return NULL; // else SO model = NULL; try { model = ProjectModel::loadFromXML(lineEditFile->text()); } catch (Exception*) { QMessageBox::information(this, "Open error", "No valid 'project.xml' file found."); return NULL; } return model; } void DialogOpenProject::file() { QString file = QFileDialog::getOpenFileName( QDir::currentDirPath(), "Project (project.xml)", this, "openFileDialog", "Choose project file"); if (file == QString::null) return; lineEditFile->setText(file); } void DialogOpenProject::ok() { if (lineEditFile->text().isEmpty()) { QMessageBox::information(this, "Information missing", "Please choose project file."); return; } accept(); } void DialogOpenProject::cancel() { reject(); } } //namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/dialogopenproject.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 551 Text-content-md5: a5ff891cf4643125c99c35d5140ae6f9 Content-length: 561 PROPS-END #ifndef PROJECT_DIALOGOPENPROJECT_H #define PROJECT_DIALOGOPENPROJECT_H #include "uic/dialogopenprojectgui.h" #include namespace CGA { namespace PROJECT { class ProjectModel; /** * DialogOpenProject */ class DialogOpenProject : public DialogOpenProjectGUI { Q_OBJECT public: DialogOpenProject(); VRS::SO openProject(); public slots: void file(); void ok(); void cancel(); private: }; } //namespace EXTRACTION } // namespace CGA #endif // PROJECT_DIALOGOPENPROJECT_H Node-path: trunk/cga/project/dialogopenprojectgui.ui Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 5558 Text-content-md5: 0a46e8363d037f33c181a0bc7124454e Content-length: 5568 PROPS-END DialogOpenProjectGUI DialogOpenProjectGUI 0 0 358 70 5 5 0 0 Open Project unnamed 3 textLabel3 0 5 0 0 project xml file spacer1 Horizontal Expanding 32000 20 lineEditFile LineEditPanel Sunken true pushButtonOK 0 0 0 0 OK pushButtonCancel 0 0 0 0 Cancel toolButtonFile 0 0 0 0 StrongFocus ... toolButtonFile clicked() DialogOpenProjectGUI file() pushButtonOK clicked() DialogOpenProjectGUI ok() pushButtonCancel clicked() DialogOpenProjectGUI cancel() lineEditFile toolButtonFile pushButtonOK pushButtonCancel ok() cancel() file() Node-path: trunk/cga/project/projectgui.ui Node-kind: file Node-action: change Text-content-length: 8036 Text-content-md5: e826cdf78e9695567a425d6f41af1e85 Content-length: 8036 ProjectGui ProjectGui 0 0 971 919 3 3 0 0 21 196 CGA - Call Graph Analyzer unnamed widgetStack WStackPage 0 unnamed frameNoProject StyledPanel Raised WStackPage 1 unnamed frameExtraction StyledPanel Raised WStackPage 2 unnamed frameExploration StyledPanel Raised MenuBar true projectNewAction New &New Ctrl+N projectOpenAction Open &Open... Ctrl+O projectExitAction Exit E&xit fooFooAction &Foo modeData_ExtractionAction Data &Extraction modeData_ExplorationAction Data E&xploration projectCloseAction &Close projectExitAction activated() ProjectGui close() projectgui.ui.h init() destroy() setMode(int) getFrameNoProject() getFrameExtraction() getFrameExploration() Node-path: trunk/cga/project/projectgui.ui.h Node-kind: file Node-action: change Text-content-length: 2319 Text-content-md5: fcc0818a7ca728832496c1f4b5f2f426 Content-length: 2319 /**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you wish to add, delete or rename functions or slots use ** Qt Designer which will update this file, preserving your code. Create an ** init() function in place of a constructor, and a destroy() function in ** place of a destructor. *****************************************************************************/ #include "controller.h" void ProjectGui::init() { qWarning("init GUI ..."); CGA::PROJECT::Controller* instance = CGA::PROJECT::Controller::instance(); instance->registerProjectGui(this); // signals and slots connections connect(projectNewAction, SIGNAL(activated()), instance, SLOT(newProject())); connect(projectOpenAction, SIGNAL(activated()), instance, SLOT(openProject())); connect(projectCloseAction, SIGNAL(activated()), instance, SLOT(closeProject())); connect(fooFooAction, SIGNAL(activated()), instance, SLOT(foo())); connect(modeData_ExtractionAction, SIGNAL(activated()), instance, SLOT(modeExtraction())); connect(modeData_ExplorationAction, SIGNAL(activated()), instance, SLOT(modeExploration())); } void ProjectGui::destroy() { qWarning("destroy GUI, disconnect from data base..."); CGA::PROJECT::Controller::destroyController(); } QFrame* ProjectGui::getFrameNoProject() { return frameNoProject; } QFrame* ProjectGui::getFrameExtraction() { return frameExtraction; } QFrame* ProjectGui::getFrameExploration() { return frameExploration; } /*! mode==0: no project * mode==1: extraction mode * mode==2: exploration mode */ void ProjectGui::setMode(int mode) { widgetStack->raiseWidget(mode); if (mode == 0) { // no project projectCloseAction->setEnabled(false); modeData_ExtractionAction->setEnabled(false); modeData_ExplorationAction->setEnabled(false); } else if (mode == 1) { // extraction mode projectCloseAction->setEnabled(true); modeData_ExtractionAction->setEnabled(true); modeData_ExplorationAction->setEnabled(true); } else if (mode == 2) { // exploration mode projectCloseAction->setEnabled(true); modeData_ExtractionAction->setEnabled(true); modeData_ExplorationAction->setEnabled(true); } } Node-path: trunk/cga/project/projectmodel.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2847 Text-content-md5: a004456cf45b95873646743f0b9ad9d7 Content-length: 2857 PROPS-END #include "../config.h" #include "projectmodel.h" #include "projectmodelxmlreader.h" #include "../storage/databasewrapper.h" #include "../exception.h" #include "../xmlutil.h" #include #include #include #include #include using VRS::SO; namespace CGA { namespace PROJECT { ProjectModel::ProjectModel( QString projectName, QString projectFolder, QString databaseHost, unsigned int databasePort, QString databaseUser, QString databasePass) : projectName_(projectName), projectFolder_(projectFolder), databaseHost_(databaseHost), databasePort_(databasePort), databaseUser_(databaseUser), databasePass_(databasePass) { init(); QDir::setCurrent(projectFolder_); saveToXML(); } void ProjectModel::init() { } void ProjectModel::saveToXML() { QDir::setCurrent(projectFolder_); // check file QString file = "project.xml"; QFile f(file); if (!f.open(IO_WriteOnly)) { throw FileException("Can not open file for writing: " + file); } QTextStream stream(&f); stream.precision(9); // // head // stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n"; // // close file // f.close(); } VRS::SO ProjectModel::loadFromXML(QString file) { QString projectName; QString databaseHost; unsigned int databasePort; QString databaseUser; QString databasePass; QFileInfo info(file); QString projectFolder = info.dirPath(true); QDir::setCurrent(projectFolder); SO model = NULL; try { ProjectModelXMLReader::read( file, &projectName, &databaseHost, &databasePort, &databaseUser, &databasePass); model = new ProjectModel( projectName, projectFolder, databaseHost, databasePort, databaseUser, databasePass); STORAGE::DatabaseWrapper::connectDB( projectName, databaseHost, databasePort, databaseUser, databasePass); } catch (DatabaseException*) { QMessageBox::information(NULL, "Database error", "Could not establish connection to database."); return NULL; } return model; } } // namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/projectmodel.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1025 Text-content-md5: 9c6e1ab897f41dc906ad21c0d128bb09 Content-length: 1035 PROPS-END #ifndef PROJECT_PROJECTMODEL_H #define PROJECT_PROJECTMODEL_H #include #include namespace CGA { namespace PROJECT { /** * ProjectModel */ class ProjectModel : public VRS::SharedObj { public: ProjectModel( QString projectName, QString projectFolder, QString databaseHost, unsigned int databasePort, QString databaseUser, QString databasePass); /// throws Exception void saveToXML(); static VRS::SO loadFromXML(QString file); // //////////////////////////////////////////////////////////////////////// // getter methods // //////////////////////////////////////////////////////////////////////// QString getProjectName() const {return projectName_;} private: void init(); QString projectName_; QString projectFolder_; QString databaseHost_; unsigned int databasePort_; QString databaseUser_; QString databasePass_; }; } // namespace PROJECT } // namespace CGA #endif //PROJECT_PROJECTMODEL_H Node-path: trunk/cga/project/projectmodelxmlhandler.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2619 Text-content-md5: fa412539a92a066a89f9407c39fee33f Content-length: 2629 PROPS-END #include "../config.h" #include "projectmodelxmlhandler.h" #include "../exception.h" #include "../xmlutil.h" #include using VRS::SO; namespace CGA { namespace PROJECT { ProjectModelXMLHandler::ProjectModelXMLHandler( QString* outProjectName, QString* outPatabaseHost, unsigned int* outDatabasePort, QString* outDatabaseUser, QString* outDatabasePass) : outProjectName_(outProjectName), outPatabaseHost_(outPatabaseHost), outDatabasePort_(outDatabasePort), outDatabaseUser_(outDatabaseUser), outDatabasePass_(outDatabasePass) { } ProjectModelXMLHandler::~ProjectModelXMLHandler() { } void ProjectModelXMLHandler::endDocument() { } void ProjectModelXMLHandler::characters(const XMLCh* const chars, const unsigned int length) { } void ProjectModelXMLHandler::ignorableWhitespace(const XMLCh* const chars, const unsigned int length) { } void ProjectModelXMLHandler::processingInstruction(const XMLCh* const target, const XMLCh* const data) { } void ProjectModelXMLHandler::startDocument() { } void ProjectModelXMLHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname) { } void ProjectModelXMLHandler::startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const xercesc::Attributes& attributes) { QString e = XMLUtil::transcode(localname); if (e == "project") { QString name = XMLUtil::transcode(attributes.getValue((unsigned int)0)); *outProjectName_ = name; return; } if (e == "database") { QString host = XMLUtil::transcode(attributes.getValue((unsigned int)0)); unsigned int port = XMLUtil::transcode(attributes.getValue((unsigned int)1)).toUInt(); QString user = XMLUtil::transcode(attributes.getValue((unsigned int)2)); QString pass = XMLUtil::transcode(attributes.getValue((unsigned int)3)); *outPatabaseHost_ = host; *outDatabasePort_ = port; *outDatabaseUser_ = user; *outDatabasePass_ = pass; return; } } void ProjectModelXMLHandler::warning(const xercesc::SAXParseException& exc) { throw XMLException("XML warning: " + XMLUtil::transcode(exc.getMessage())); } void ProjectModelXMLHandler::error(const xercesc::SAXParseException& exc) { throw XMLException("XML error: " + XMLUtil::transcode(exc.getMessage())); } void ProjectModelXMLHandler::fatalError(const xercesc::SAXParseException& exc) { throw XMLException("XML fatalError: " + XMLUtil::transcode(exc.getMessage())); } } // namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/projectmodelxmlhandler.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1599 Text-content-md5: fb3d28c99d8834ad37d32f3a07e4df0d Content-length: 1609 PROPS-END #ifndef PROJECT_PROJECTMODELXMLHANDLER_H #define PROJECT_PROJECTMODELXMLHANDLER_H #include #include #include namespace CGA { namespace PROJECT { /** * ProjectModelXMLHandler is used by ProjectModelXMLReader to create an ProjectProjectModel from an XML file */ class ProjectModelXMLHandler : public xercesc::DefaultHandler { public: ProjectModelXMLHandler( QString* outProjectName, QString* outPatabaseHost, unsigned int* outDatabasePort, QString* outDatabaseUser, QString* outDatabasePass); virtual ~ProjectModelXMLHandler(); private: void endDocument(); void endElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname); void characters(const XMLCh* const chars, const unsigned int length); void ignorableWhitespace(const XMLCh* const chars, const unsigned int length); void processingInstruction(const XMLCh* const target, const XMLCh* const data); void startDocument(); void startElement( const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const xercesc::Attributes& attributes); void warning(const xercesc::SAXParseException& exc); void error(const xercesc::SAXParseException& exc); void fatalError(const xercesc::SAXParseException& exc); private: QString* outProjectName_; QString* outPatabaseHost_; unsigned int* outDatabasePort_; QString* outDatabaseUser_; QString* outDatabasePass_; }; } // namespace PROJECT } // namespace CGA #endif // PROJECT_PROJECTMODELXMLHANDLER_H Node-path: trunk/cga/project/projectmodelxmlreader.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1664 Text-content-md5: 091c254270c28e6e9f5f8a7f36f463a2 Content-length: 1674 PROPS-END #include "../config.h" #include "projectmodelxmlreader.h" #include "projectmodelxmlhandler.h" #include "../exception.h" #include #include #include #include namespace CGA { namespace PROJECT { ProjectModelXMLReader::ProjectModelXMLReader() { } void ProjectModelXMLReader::read( QString xmlfile, QString* outProjectName, QString* outPatabaseHost, unsigned int* outDatabasePort, QString* outDatabaseUser, QString* outDatabasePass) { // check file QFile f(xmlfile); if (!f.exists() || !f.open(IO_ReadOnly)) { throw FileException("Can not open file " + xmlfile); } // Initialize the XML4C2 system try { xercesc::XMLPlatformUtils::Initialize(); } catch (const xercesc::XMLException&) { throw XMLException("Can not initialize XML parser."); } xercesc::SAX2XMLReader* parser = xercesc::XMLReaderFactory::createXMLReader(); parser->setFeature(xercesc::XMLUni::fgSAX2CoreValidation, false); parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpaces, true); parser->setFeature(xercesc::XMLUni::fgXercesSchema, false); parser->setFeature(xercesc::XMLUni::fgXercesSchemaFullChecking, false); parser->setFeature(xercesc::XMLUni::fgSAX2CoreNameSpacePrefixes, false); ProjectModelXMLHandler handler( outProjectName, outPatabaseHost, outDatabasePort, outDatabaseUser, outDatabasePass); parser->setContentHandler(&handler); parser->parse(xmlfile.ascii()); delete parser; xercesc::XMLPlatformUtils::Terminate(); } } // namespace PROJECT } // namespace CGA Node-path: trunk/cga/project/projectmodelxmlreader.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 707 Text-content-md5: 57054754353701b73e5a244cb1d4695c Content-length: 717 PROPS-END #ifndef PROJECT_PROJECTMODELXMLREADER_H #define PROJECT_PROJECTMODELXMLREADER_H #include #include namespace CGA { namespace PROJECT { class ProjectModel; /** * ProjectModelXMLReader has the static method read to create an ProjectModel from an XML file */ class ProjectModelXMLReader { public: // throws FileException, XMLException static void read( QString xmlfile, QString* outProjectName, QString* outPatabaseHost, unsigned int* outDatabasePort, QString* outDatabaseUser, QString* outDatabasePass); private: ProjectModelXMLReader(); }; } // namespace PROJECT } // namespace CGA #endif // PROJECT_PROJECTMODELXMLREADER_H Node-path: trunk/cga/storage/databasewrapper.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3349 Text-content-md5: b4a3fdb31681e0be0b819bfbb9366b1f Content-length: 3359 PROPS-END #include "../config.h" #include "databasewrapper.h" #include "../exception.h" using VRS::SO; namespace CGA { namespace STORAGE { DatabaseWrapper* DatabaseWrapper::instance_ = NULL; DatabaseWrapper* DatabaseWrapper::instance() { if (!instance_) throw new DatabaseException("Database is not connected"); return instance_; } void DatabaseWrapper::createDatabase(QString databasename, QString host, unsigned int port, QString user, QString pass) { QString conninfo("host="+host+" port="+QString::number(port)+" dbname=postgres user="+user+" password="+pass); PGconn* conn = PQconnectdb(conninfo.ascii()); if (PQstatus(conn) != CONNECTION_OK) { throw new DatabaseException("Connection to database postgres failed: " + QString(PQerrorMessage(conn)) + "\n" + conninfo); } QString cmd = "SELECT datname FROM pg_database;"; PGresult* res = PQexec(conn, cmd); if (PQresultStatus(res) != PGRES_TUPLES_OK) { QString error = PQerrorMessage(conn); PQclear(res); throw new DatabaseException(error + "\n" + cmd); } int i, iMax = PQntuples(res); for (i=0; iconn_) { PQfinish(instance_->conn_); instance_->conn_ = NULL; } delete instance_; instance_ = NULL; } void DatabaseWrapper::execCommand(QString cmd) { PGresult* res = PQexec(conn_, cmd); if (PQresultStatus(res) != PGRES_COMMAND_OK) { PQclear(res); QString error = PQerrorMessage(conn_); throw new DatabaseException(error + "\n" + cmd); } PQclear(res); } PGresult* DatabaseWrapper::execTupleCommand(QString cmd) { // TODO: encapsulate results //PGresult* res = PQexec(conn_, cmd); //if (PQresultStatus(res) != PGRES_TUPLES_OK) //{ // QString error = PQerrorMessage(conn_); // PQclear(res); // throw new DatabaseException(error + "\n" + cmd); //} //return res; return NULL; } } // namespace STORAGE } // namespace CGA Node-path: trunk/cga/storage/databasewrapper.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1074 Text-content-md5: 9228f2c60822662f2fb9be0e45f9bd24 Content-length: 1084 PROPS-END #ifndef STORAGE_DATABASEWRAPPER_H #define STORAGE_DATABASEWRAPPER_H #include #include #include #include namespace CGA { namespace STORAGE { /** * DatabaseWrapper */ class DatabaseWrapper { public: static DatabaseWrapper* instance(); /// throws DatabaseException static void createDatabase( QString databasename, QString host, unsigned int port, QString user, QString pass); /*! throws DatabaseException * creates an instance of DatabaseWrapper that is accessible with instance() */ static void connectDB( QString databasename, QString host, unsigned int port, QString user, QString pass); static void disconnectDB(); void execCommand(QString cmd); // FIXME: return result in an encapsulated way PGresult* execTupleCommand(QString cmd); private: DatabaseWrapper(); static DatabaseWrapper* instance_; PGconn* conn_; }; } // namespace STORAGE } // namespace CGA #endif // STORAGE_DATABASEWRAPPER_H Node-path: trunk/cga/storage/exploration Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/storage/extraction Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/cga/storage/extraction/databaseinitializer.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 3348 Text-content-md5: 2adbec3d14b104a61aae96cb22000150 Content-length: 3358 PROPS-END #include "../../config.h" #include "databaseinitializer.h" using VRS::SO; namespace CGA { namespace STORAGE { namespace EXTRACTION { DatabaseInitializer::DatabaseInitializer() { VRS_Error(false, "no instance"); } void DatabaseInitializer::createAndInitialize( QString databasename, QString host, unsigned int port, QString user, QString pass) { create(databasename, host, port, user, pass); init(databasename, host, port, user, pass); } void DatabaseInitializer::create( QString databasename, QString host, unsigned int port, QString user, QString pass) { DatabaseWrapper::createDatabase( databasename, host, port, user, pass); } void DatabaseInitializer::init( QString databasename, QString host, unsigned int port, QString user, QString pass) { DatabaseWrapper::connectDB( databasename, host, port, user, pass); QString cmd = "CREATE TABLE fl2name (\ fl int8 not null primary key,\ name varchar(512) not null);\ CREATE INDEX fl2name_name_idx ON fl2name (name);\ CREATE TABLE elf2name (\ elf int8 not null primary key, \ name varchar(512) not null,\ issystemlib int not null,\ archcomp int8 not null);\ CREATE INDEX elf2name_name_idx ON elf2name (name);\ CREATE TABLE functions (\ fn int8 not null primary key,\ fl int8 not null REFERENCES fl2name (fl), \ elf int8 not null REFERENCES elf2name (elf),\ name varchar(512) not null,\ shortname varchar(512) not null);\ CREATE INDEX functions_name_idx ON functions (name);\ CREATE SEQUENCE idfn;\ CREATE SEQUENCE idfl;\ CREATE SEQUENCE idelf;\ CREATE SEQUENCE idarch;\ CREATE SEQUENCE idfeat;\ CREATE SEQUENCE idtrace;\ CREATE TABLE archcomps (\ comp int8 not null primary key,\ parent int8 REFERENCES archcomps (comp),\ name varchar(128),\ fullname varchar(512),\ hierarchydepth int);\ CREATE INDEX archcomps_comp_idx ON archcomps (comp);\ CREATE INDEX archcomps_parent_idx ON archcomps (parent);\ INSERT INTO archcomps(comp) VALUES (" + QString::number(UNDEF_ID) + ");\ CREATE TABLE archenv (\ type varchar(32) not null primary key,\ comp int8 not null REFERENCES archcomps (comp));\ INSERT INTO archenv VALUES ('undef', " + QString::number(UNDEF_ID) + ");\ CREATE TABLE archdirs (\ dir int8 not null primary key,\ parent int8 REFERENCES archdirs (dir),\ name varchar(128),\ comp int8 REFERENCES archcomps (comp));\ CREATE INDEX archdirs_dir_idx ON archdirs (dir);\ CREATE INDEX archdirs_parent_idx ON archdirs (parent);\ CREATE TABLE archdirenv (\ type varchar(32) not null primary key,\ dir int8 not null REFERENCES archdirs (dir));\ CREATE TABLE funcarchmapping (\ fn int8 not null primary key REFERENCES functions (fn),\ comp int8 not null);\ CREATE TABLE features (\ id int8 not null primary key,\ name varchar(128),\ description varchar(1024));\ CREATE TABLE traces (\ id int8 not null primary key,\ name varchar(128),\ description varchar(1024),\ featureid int8 REFERENCES features (id));\ CREATE INDEX traces_featureid_idx ON traces (featureid);\ "; DatabaseWrapper::instance()->execCommand(cmd); } } // namespace EXTRACTION } // namespace STORAGE } // namespace CGA Node-path: trunk/cga/storage/extraction/databaseinitializer.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 851 Text-content-md5: ea0595872dc340f5e235aed7b119af47 Content-length: 861 PROPS-END #ifndef STORAGE_EXTRACTION_DATABASEINITIALIZER_H #define STORAGE_EXTRACTION_DATABASEINITIALIZER_H #include "../databasewrapper.h" namespace CGA { namespace STORAGE { namespace EXTRACTION { /** * DatabaseInitializer */ class DatabaseInitializer { public: static void createAndInitialize( QString databasename, QString host = "localhost", unsigned int port = 5432, QString user = "cga", QString pass = "cga"); private: DatabaseInitializer(); static void create( QString databasename, QString host, unsigned int port, QString user, QString pass); static void init( QString databasename, QString host, unsigned int port, QString user, QString pass); }; } // namespace EXTRACTION } // namespace STORAGE } // namespace CGA #endif // STORAGE_EXTRACTION_DATABASEINITIALIZER_H Node-path: trunk/cga/xmlutil.cpp Node-kind: file Node-action: change Text-content-length: 840 Text-content-md5: 51e2e043a8a7d8ef18e07dd0a83cdb21 Content-length: 840 #include "xmlutil.h" namespace CGA { QString XMLUtil::transcode(const XMLCh* const chars) { QString result; char* temp = xercesc::XMLString::transcode(chars); result = temp; xercesc::XMLString::release(&temp); return result; } QString XMLUtil::transformSpecialChars(std::string str) { QString clean = str.c_str(); clean.replace(QChar('&'), "&"); clean.replace(QChar(39), "'"); clean.replace(QChar('<'), "<"); clean.replace(QChar('>'), ">"); clean.replace(QChar('"'), """); clean.replace(QChar(''), "Ä"); clean.replace(QChar(''), "Ö"); clean.replace(QChar(''), "Ü"); clean.replace(QChar(''), "ä"); clean.replace(QChar(''), "ö"); clean.replace(QChar(''), "ü"); clean.replace(QChar(''), "ß"); return clean; } } // namespace CGA Node-path: trunk/cga/xmlutil.h Node-kind: file Node-action: change Text-content-length: 438 Text-content-md5: 3a79e8bfd5926febcc1b8746b3516588 Content-length: 438 #ifndef XMLUTIL_H #define XMLUTIL_H #include #include namespace CGA { /** * This is a simple class providing easy (though not terribly * efficient) trancoding of XMLCh data to QString data. */ class XMLUtil { public: static QString transcode(const XMLCh* const chars); static QString transformSpecialChars(std::string str); }; } // namespace CGA #endif // XMLUTIL_H Node-path: trunk/environmentvars.txt Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 359 Text-content-md5: 0237cb9e1859f873bb733a12d1c6ac75 Content-length: 369 PROPS-END Environment variables that need to be set: ------------------------------------------ VRS_HOME -> vrs-project includes&libs (www.vrs3d.org) [$(VRS_HOME)/include and $(VRS_HOME)/lib] POSTGRESQL -> PostgreSQL database includes&libs (www.postgresql.org) QTDIR -> qt3 includes&libs XERCES_HOME -> Xerces XML-parser includes&libs (xml.apache.org/xerces-c) Revision-number: 12 Prop-content-length: 144 Content-length: 144 K 7 svn:log V 33 Support for MS Visual Studio 2005 K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-20T09:40:38.392142Z PROPS-END Node-path: trunk/HOWTO-postgresql.txt Node-kind: file Node-action: change Text-content-length: 998 Text-content-md5: 5a501ff30bbf774a13a05881e6692bc0 Content-length: 998 Installation: ------------- Installation instructions for PostgreSQL are found here: http://www.postgresql.org/docs/8.1/interactive/installation.html Note, that you need to install the binary&configuration files to run the server AND include&library files to build CGA with PostgreSQL-support afterwards. Afterwards, a database server is running on port 5432 and an initial database named "postgres" is created. Now PostgreSQL needs to be configured for working with CGA: ------------------------------------------------------------------- 1) Change method access for local users (-> 127.0.0.1/32) to "password". Standard was md5. For this, you need to edit the "data/pg_hba.conf" file in the PostgreSQL installation directory. 2) Create a user called "cga" with password "cga". For this, use the command line tool "createuser": createuser -Upostgres -S -d -R -P cga You need to type in the "cga" password twice and the password for the superuser "postgres" once. Node-path: trunk/cga/cga-vs2003.vcproj Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 26177 Text-content-md5: 679549604604dedf98d8d476a0d0eb16 Content-length: 26187 PROPS-END Node-path: trunk/cga/cga-vs2005.vcproj Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 27915 Text-content-md5: 25c7722f609552beb0cd064da13b2b13 Content-length: 27925 PROPS-END Node-path: trunk/cga/cga.vcproj Node-action: delete Node-path: trunk/cga-vs2003.sln Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 906 Text-content-md5: c70039f47f63d673944562740e439fa8 Content-length: 916 PROPS-END Microsoft Visual Studio Solution File, Format Version 8.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cga", "cga\cga-vs2003.vcproj", "{7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.ActiveCfg = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug.Build.0 = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.ActiveCfg = Release|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal Node-path: trunk/cga-vs2005.sln Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 876 Text-content-md5: 650317e06fcc58bb9be613f6ce433943 Content-length: 886 PROPS-END Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cga", "cga\cga-vs2005.vcproj", "{7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug|Win32.ActiveCfg = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug|Win32.Build.0 = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release|Win32.ActiveCfg = Release|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Node-path: trunk/cga.sln Node-action: delete Revision-number: 13 Prop-content-length: 110 Content-length: 110 K 7 svn:log V 0 K 10 svn:author V 15 Johannes_Bohnet K 8 svn:date V 27 2006-09-20T12:32:14.752632Z PROPS-END Node-path: trunk/cga/cga-vs2005.vcproj Node-kind: file Node-action: change Text-content-length: 28349 Text-content-md5: add992924c8d2d3bf8540110e30f4b4d Content-length: 28349 Node-path: trunk/cga-devel-example-bohnet.bat Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 402 Text-content-md5: 7b4292d1e7708481f0c9a1592bd2d86e Content-length: 412 PROPS-END SET CGA_HOME=e:\projects\cga SET VRS_HOME=e:\projects\vrs SET XERCES_HOME=e:\projects\ldx SET POSTGRESQL=D:\programme\PostgreSQL\8.1 SET QTDIR=D:\programme\Qt\3.2.0Educational SET FREETYPE_HOME=E:\projects\freetype-2.2.1 SET PATH=%VRS_HOME%/lib;%CGA_HOME%/vrs_anno/lib;%CGA_HOME%/vrs_text/bin;%PATH% START "D:\programme\Microsoft Visual Studio 8\Common7\IDE\devenv.exe" %CGA_HOME%\cga-vs2005.sln Node-path: trunk/cga-vs2005.sln Node-kind: file Node-action: change Text-content-length: 2648 Text-content-md5: fffcb9e08c78cb879e1859b51a9dbc36 Content-length: 2648 Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cga", "cga\cga-vs2005.vcproj", "{7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrs_anno", "vrs_anno\win32\vrs_anno\vrs_anno.vcproj", "{2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F}" ProjectSection(ProjectDependencies) = postProject {E151AA45-3477-4FC4-A94B-BA9D06AB3A54} = {E151AA45-3477-4FC4-A94B-BA9D06AB3A54} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vrs_text", "vrs_text\win32\vrs_text\vrs_text_vc8.vcproj", "{E151AA45-3477-4FC4-A94B-BA9D06AB3A54}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smartmaplabels_01", "vrs_anno\win32\smartmaplabels_01\smartmaplabels_01.vcproj", "{336BCEC8-E39F-4C47-8667-B976AE619654}" ProjectSection(ProjectDependencies) = postProject {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F} = {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F} EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug|Win32.ActiveCfg = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Debug|Win32.Build.0 = Debug|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release|Win32.ActiveCfg = Release|Win32 {7AD904CF-C8F1-4E39-B5AF-FDC5BADB48B5}.Release|Win32.Build.0 = Release|Win32 {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F}.Debug|Win32.ActiveCfg = Debug|Win32 {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F}.Debug|Win32.Build.0 = Debug|Win32 {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F}.Release|Win32.ActiveCfg = Release|Win32 {2B65E11E-2CBD-4D5B-AECF-F51CC8DE911F}.Release|Win32.Build.0 = Release|Win32 {E151AA45-3477-4FC4-A94B-BA9D06AB3A54}.Debug|Win32.ActiveCfg = Debug|Win32 {E151AA45-3477-4FC4-A94B-BA9D06AB3A54}.Debug|Win32.Build.0 = Debug|Win32 {E151AA45-3477-4FC4-A94B-BA9D06AB3A54}.Release|Win32.ActiveCfg = Release|Win32 {E151AA45-3477-4FC4-A94B-BA9D06AB3A54}.Release|Win32.Build.0 = Release|Win32 {336BCEC8-E39F-4C47-8667-B976AE619654}.Debug|Win32.ActiveCfg = Debug|Win32 {336BCEC8-E39F-4C47-8667-B976AE619654}.Debug|Win32.Build.0 = Debug|Win32 {336BCEC8-E39F-4C47-8667-B976AE619654}.Release|Win32.ActiveCfg = Release|Win32 {336BCEC8-E39F-4C47-8667-B976AE619654}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal Node-path: trunk/environmentvars.txt Node-kind: file Node-action: change Text-content-length: 432 Text-content-md5: 570bc3c5dd2cad3f289831a2fba16904 Content-length: 432 Environment variables that need to be set: ------------------------------------------ VRS_HOME -> vrs-project includes&libs (www.vrs3d.org) [$(VRS_HOME)/include and $(VRS_HOME)/lib] POSTGRESQL -> PostgreSQL database includes&libs (www.postgresql.org) QTDIR -> qt3 includes&libs XERCES_HOME -> Xerces XML-parser includes&libs (xml.apache.org/xerces-c) FREETYPE_HOME -> Freetype 2.2.1 includes&libs (freetype.sourceforge.net) Node-path: trunk/vrs_anno Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/apps Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/apps/smartmapllabels_01 Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/apps/smartmapllabels_01/main.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 11997 Text-content-md5: 5ed5e74438e17d7a9bc5d9c8b4e517a5 Content-length: 12007 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include #ifdef WIN32 # define NOMINMAX # include # include // for random #include #define random rand using namespace std; #endif // vrs includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 // force linking with the importer/exporter VRSIO DLL #include namespace { VRS::SO dummy = new VRS::JPEGReader; } #endif #include using namespace std; using namespace VRS; using namespace VRS::ANNOTATION; using namespace VRS::TEXT; // global variables SO canvas_ = NULL; SO keycb_ = NULL; SO camPerspective_ = NULL; SO camLookAt_ = NULL; std::string fileName = "maplabeldemo"; // the help on the console void dumpHelpInfo () { printf ("=================================================================\n"); printf ("===\n"); printf ("=== MapLabelDemo Demo - 2006 - stefan.maass@hpi.uni-potsdam.de\n"); printf ("===\n"); printf ("=================================================================\n"); printf ("F1: dump this help\n"); printf ("F2: toggle techniques\n"); printf ("ESC: quit\n"); printf ("=================================================================\n\n"); } // // keyboard handler // void key () { KeyEvent *ke = VRS_Cast (KeyEvent, keycb_->currentCanvasEvent()); if(ke != NULL) { switch(ke->keyCode()) { case Key::Escape: exit(0); break; case Key::F1: dumpHelpInfo () ; break; case Key::F2: if (SmartMapLabelGroupSimplifierGL::getViewManagementStrategy () == SmartMapLabelGroupSimplifierGL::FIXED) SmartMapLabelGroupSimplifierGL::setViewManagementStrategy(SmartMapLabelGroupSimplifierGL::BORDERTOP); else if (SmartMapLabelGroupSimplifierGL::getViewManagementStrategy() == SmartMapLabelGroupSimplifierGL::BORDERTOP) SmartMapLabelGroupSimplifierGL::setViewManagementStrategy(SmartMapLabelGroupSimplifierGL::OPTIMAL); else if (SmartMapLabelGroupSimplifierGL::getViewManagementStrategy() == SmartMapLabelGroupSimplifierGL::OPTIMAL) SmartMapLabelGroupSimplifierGL::setViewManagementStrategy(SmartMapLabelGroupSimplifierGL::FIXED); ; break; } if (canvas_) canvas_->postForRedisplay (); } } /*! Create a flat textured plane, showing a map */ void createScene (SO& sceneNode) { float w = 100; float h = 90; //sceneNode->append (new ShapeMaterialGL(Color::gray)); //sceneNode->append (new Box (Vector (w , -0.01, h), Vector (-w, -10.0, -h))); // load texture for the plane SO texture = NULL; SO imageLoad = VRS_GuardedLoadObject (Image, "europe-small.png"); if (imageLoad) { SO imageMem = new MemoryImage (imageLoad); if (imageMem) { texture = new ImageTexture2DGL (imageMem); if (texture != NULL) { texture->setWrapS (TextureGL::CLAMP_TO_BORDER); texture->setWrapT (TextureGL::CLAMP_TO_BORDER); texture->setBorderColor (Color::white); sceneNode->append (texture); } } } SO pset = new PolygonSet (PolygonSet::Quads, makeIterator (Vector (-w, 0, h), Vector ( w, 0, h), Vector ( w, 0,-h), Vector (-w, 0,-h)), makeIterator (Vector ( 0, 0, 1), Vector ( 0, 0, 1), Vector ( 0, 0, 1), Vector ( 0, 0, 1)), makeIterator (Vector ( 1, 0, 0), Vector ( 0, 0, 0), Vector ( 0, 1, 0), Vector ( 1, 1, 0))); if (pset != NULL) { sceneNode->append (pset); } } /*! Create a label shape and texture object as you need */ bool createLabel (const std::string& ttfFileName, const std::string& text, const int haloSize, const Color& foregroundColor, const Color& backgroundColor, SO& textureRetValue) { SO txtRenderer = new TextRendererGL(ttfFileName, 64); VRS_Error (txtRenderer != NULL, "allocation error"); if (txtRenderer == NULL) return false; SO image = txtRenderer->renderHaloedText (text, 8, foregroundColor, backgroundColor); VRS_Error (image != NULL, "allocation error"); if (image == NULL) return false; SO pow2Image = image->copyToPow2 (); VRS_Error (pow2Image != NULL, "allocation error"); if (pow2Image == NULL) return false; SO texture = new ImageTexture2DGL (pow2Image); VRS_Error (texture != NULL, "allocation error"); if (texture == NULL) return false; // set some default values texture->setWrapS (TextureGL::CLAMP_TO_BORDER); texture->setWrapT (TextureGL::CLAMP_TO_BORDER); texture->setBorderColor ( Color::white); textureRetValue = texture; return true; } int main (int argc, char** argv) { glutInit(&argc, argv); // create canvas canvas_ = new GlutCanvas ("Demo: Smart Map Labels (stefan.maass@hpi.uni-potsdam.de)", 800, 600, GLCanvas::RGBADD); // Font-Manager FontManager* fm = new FontManager(); fm->addFontDirectory( "." ); fm->prefetchFontDirectories(); SO arialblk = fm->createFontDefinitionByFilename("Arial Black 80Pt", "ariblk.ttf", "", FontSize::fromPixel (24)); //arialblk->addDefaultGlyphs(); // uncomment this line to create the texture for all glyphs // build scene camPerspective_ = new VRS::Perspective (60.0, 1.0, 500.0); camLookAt_ = new LookAt (Vector (-130, 50, -130), Vector (0, 0, 0), Vector (0,1,0)); SO camera = new Camera (camPerspective_, camLookAt_); SO view = new SceneThing (); view->append (camera); view->append (new DepthBufferGL (true, true)); SO light = new DistantLight ( Vector (0.4, 0.4, -1.0), Color (1,1,1), 0.75); light->setDiffuseIntensity (0.9); light->setSpecularIntensity (0.2); view->append (light); // ============================================ // === // === CREATE ROOT NODE WITH DEFAULT SETTINGS // === SO scene = new SceneThing (view); scene->append (new BackgroundGL (0.7, 0.7, 1.0, 0.0)); scene->append (new TexEnvGL (TexEnvGL::Replace, Color (1.0,1.0,1.0,1.0))); SO terrain = new SceneThing (scene); createScene(terrain); // =================================== // === // === ADD LABEL GROUP // === SO > > mapLabelArray = new NonPersistentArray > (); for (unsigned int i = 0; i < 50; ++i) { Vector position (180. * (1.0*random ()/RAND_MAX) - 90., 0, 160. * (1.0*random ()/RAND_MAX) - 80.); SO text = new TextureText( arialblk, "Label 01" ); text->setVerticalAlignment( AbstractText::BOTTOM ); text->setHorizontalAlignment( AbstractText::CENTER ); SO label = new SmartMapLabel (position, text); mapLabelArray->append (label); position = Vector (180. * (1.0*random ()/RAND_MAX) - 90., 0, 160. * (1.0*random ()/RAND_MAX) - 80.); text = new TextureText( arialblk, "labeling 02" ); text->setVerticalAlignment( AbstractText::BOTTOM ); text->setHorizontalAlignment( AbstractText::CENTER ); label = new SmartMapLabel (position, text); mapLabelArray->append (label); } // create an labelGroup and append it to the scene SO labelgroup = SmartMapLabelGroup::getInstancePtr (); labelgroup->setLabelIterator(mapLabelArray->newIterator ()); scene->append ( new ShapeMaterialGL (Color::black) ); scene->append (labelgroup); // take a look at the SmartMapLabelGroupSimplifierGL methods if the default values doesn't fit your needs SmartMapLabelGroupSimplifierGL::setMinimalTextSize(20); SmartMapLabelGroupSimplifierGL::setMaximalTextSize(20); // add geometry graph (view) and behavior graph (resize handler) canvas_->append (view); // =================================== // === // === ADD INTERACTION // === SO concept = new VRS::InteractionConcept(camLookAt_); // Examination-Mode: SO examine = new VRS::InteractionMode(); // Sphere SO sphereNav = new VRS::SphereGroundPlateNavigation(0.0); sphereNav->assignMouseButton(VRS::SphereGroundPlateNavigation::MoveCamera, VRS::InputEvent::MouseButton1); SO sphereSettings = new VRS::PhysicalModelSettings(false); sphereSettings->setViscosity(200.0); sphereSettings->setSpringStrength(2500.0); sphereSettings->setMeterDefinition(300.0); examine->addInteractionTechnique(sphereNav); examine->setPhysicalModelSettings(sphereNav, sphereSettings); // Move-Focus SO moveFocus = new VRS::MoveFocusGroundPlateNavigation(0.0, VRS::MoveFocusGroundPlateNavigation::PRESERVE_ANGLE); moveFocus->assignMouseButton(VRS::MoveFocusGroundPlateNavigation::MoveFocus, VRS::InputEvent::MouseButton1, VRS::InputEvent::Ctrl); moveFocus->setAnimationTime(.6); examine->addInteractionTechnique(moveFocus); // Zoom SO zoom = new VRS::ZoomGroundPlateNavigation(0.0); zoom->setMinDistance(0.001); zoom->setWheelZoomFactor(0.95); zoom->assignMouseButton(VRS::ZoomGroundPlateNavigation::Zoom, VRS::InputEvent::MouseButton3); examine->addInteractionTechnique(zoom); SO zoomSettings = new VRS::PhysicalModelSettings(false); zoomSettings->setViscosity(150.0); zoomSettings->setSpringStrength(1500.0); zoomSettings->setMeterDefinition(300.); examine->setPhysicalModelSettings(zoom, zoomSettings); concept->addInteractionMode(examine); canvas_->append(concept); // add keyboard callback canvas_->append (keycb_ = new BehaviorCallback()); keycb_->setCanvasCallback (new FunctionCallback (&key)); keycb_->activate (); dumpHelpInfo (); glutMainLoop(); return 0; } Node-path: trunk/vrs_anno/bin Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/include Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/include/vrs Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/include/vrs/annotation Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/include/vrs/annotation/smartmaplabel.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1637 Text-content-md5: c36a071891ac7be3a7a543a6c09139ae Content-length: 1647 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #ifndef VRS_ANNOTATION_SMARTMAPLABEL_H_ #define VRS_ANNOTATION_SMARTMAPLABEL_H_ VRS_ANNOTATION_SMARTMAPLABEL_H_ #include #include using namespace VRS::TEXT; namespace VRS { namespace ANNOTATION { class VRS_ANNO_API SmartMapLabel : public Shape { public: SmartMapLabel (); SmartMapLabel (const Vector position, TextureText* text); virtual ~SmartMapLabel (); public: TextureText* getText (); public: const Vector& getAnchorPoint () const; Bounds boundingBox() const; VRS_TYPEINFO(SmartMapLabel, Shape); VRS_SERIALIZABLE(SmartMapLabel); private: friend class SmartMapLabelPainterGL; friend class SmartMapLabelGroupSimplifierGL; friend class SmartMapLabelGroupSimplifierGLPrivate; // hide per default to avoid misusage SmartMapLabel (const SmartMapLabel& other); SmartMapLabel& operator = (const SmartMapLabel& other); Vector m_anchorPoint; // anchor point on the ground SO m_text0; }; }// namespace ANNOTATION }// namespace VRS #endif /* VRS_ANNOTATION_SMARTMAPLABEL_H_ */ Node-path: trunk/vrs_anno/include/vrs/annotation/smartmaplabelgroup.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1801 Text-content-md5: d0388cbca5180f1a46c9558b0a744db4 Content-length: 1811 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #ifndef VRS_ANNOTATION_SMARTMAPLABELGROUP_H #define VRS_ANNOTATION_SMARTMAPLABELGROUP_H VRS_ANNOTATION_SMARTMAPLABELGROUP_H #include #include namespace VRS { class FilterTag; namespace ANNOTATION { class SmartMapLabel; class VRS_ANNO_API SmartMapLabelGroup : public Shape { public: static SO SmartMapLabelGroup::getInstancePtr (); public: void setLabelIterator (Iterator >* iter); Iterator >* newLabelIterator () const; const Vector& getOffset () const; public: Bounds boundingBox() const; static SO uniqueFilterTag (); VRS_TYPEINFO(SmartMapLabelGroup, Shape); VRS_SERIALIZABLE(SmartMapLabelGroup); protected: SmartMapLabelGroup(); // for persistency only! private: static SO s_singletonPtr; static SO s_FilterTag; SO > > m_labelIter; Vector minOffset_; mutable VRS::Bounds bbox_; // additional data for a simplifier // FIXME: this doesn't work for multiple view configurations friend class SmartMapLabelGroupSimplifierGL; Matrix lastMVPMatrix_; }; } // namespace ANNOTATION } // namespace VRS #endif // VRS_ANNOTATION_SMARTMAPLABELGROUP_H Node-path: trunk/vrs_anno/lib Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/scons Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/scons/custom.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 871 Text-content-md5: f7014f8617e55e5bfc126d728e2b6256 Content-length: 881 PROPS-END ############################################################################## ## SCons Build System for VRS - The Virtual Rendering System ## Copyright (C) 2000-2006 Computer Graphics Systems Group at the ## Hasso-Plattner-Institute (HPI), Potsdam, Germany. ## ## $Id: custom.py,v 1.2 2005/08/19 16:00:39 maass Exp $ ## $Date: 2005/08/19 16:00:39 $ ## $Revision: 1.2 $ ## $State: Exp $ ## $Author: maass $ ############################################################################## ## choose your standart build variant #variant = 'Release' variant = 'Debug' ## define specialized compiler commands #CXX = 'ccache g++' #CXX = 'ccache distcc g++' ## add addtional include pathes (e.g. nvidia opengl includes) #CPPPATH = ['/usr/share/doc/nvidia-glx-dev/include'] ## add additional libaries and pathes for linking #LIBPATH = ['/usr/X11/lib'] #LIBS = ['m'] Node-path: trunk/vrs_anno/scons/localcfg.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1708 Text-content-md5: c41031b94ebd919a70f76c899a009cca Content-length: 1718 PROPS-END def generate (env): variant = env ['variant'] PLATFORM = env ['PLATFORM'] env.Append (CPPDEFINES=['VRS_FAST_INCL']) if variant == 'Release': env.Append (CPPDEFINES=['NDEBUG']) elif variant == 'Debug': env.Append (CPPDEFINES=['DEBUG']) if PLATFORM == 'posix': if variant == 'Release': env.Append (CXXFLAGS=['-O2', '-march=pentium', '-momit-leaf-frame-pointer']) elif variant == 'Debug': env.Append (CXXFLAGS=['-Wall', '-g']) elif PLATFORM == 'win32': env.Append (CPPDEFINES=['WIN32', '_MBCS']) #WINDOWS_CCLFLAGS_DEBUG = '/D "WIN32" /D "_MBCS" /FD /EHsc /RTC1 /MDd /GR /Fp"./build/Windows/debug/annodemo.pch" /Fo"./build/Windows/debug/" /Fd"./build/Windows/debug/" /FR"./build/Windows/debug/" /W3 /nologo /c /ZI' #WINDOWS_CCLFLAGS_RELEASE = '/O2 /G5 /D "WIN32" /D "_MBCS" /FD /EHsc /MD /GR /W3 /nologo /c' env.Append (CXXFLAGS=['/FD', '/EHsc', '/GR', '/W3', '/nologo', '/c']) # env.Append (CXXFLAGS=['/FD','/GR', '/EHsc','/nologo', '/c']) if variant == 'Release': env.Append (CXXFLAGS=['/O2', '/G5', '/MD']) elif variant == 'Debug': # env.Append (CXXFLAGS=['/Od', '/RTC1', '/MDd', '/ZI', '/GZ' ,'/Gm']) # env.Append (CXXFLAGS=['/Od', '/MDd', '/ZI', '/GZ' ,'/Gm']) # env.Append (CXXFLAGS=['/Od', '/G6', '/FD', '/EHsc', '/RTC1', '/RTCc', '/MDd', '/GS', '/Gy']) # env.Append (CXXFLAGS=['/Zc:forScope', '/GR']) # env.Append (CXXFLAGS=['/W3', '/nologo', '/c', '/ZI', '/TP']) # env.Append (CPPDEFINES=['_DEBUG',]) env.Append (LINKFLAGS=['/DEBUG']) # env.Append (LINKFLAGS=['/debugtype:cv']) def exists(env): return True Node-path: trunk/vrs_anno/scons/opengl.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 322 Text-content-md5: 9c33e9e02cc4db8c2ff493c9185a9eea Content-length: 332 PROPS-END def generate (env): PLATFORM = env ['PLATFORM'] if PLATFORM == 'posix': env.Append (LIBS = ['GL', 'GLU', 'glut']) env.Append (LIBPATH = ['/usr/X11R6/lib']) elif PLATFORM == 'win32': env.Append (LIBS = ['OpenGL32', 'GLU32', 'glut32']) def exists(env): return True Node-path: trunk/vrs_anno/scons/qt.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 850 Text-content-md5: 52f0790f2bdd805965b95f22dae6f1ef Content-length: 860 PROPS-END ############################################################################## ## SCons Build System for VRS - The Virtual Rendering System ## Copyright (C) 2000-2006 Computer Graphics Systems Group at the ## Hasso-Plattner-Institute (HPI), Potsdam, Germany. ## ## $Id: vrs-qt-build.py,v 1.2 2005/10/07 09:15:06 maass Exp $ ## $Date: 2005/10/07 09:15:06 $ ## $Revision: 1.2 $ ## $State: Exp $ ## $Author: maass $ ############################################################################## def generate (env): variant = env ['variant'] PLATFORM = env ['PLATFORM'] # qt includes env.Tool ('qt') env['QT_LIB'] = 'qt-mt' # we use the multi-threaded version env['QT_AUTOSCAN'] = 0 # speedup, don't scan for mocable files env.AppendUnique (CPPDEFINES=['QT_CLEAN_NAMESPACE']) def exists(env): return True Node-path: trunk/vrs_anno/scons/vrs-anno-build.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 397 Text-content-md5: baaebafc318c4ed57978cb3a04fd9974 Content-length: 407 PROPS-END import os def generate (env): PLATFORM = env ['PLATFORM'] env.AppendUnique (CPPPATH = ['#/include']) env.AppendUnique (CPPPATH = ['#/include' + os.sep + 'private']) if PLATFORM == 'posix': env.Append (CPPDEFINES=['VRS_ANNO_API=""']) elif PLATFORM == 'win32': env.Append (CPPDEFINES=['VRS_ANNO_API="_declspec(dllexport)"']) def exists(env): return True Node-path: trunk/vrs_anno/scons/vrs-anno.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 606 Text-content-md5: 22aea52930f4ad4980c4d921ee2df1ce Content-length: 616 PROPS-END import os def generate (env): variant = env ['variant'] PLATFORM = env ['PLATFORM'] env.AppendUnique (CPPPATH = ['#/include']) env.AppendUnique (CPPPATH = ['#/include' + os.sep + 'private']) if PLATFORM == 'posix': env.Append (CPPDEFINES=['VRS_ANNO_API=""']) elif PLATFORM == 'win32': env.Append (CPPDEFINES=['VRS_ANNO_API="_declspec(dllimport)"']) if variant == 'Release': env.Prepend (LIBS='vrs_anno') elif variant == 'Debug': env.Prepend (LIBS='vrs_anno_debug') env.Append (LIBPATH=['#/lib']) def exists(env): return True Node-path: trunk/vrs_anno/scons/vrs.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1716 Text-content-md5: 63b7af6c903577b8e2c88dad0b5d4a20 Content-length: 1726 PROPS-END import os import SCons.Defaults import SCons.Tool import SCons.Util class ToolVRSWarning(SCons.Warnings.Warning): pass class VrsDirNotFound(ToolVRSWarning): pass def _detect(env): VRSDIR = None if not VRSDIR: VRSDIR = env.get('VRSDIR',None) if not VRSDIR: VRSDIR = os.environ.get('VRSDIR', None) if not VRSDIR: VRSDIR = None SCons.Warnings.warn(VrsDirNotFound, "Could not detect vrs, using empty VRSDIR") return VRSDIR def generate(env): VRSDIR = _detect (env) env ['VRSDIR'] = VRSDIR PLATFORM = env ['PLATFORM'] variant = env ['variant'] # append settings for all plattform and variants env.AppendUnique (CPPDEFINES = ['QT_CLEANNAMESPACE']); env.AppendUnique (CPPPATH = [VRSDIR + os.sep + 'include']) env.AppendUnique (LIBPATH = [VRSDIR + os.sep + 'lib']) # append variant specific settings VRSLIBS = ['vrs_core', 'vrs_opengl', 'vrs_io', 'vrs_sg', 'vrs_image', 'vrs_glut'] # 'vrs_qt' VRSLIBS_DBG = map ((lambda x: x + '_debug'), VRSLIBS) if variant == 'Debug': env.Append (CPPDEFINES=['VRS_VERSION_DEBUG']); env.Append (LIBS=VRSLIBS_DBG) elif variant == 'Release': env.Append (CPPDEFINES=['VRS_VERSION_RELEASE']); env.Append (LIBS=VRSLIBS) # again some global settings if PLATFORM == 'posix': env.Append (LIBS = ['png', 'freetype', 'jpeg']) elif PLATFORM == 'win32': libs = ['libpng'] if variant == 'Debug': libs = map ((lambda x: x + '_debug'), libs) libs += ['freetype2110'] env.Append (LIBS = libs) def exists(env): return _detect (env) Node-path: trunk/vrs_anno/scons/xerces.py Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1052 Text-content-md5: 4efeb6fc830f1bbdeedf1374f52cdb9f Content-length: 1062 PROPS-END import os import SCons.Defaults import SCons.Tool import SCons.Util ########################################################## ## ## XERCES ## class ToolXercesWarning(SCons.Warnings.Warning): pass class XercesDirNotFound(ToolXercesWarning): pass def _detect(env): XERCESDIR = None if not XERCESDIR: XERCESDIR = env.get('XERCESDIR',None) if not XERCESDIR: XERCESDIR = os.environ.get('XERCESDIR', None) if not XERCESDIR: XERCESDIR = None SCons.Warnings.warn(XercesDirNotFound, "Could not detect xerces, using empty XERCESDIR") return XERCESDIR def generate (env): PLATFORM = env ['PLATFORM'] if PLATFORM == 'posix': env.Append (LIBS = ['xerces-c']) elif PLATFORM == 'win32': XERCESDIR = _detect (env) env.Append (CPPPATH = [XERCESDIR + os.sep + 'include']) env.Append (LIBPATH = [XERCESDIR + os.sep + 'lib']) env.Append (LIBS = ['xerces-c_2']) def exists(env): return True Node-path: trunk/vrs_anno/src Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/src/SConscript Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1413 Text-content-md5: 49e6a1afa6273378a0a24fcfe339fc76 Content-length: 1423 PROPS-END import os Import ('mapLabelDemoEnv') demofiles = [ 'main.cpp', 'viewmanagement.cpp', 'labeldefinition.cpp', 'smartmaplabel.cpp', 'smartmaplabelpaintergl.cpp', 'smartmaplabelgroup.cpp', # 'smartmaplabelgroupsimplifiergl.cpp', 'smartmaplabelgroupsimplifiergl0.cpp', 'rpatch.cpp', 'rterrain.cpp', 'rterrainsimplifier.cpp', 'scenegenerator.cpp', 'depthtest.cpp', 'depthtestzbuffer.cpp', 'depthtestidbuffer.cpp', 'depthtestfbo.cpp', 'depthtestrayrequest.cpp', 'headlight.cpp', 'lineset2d.cpp', 'lineset2dpaintergl.cpp', 'smlgstatedata.cpp' ] #mapLabelDemoEnv.Append (CXXFLAGS=['.']) prg_name = '#' + os.sep + 'maplabeldemo' mapLabelDemoEnv.Append (CPPPATH=['#src/maplabeldemo']) if mapLabelDemoEnv ['variant'] == 'Debug': prg_name = prg_name + '_debug' #if demoEnv ['PLATFORM'] == 'win32': # if demoEnv ['variant'] == 'Debug': # demoEnv.Append (CXXFLAGS=['/Fd"maplabeldemo_debug.pdb"']) # demoEnv.Append (CXXFLAGS=['/FR"build/windows/debug/maplabeldemo/"']) # demoEnv.Append (CXXFLAGS=['/Fo"build/windows/debug/maplabeldemo/"']) demo = mapLabelDemoEnv.Program (prg_name , demofiles) Default (demo) Node-path: trunk/vrs_anno/src/smartmaplabel.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2233 Text-content-md5: 8277ad5e9aa8ad59c909ce00d5fa6a23 Content-length: 2243 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include #include #include #include #include namespace VRS { namespace ANNOTATION { // ========================================================================= // === // === DOCUMENTATION // === /*! \class SmartMapLabel smartmaplabel.h "smartmaplabel.h" \brief short description \todo documentation missing */ // ========================================================================= // === // === PUBLIC PART // === /*! Constructor */ SmartMapLabel::SmartMapLabel () : Shape (), m_anchorPoint (0,0,0), m_text0 (NULL) {} SmartMapLabel::SmartMapLabel (const Vector position, TextureText* text) : Shape (), m_anchorPoint (position), m_text0 (text) {} /*! Destructor */ SmartMapLabel::~SmartMapLabel () {} const Vector& SmartMapLabel::getAnchorPoint () const { return m_anchorPoint; } TextureText* SmartMapLabel::getText () { return m_text0; } Bounds SmartMapLabel::boundingBox () const { assert (0); Bounds bbox; return bbox; } /*! This method implements the standard serialization mechanism. */ void SmartMapLabel::serialize (SerializationManager& doc) { VRS_Assertion (0, "Not yet implemented"); UINT8 version = 0; doc.classVersion (version); Shape::serialize (doc); // add additionaly serialization calls, for example: // serialization(doc, "height", height_, 0.0); } VRS_SERIALIZATION_REGISTRATION(VRS::ANNOTATION::SmartMapLabel); }// namespace ANNOTATION }// namespace VRS Node-path: trunk/vrs_anno/src/smartmaplabelgroup.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2783 Text-content-md5: 5f429e01e9fab8fe026164671fffba89 Content-length: 2793 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include #include #include #include #include namespace VRS { namespace ANNOTATION { SO SmartMapLabelGroup::s_singletonPtr = NULL; SO SmartMapLabelGroup::s_FilterTag = NULL; // ========================================================================= // === // === DOCUMENTATION // === /*! \class SmartMapLabelGroup smartmaplabelgroup.h "vrs/smartmaplabelgroup.h" \brief short description \addtogroup vrs \todo documentation missing */ // ========================================================================= // === // === PRIVATE PART // === SmartMapLabelGroup::SmartMapLabelGroup() : Shape (), m_labelIter (NULL) {} // ========================================================================= // === // === PUBLIC PART // === SO SmartMapLabelGroup::getInstancePtr() { if (s_singletonPtr == NULL) { s_singletonPtr = new SmartMapLabelGroup (); } return s_singletonPtr; } void SmartMapLabelGroup::setLabelIterator (Iterator >* iter) { m_labelIter = iter; } Iterator >* SmartMapLabelGroup::newLabelIterator () const { return m_labelIter; } const Vector& SmartMapLabelGroup::getOffset () const { return minOffset_; } Bounds SmartMapLabelGroup::boundingBox () const { assert (0); Bounds bbox; return bbox; } SO SmartMapLabelGroup::uniqueFilterTag () { if (s_FilterTag == NULL) s_FilterTag = FilterTag::newUniqueTag (); return s_FilterTag; } /*! This method implements the standard serialization mechanism. */ void SmartMapLabelGroup::serialize (SerializationManager& doc) { VRS_Assertion (0, "Not yet implemented"); UINT8 version = 0; doc.classVersion (version); Shape::serialize (doc); // add additionaly serialization calls, for example: // serialization(doc, "height", height_, 0.0); } VRS_SERIALIZATION_REGISTRATION(VRS::ANNOTATION::SmartMapLabelGroup); } // namespace ANNOTATION } // namespace VRS Node-path: trunk/vrs_anno/src/smartmaplabelgroupsimplifiergl.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 14438 Text-content-md5: 50034038886e0ba37d3daa881fd24f64 Content-length: 14448 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; namespace VRS { namespace ANNOTATION { SmartMapLabelGroupSimplifierGL::Strategy SmartMapLabelGroupSimplifierGL::s_strategy = SmartMapLabelGroupSimplifierGL::OPTIMAL; float SmartMapLabelGroupSimplifierGL::s_minPixelSize = 24.0; // pixel float SmartMapLabelGroupSimplifierGL::s_maxPixelSize = 24.0; // pixel float SmartMapLabelGroupSimplifierGL::s_initialLabelOffset = 30.0; // pixel float SmartMapLabelGroupSimplifierGL::s_minimalTextDistance = 0.0; // screen coordinate [0..1] float SmartMapLabelGroupSimplifierGL::s_maximalTextDistance = 1.0; // screen coordinate [0..1] // ========================================================================= // === // === DOCUMENTATION // === /*! \class SmartMapLabelGroupSimplifierGL smartmaplabelgroupsimplifiergl.h "smartmaplabelgroupsimplifiergl.h" \brief short description \todo documentation missing */ // ========================================================================= // === // === PRIVATE // === class SmartMapLabelGroupSimplifierGLPrivate { public: SmartMapLabelGroupSimplifierGLPrivate (); public: static SMLGStateData s_stateData; }; SMLGStateData SmartMapLabelGroupSimplifierGLPrivate::s_stateData; SmartMapLabelGroupSimplifierGLPrivate::SmartMapLabelGroupSimplifierGLPrivate () {} // ========================================================================= // === // === PUBLIC PART // === SmartMapLabelGroupSimplifierGL::SmartMapLabelGroupSimplifierGL () : m_private (NULL) { m_private = new SmartMapLabelGroupSimplifierGLPrivate (); } SmartMapLabelGroupSimplifierGL::~SmartMapLabelGroupSimplifierGL () { if (m_private != NULL) { delete m_private; m_private = NULL; } } /*! * \todo documentation missing */ ID SmartMapLabelGroupSimplifierGL::target () const { return SmartMapLabelGroup::ClassNameVRS(); } /*! * \todo documentation missing */ bool SmartMapLabelGroupSimplifierGL::simplify (Engine* E, const Shape* S) { VRS_Assertion (s_initialLabelOffset >= 0.0, "invalid value"); VRS_Assertion (s_minPixelSize >= 0.0, "invalid value"); VRS_Assertion (s_maxPixelSize >= s_minPixelSize, "invalid value"); VRS_Assertion (s_minimalTextDistance >= 0.0, "invalid value"); VRS_Assertion (s_maximalTextDistance >= s_minimalTextDistance && s_maximalTextDistance <= 1.0, "invalid value"); // PREPARATION SO engine = VRS_GuardedCast (EngineGL, E); Matrix mvMatrix = E->currentTf (Engine::modelviewMatrix); Matrix completeMatrix = E->currentTf (Engine::projectionMatrix) * mvMatrix; const VRS::CameraInfo* const cameraInfo = E->cameraInfo(); Vector cameraRight (cameraInfo->rightVector ().normalized ()); Vector cameraUp (cameraInfo->upVector ().normalized ()); Vector cameraDir (cameraInfo->direction().normalized ()); Vector cameraPos (cameraInfo->position()); const double canvasPixelHeight = 1.0 / (double) E->getCanvas()->getHeight(); SO labelGroup = VRS_GuardedCast (SmartMapLabelGroup, S); SO > > labelIter = labelGroup->newLabelIterator(); unsigned int numberOfLabels = labelIter->size (); unsigned int numDisplayedLabels = 0; SMLGStateData& stateData = SmartMapLabelGroupSimplifierGLPrivate::s_stateData; stateData.m_distanceIndexPairs.clear (); // stateData.m_annoationZDepth.clear(); const double oneDivPixelWidth = 1.0 / ((double) E->getCanvas()->getWidth()); const double oneDivPixelHeight = 1.0 / ((double) E->getCanvas()->getHeight()); // === determine visible labels and sort them by their distance to the observer === unsigned int i; const double nearPlane = cameraInfo->nearPlane (); const double oneDivNearFarPlaneDistance = 1.0 / (cameraInfo->farPlane () - cameraInfo->nearPlane ()); for (i=0; iget(i)->m_anchorPoint; double distance; // cameraPos [1] = visPos [1]; VRS::Vector dist = visPos - cameraPos; if (dist.dotProduct (cameraDir) <= 0) continue; // skip if not visible dist[1] = 0.0; // on Ground distance distance = dist.abs2(); // distance = dist.dotProduct (cameraDir); // if (distance <= 0) continue; stateData.m_distanceIndexPairs.push_back( std::make_pair(distance, i) ); #else const Vector anchorPos = mvMatrix * labelIter->get(i)->m_anchorPoint; double zDepth = (anchorPos [2] - nearPlane) * oneDivNearFarPlaneDistance; if (zDepth < s_minimalTextDistance || zDepth > s_maximalTextDistance ) continue; // skip if outside of range (or not visible) // stateData.m_annoationZDepth.push_back (anchorPos [2]); stateData.m_distanceIndexPairs.push_back( std::make_pair(zDepth, i) ); #endif } // if no label is visible we have nothing to do if(stateData.m_distanceIndexPairs.empty()) return true; // else sort by distance in back to front order std::sort(stateData.m_distanceIndexPairs.begin(), stateData.m_distanceIndexPairs.end(), std::greater >()); // === calculate heights =========================================== const double horizon = 1.0; const unsigned int nrSlots = 800; ViewManagement vm; vm.setNumberOfIntervalls (nrSlots); vm.setHorizont (horizon); numDisplayedLabels = stateData.m_distanceIndexPairs.size (); stateData.m_annotationScreenScale.resize (numDisplayedLabels); stateData.m_annotationPoleStart.resize (numDisplayedLabels); stateData.m_annotationPoleEnd.resize (numDisplayedLabels); for (i=0; i currentLabel = labelIter->get (labelIndex); // determine linear z-Depth for the anchorPoint // FIXME: use z-Depth from the label point if this is different (other strategy than camera up) ? // const Vector anchorPos = mvMatrix * currentLabel->m_anchorPoint; // double zDepth = (anchorPos [2] - cameraInfo->nearPlane ()) / (cameraInfo->farPlane () - cameraInfo->nearPlane ()); const Bounds labelBounds = currentLabel->m_text0->boundingBox(); const Vector labelDimensions = labelBounds.getURB () - labelBounds.getLLF(); const double labelWidth = labelDimensions [0]; const double labelHeight = labelDimensions [1]; const double labelAspect = labelWidth / labelHeight; // we use labelLineHeight instead of labelDimensions [1] for the calculation in the following, // because we want to have all characters (e.G. 'U' and 'y') a unique scaling const double labelLineHeight = currentLabel->m_text0->getFontDefinition()->getLineHeight(); // project the anchor point to the screen space stateData.m_annotationPoleStart [i] = completeMatrix * currentLabel->m_anchorPoint; // map from (-1,-1)x(1,1) to (0,0)x(1,1) stateData.m_annotationPoleStart [i] [0] += 1.0; stateData.m_annotationPoleStart [i] [1] += 1.0; stateData.m_annotationPoleStart [i] [0] *= 0.5; stateData.m_annotationPoleStart [i] [1] *= 0.5; #if 0 double elevationHeight = 15.0; Vector poleEnd = currentLabel->m_anchorPoint + elevationHeight * Vector (0,1,0); //+ inititialOffset * cameraUp; poleEnd = completeMatrix * poleEnd; stateData.m_annotationPoleEnd [i] = poleEnd; #else stateData.m_annotationPoleEnd [i] = stateData.m_annotationPoleStart [i]; stateData.m_annotationPoleEnd [i] [1] += 30.0 * oneDivPixelHeight; #endif double newPixelHeight = s_minPixelSize; zDepth = std::min (1.0, std::max (0.0, 4.0 * (zDepth - 1.0) + 1.0)); if (s_minPixelSize != s_maxPixelSize ) newPixelHeight = (s_minPixelSize + std::min(1.0, std::max (0.0, 1.0 - (zDepth))) * (s_maxPixelSize - s_minPixelSize)); // printf ("newPixelHeight %.3f\n", newPixelHeight); const double newLabelLineHeight = newPixelHeight * oneDivPixelHeight; const double newLabelHeight = newLabelLineHeight * labelHeight/labelLineHeight; const double newLabelWidth = newPixelHeight * labelAspect * oneDivPixelWidth ; stateData.m_annotationScreenScale [i] = Vector (newLabelWidth/labelWidth, newLabelHeight/labelHeight, 1.0); double underlineOffset = labelBounds.getLLF () [1]; if (underlineOffset < 0.0) { underlineOffset *= (newLabelHeight/labelHeight); } //printf ("underlineoffset %.3f\n", underlineOffset); Vector& poleEnd = stateData.m_annotationPoleEnd [i]; const double screenXmin = poleEnd [0] - newLabelWidth * 0.5; const double screenXmax = screenXmin + newLabelWidth; const double screenYmin = poleEnd [1] + underlineOffset; const double screenYmax = poleEnd [1] + newLabelHeight + underlineOffset; const double screenX0 = std::max(0.0, std::min (1.0, screenXmin)); const double screenY0 = std::max(0.0, std::min (1.0, screenYmin)); const double screenX1 = std::max(0.0, std::min (1.0, screenXmax)); const double screenY1 = std::max(0.0, std::min (1.0, screenYmax)); // skip items that are to small and/or invisible if (abs(screenX1 - screenX0) < 0.0001 || abs(screenY1 - screenY0) < 0.0001 ) continue; double screenY=0; switch (s_strategy) { case OPTIMAL: screenY = vm.nextFreeRectangleAbove (screenX0, screenY0, screenX1, screenY1); break; case BORDERTOP: screenY = vm.nextFreeRectangleOnTop (screenX0, screenY0, screenX1, screenY1); break; case FIXED: screenY = screenY0; break; default: VRS_InternalError (0, "Unknown strategy enumeration"); } if (screenY == screenY0) { if (screenY0 < 1.0 && screenY1 > 0.0) { if (s_strategy != FIXED) vm.addRectangle (screenX0, screenY0, screenX1, screenY1); } } else { if (s_strategy != FIXED) vm.addRectangle (screenX0, screenY, screenX1, std::min (1.0, screenY + newLabelHeight)); stateData.m_annotationPoleEnd [i] [1] = screenY - underlineOffset; } } // for all displayed labels ( = all labels - culled labels) // =================== // === // === RENDERING // === // ATTENTION: We need an identity matrix so we choose z min = -1.0 here, even if our z values are in the [0..1] interval static const SO STANDARD_VIEW = Camera::newNormalizedDeviceCoordsCamera (0,1.0, 0,1.0, -1.0, 1.0); static const SO NO_LIGHT = new LightModelGL(LightModelGL::DisableLighting); static const SO DEPTH_BUFFER_ATTR = new DepthBufferGL (DepthBufferGL::SetDepthTest|DepthBufferGL::SetDepthFunction|DepthBufferGL::SetDepthRange, false, true, GL_LESS, 0.0, 1.0); static const SO COLOR_BUFFER_ATTR = ColorBufferGL::newBlending (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); E->push (STANDARD_VIEW); E->push (NO_LIGHT); E->push (DEPTH_BUFFER_ATTR); E->push (COLOR_BUFFER_ATTR); // === render pole lines === glBegin (GL_LINES); for (unsigned int i=0; i < numDisplayedLabels; ++i) { float v_x = stateData.m_annotationPoleStart [i] [0]; float v_y = stateData.m_annotationPoleStart [i] [1]; float v_z = stateData.m_annotationPoleStart [i] [2]; glVertex3f (v_x, v_y, v_z); v_x = stateData.m_annotationPoleEnd [i] [0]; v_y = stateData.m_annotationPoleEnd [i] [1]; v_z = stateData.m_annotationPoleEnd [i] [2]; glVertex3f (v_x, v_y, v_z); } glEnd (); // GL_LINES // === render labels === static SO textPainter = new TextureTextPainterGL (); for (unsigned int i=0; i < numDisplayedLabels; ++i) { const unsigned int labelIndex = numDisplayedLabels - i - 1; //const unsigned int labelIndex = i; SO label = labelIter->get(stateData.m_distanceIndexPairs [i].second); // active label texture if (label->getText () != NULL) { // Translation and Scale E->pushTf(); E->multTf (Matrix::translation (stateData.m_annotationPoleEnd [labelIndex])); E->multTf (Matrix::scaling (stateData.m_annotationScreenScale [labelIndex])); textPainter->renderText(E,label->getText ()); E->popTf(); } } E->pop (COLOR_BUFFER_ATTR); E->pop (DEPTH_BUFFER_ATTR); E->pop (NO_LIGHT); E->pop (STANDARD_VIEW); return true; } void SmartMapLabelGroupSimplifierGL::setDepthTest (SO obj) { VRS_Assertion (0, "not implemented in this version"); } void SmartMapLabelGroupSimplifierGL::setIDTest (SO obj) { VRS_Assertion (0, "not implemented in this version"); } DepthTest* SmartMapLabelGroupSimplifierGL::gettDepthTest () { VRS_Assertion (0, "not implemented in this version"); return NULL; } /*! * \todo documentation missing */ bool SmartMapLabelGroupSimplifierGL::isSimple() { return true; } VRS_REGISTER_HANDLER(SmartMapLabelGroupSimplifierGL, EngineGL); } // namespace ANNOTATION } // namespace VRS Node-path: trunk/vrs_anno/src/smlgstatedata.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 1021 Text-content-md5: 927c71ed77b5f4f1f074b3441b9845b4 Content-length: 1031 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include namespace VRS { namespace ANNOTATION { // ========================================================================= // === // === DOCUMENTATION // === /*! \class ClassXYZ classxyz.h "classxyz.h" \brief short description \todo documentation missing */ // ========================================================================= // === // === PUBLIC PART // === /*! Constructor */ SMLGStateData::SMLGStateData () {} } // namespace ANNOTATION } // namespace VRS Node-path: trunk/vrs_anno/src/viewmanagement.cpp Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 10246 Text-content-md5: 75690fa8cf75d7ca4e70dbf84de7e93e Content-length: 10256 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #include #include #include namespace VRS { namespace ANNOTATION { ViewManagement::ViewManagement () : nrIntervalls_ (20), horizont_ (1.0), m_lastTestAboveHorizon (false) { this->init (nrIntervalls_); } void ViewManagement::setNumberOfIntervalls (unsigned int value) { nrIntervalls_ = value; this->init (nrIntervalls_); } unsigned int ViewManagement::getNumberOfIntervalls () { return nrIntervalls_; } void ViewManagement::setHorizont (const double value) { horizont_ = value; } void ViewManagement::clear() { this->init (nrIntervalls_); } void ViewManagement::addRectangle (double x0, double y0, double x1, double y1) { assert (x0 >= 0.0 && x0 <= 1.0); assert (y0 >= 0.0 && y0 <= 1.0); assert (x1 >= 0.0 && x1 <= 1.0); assert (y1 >= 0.0 && y1 <= 1.0); assert (y1 >= y0); // printf ("add rectangle %.3f-%.3f, %.3f-%.3f\n",x0, x1,y0, y1); const double iSize = 1.0/((double)(nrIntervalls_-1)); const unsigned int slotEnd = (unsigned int) (x1/iSize); unsigned int slot = (unsigned int) (x0/iSize); // printf ("slots %i-%i\n", slot, slotEnd); assert (slot >= 0 && slot < nrIntervalls_); assert (slotEnd >= 0 && slotEnd < nrIntervalls_); int case0 = 0; int case1 = 0; int case2 = 0; int case3 = 0; int case4 = 0; const double epsilon = .0001; typedef std::pair dpair; while (slot <= slotEnd) { std::list::iterator iStart = spaceStructure_ [slot].begin (); std::list::iterator iEnd = spaceStructure_ [slot].end (); std::list newIntervallList; while (iStart != iEnd) { if ((iStart->second < y0) ||(iStart->first > y1)) { case0++; // empty intervall is complete outside of (y0,y1) newIntervallList.push_back ((*iStart)); } else if ((iStart->first >= y0) && (iStart->second <= y1)) { case1++; // emtpy intervall complete overlayed by rectangle // => skip whole intervall } else if ( (iStart->first >= y0) && (iStart->second > y1)) { case2++; assert (iStart->first < y1); // cut intervall from the bottom double newBottom = y1+epsilon; if ((newBottom+epsilon) < iStart->second) newIntervallList.push_back (make_pair (newBottom, iStart->second)); } else if ( (iStart->second >= y0) && (iStart->second <= y1)) { case3++; // printf ("%.3f >= %.3f && %.3f <= %.3f\n", iStart->second, y0, iStart->second, y1); assert (iStart->first < y0); // cut intervall from the top double newTop = y0-epsilon; if ((newTop-epsilon) > iStart->first) newIntervallList.push_back (make_pair (iStart->first, newTop)); } else if ( (iStart->first < y0) && (iStart->first < y1) && (iStart->second > y0) && (iStart->second > y1)) { assert (y0 < y1); case4++; double newTop = y0-epsilon; if ((newTop-epsilon) > iStart->first) newIntervallList.push_back (make_pair (iStart->first, newTop)); double newBottom = y1+epsilon; if ((newBottom+epsilon) < iStart->second) newIntervallList.push_back (make_pair (newBottom, iStart->second)); // printf ("split intervall into %.3f, %.3f and %.3f,%.3f\n", iStart->first, newTop, newBottom, iStart->second); } else { printf ("f %.5f, s %.5f, y0 %.5f, y1 %.5f\n", iStart->first, iStart->second, y0, y1); assert (0); // all cases should be handled } ++iStart; } spaceStructure_ [slot] = newIntervallList; slot++; } #if 0 printf ("case 00: %i\n", case0); printf ("case 01: %i\n", case1); printf ("case 02: %i\n", case2); printf ("case 03: %i\n", case3); printf ("case 04: %i\n", case4); #endif } double ViewManagement::nextFreePointAbove (const double x0, const double y0) const { double iSize = 1.0/nrIntervalls_; unsigned int slot = (unsigned int) (x0/iSize); // typedef std::pair dpair; // list::iterator s = spaceStructure_ [slot].begin (); // list::iterator e = spaceStructure_ [slot].end (); // // while (sm_lastTestAboveHorizon = false; assert (x0 >= 0.0 && x0 <= 1.0); assert (y0 >= 0.0 && y0 <= 1.0); assert (x1 >= 0.0 && x1 <= 1.0); assert (y1 >= 0.0 && y1 <= 1.0); double newYValue = y0; double height = y1 - y0; double iSize = 1.0/((double) (nrIntervalls_ - 1)); unsigned int slotStart = (unsigned int) (x0/iSize); unsigned int slotEnd = (unsigned int) (x1/iSize); // printf ("slot Start/End %i, %i, %.3f, %.3f\n", slotStart, slotEnd, x1, iSize); assert (slotStart >= 0 && slotStart < nrIntervalls_); assert (slotEnd >= 0 && slotEnd < nrIntervalls_); unsigned int slot = slotStart; while (slot <= slotEnd) { if ( spaceStructure_ [slot].empty () || spaceStructure_ [slot].back ().second < (newYValue + height)) { // printf ("slot empty\n"); newYValue = 1.0; break; } else { double slotYMin = spaceStructure_ [slot].back ().first; // printf ("slotYMin %.3f\n", slotYMin); if (slotYMin > newYValue) newYValue = slotYMin; } ++slot; } if ((newYValue + height) > horizont_) { // printf ("cutted by horizont\n"); newYValue = horizont_ - height; this->m_lastTestAboveHorizon = true; } if (newYValue < 0.0) newYValue = 0.0; // printf ("newYValue %.3f\n", newYValue); return newYValue; } double ViewManagement::nextFreeRectangleAbove (const double x0, const double y0, const double x1, const double y1) { this->m_lastTestAboveHorizon = false; assert (x0 >= 0.0 && x0 <= 1.0); assert (y0 >= 0.0 && y0 <= 1.0); assert (x1 >= 0.0 && x1 <= 1.0); assert (y1 >= 0.0 && y1 <= 1.0); const double iSize = 1.0/((double) (nrIntervalls_ - 1)); const unsigned int slotStart = (unsigned int) (x0/iSize); const unsigned int slotEnd = (unsigned int) (x1/iSize); assert (slotStart >= 0 && slotStart < nrIntervalls_); assert (slotEnd >= 0 && slotEnd < nrIntervalls_); const double height = y1 - y0; double newYValue = y0; while (true) { double resultY = intersect (slotStart, slotEnd, newYValue, newYValue+height); if (resultY == newYValue || resultY >= 1.0 ) { newYValue = resultY; break; } else { newYValue = resultY; } } // some additional constraints if ((newYValue + height) > horizont_) { newYValue = horizont_ - height; this->m_lastTestAboveHorizon = true; } if (newYValue < 0.0) newYValue = 0.0; return newYValue; } void ViewManagement::init (unsigned int numIntervalls) { spaceStructure_.resize (0); for (unsigned int i=0; i< numIntervalls; ++i) { list > l; l.push_back(std::make_pair(0.0, horizont_)); spaceStructure_.push_back (l); } } double ViewManagement::intersect (const unsigned int slotStart, const unsigned int slotEnd, const double y0, const double y1) const { assert (slotStart >= 0 && slotStart < nrIntervalls_); assert (slotEnd >= 0 && slotEnd < nrIntervalls_); unsigned int slot = slotStart; bool intersect = false; double yNew = y0; const double height = y1 - y0; while (slot <= slotEnd && intersect == false) { if ( spaceStructure_ [slot].empty ()) { yNew = 1.0; intersect = true; } else { std::list >::const_iterator iStart = spaceStructure_ [slot].begin (); std::list >::const_iterator iEnd = spaceStructure_ [slot].end (); bool foundFree = false; while ( (iStart != iEnd) && intersect == false && foundFree == false) { if ((*iStart).first > yNew) yNew = (*iStart).first; if ((*iStart).first <= yNew && ((*iStart).second >= (yNew+height))) { foundFree = true; } else { iStart++; } } if (foundFree == false) // no free interval there { intersect = true; yNew = 1.0; } } ++slot; } return yNew; } } // namespace ANNOTATION } // namespace VRS Node-path: trunk/vrs_anno/src/vrs Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/src/vrs/annotation Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/src/vrs/annotation/smartmaplabelgroupsimplifiergl.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 4652 Text-content-md5: b7d9e587919bb8c50b9953ecd95ed3b3 Content-length: 4662 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #ifndef _SMARTMAPLABELGROUPSIMPLIFIERGL_H_ #define _SMARTMAPLABELGROUPSIMPLIFIERGL_H_ _SMARTMAPLABELGROUPSIMPLIFIERGL_H_ #include #include namespace VRS { namespace ANNOTATION { class DepthTest; class SmartMapLabelGroupSimplifierGLPrivate; class VRS_ANNO_API SmartMapLabelGroupSimplifierGL : public ShapeSimplifier { public: SmartMapLabelGroupSimplifierGL (); virtual ~SmartMapLabelGroupSimplifierGL (); public: enum Strategy {FIXED, BORDERTOP, OPTIMAL }; static void setViewManagementStrategy (const Strategy mode); static Strategy getViewManagementStrategy (); static void setMinimalTextSize (const float valueInPixel); static float getMinimalTextSize (); static void setMaximalTextSize (const float valueInPixel); static float getMaximalTextSize (); static void setInitialLabelOffset (const float valueInPixel); static float getInitialLabelOffset (); static void setMinimalTextDistance (const float value_0_1); static float getMinimalTextDistance (); static void setMaximalTextDistance (const float value_0_1); static float getMaximalTextDistance (); public: virtual ID target() const; //!< See `Simplifier' virtual bool simplify(Engine*, const Shape*); //!< See `ShapeSimplifier' virtual bool isSimple(); /*!< This is a simple shape simplification. */ public: VRS_TYPEINFO(SmartMapLabelGroupSimplifierGL, ShapeSimplifier); private: SmartMapLabelGroupSimplifierGLPrivate* m_private; public: static void setDepthTest (SO obj); static void setIDTest (SO obj); static DepthTest* gettDepthTest (); private: // depth test static SO m_DepthTest; static SO m_IDTest; static bool testDepth (const double screenX, const double screenY, const double depth); static bool completeZBufferTest (const double screenX0, const double screenY0, const double screenX1, const double screenY1, const double labelDepth); static bool sampledZBufferTest (const double screenX0, const double screenY0, const double screenX1, const double screenY1, const double labelDepth); static bool completeIDBufferTest (const double screenX0, const double screenY0, const double screenX1, const double screenY1); protected: static Strategy s_strategy; static float s_minPixelSize; static float s_maxPixelSize; static float s_initialLabelOffset; static float s_minimalTextDistance; static float s_maximalTextDistance; }; // ========================================================================= // === // === INLINER // === inline void SmartMapLabelGroupSimplifierGL::setViewManagementStrategy (const Strategy mode) {s_strategy = mode; }; inline SmartMapLabelGroupSimplifierGL::Strategy SmartMapLabelGroupSimplifierGL::getViewManagementStrategy () { return s_strategy; }; inline void SmartMapLabelGroupSimplifierGL::setMinimalTextSize (const float valueInPixel) {s_minPixelSize = valueInPixel; }; inline float SmartMapLabelGroupSimplifierGL::getMinimalTextSize () {return s_minPixelSize; }; inline void SmartMapLabelGroupSimplifierGL::setMaximalTextSize (const float valueInPixel) {s_maxPixelSize = valueInPixel; }; inline float SmartMapLabelGroupSimplifierGL::getMaximalTextSize () {return s_maxPixelSize; }; inline void SmartMapLabelGroupSimplifierGL::setInitialLabelOffset (const float valueInPixel) {s_initialLabelOffset = valueInPixel; }; inline float SmartMapLabelGroupSimplifierGL::getInitialLabelOffset () {return s_initialLabelOffset; }; inline void SmartMapLabelGroupSimplifierGL::setMinimalTextDistance (const float value_0_1) { s_minimalTextDistance = value_0_1; }; inline float SmartMapLabelGroupSimplifierGL::getMinimalTextDistance () { return s_minimalTextDistance; } inline void SmartMapLabelGroupSimplifierGL::setMaximalTextDistance (const float value_0_1) { s_maximalTextDistance = value_0_1; }; inline float SmartMapLabelGroupSimplifierGL::getMaximalTextDistance () { return s_maximalTextDistance; }; } // ANNOTATION } // VRS #endif /* _SMARTMAPLABELGROUPSIMPLIFIERGL_H_ */ Node-path: trunk/vrs_anno/src/vrs/annotation/smlgstatedata.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2634 Text-content-md5: 778a493b96b3747305a658685f44e8ca Content-length: 2644 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #ifndef VRS_ANNOTATION_SMLGSTATEDATA_H_ #define VRS_ANNOTATION_SMLGSTATEDATA_H_ VRS_ANNOTATION_SMLGSTATEDATA_H_ #include #include #include #include #include using namespace std; namespace VRS { namespace ANNOTATION { class ScreenBoundArea { public: ScreenBoundArea () { x0 =0.0; x1 = 1.0; y0 =0.0; y1 = 1.0; }; ScreenBoundArea (const double& x_0, const double& y_0, const double& x_1, const double& y_1) { x0 = x_0; x1 = x_1; y0 = y_0; y1 = y_1; }; public: double x0; // double y0; // x0, x1, y0, y1 element [0..1] double x1; // x0 < x1 && y0 < y1 double y1; #ifdef DEBUG bool validate () { bool valid = ( (x0 >= 0.0 && x0 <= 1.0) && (x1 >= 0.0 && x1 <= 1.0) && (y0 >= 0.0 && y0 <= 1.0) && (y1 >= 0.0 && y1 <= 1.0) && (x0 < x1) && (y0 < y1)); assert (valid); return valid; } #endif }; // ==== class SMLGStateData { public: SMLGStateData (); public: // flag for each label, showing if it's now or after the interpolation step visible vector m_activeLabels; std::vector > m_distanceIndexPairs; // for all active // std::vector m_annoationZDepth; std::vector m_annotationBounds; std::vector m_annotationScreenScale; std::vector m_annotationPoleStart; std::vector m_annotationPoleEnd; std::vector m_currentHeight; // in Pixel std::vector m_destinationHeight; // in Pixel double m_minimumLabelDistance; double m_maximumLabelDistance; }; } // namespace ANNOTATION } // namespace VRS #endif // VRS_ANNOTATION_SMLGSTATEDATA_H_ Node-path: trunk/vrs_anno/src/vrs/annotation/viewmanagement.h Node-kind: file Node-action: add Prop-content-length: 10 Text-content-length: 2099 Text-content-md5: 3367e92c0427218f7aab43e169a96bc0 Content-length: 2109 PROPS-END /****************************************************************************** * Copyright (C) 2000-2006 Computer Graphics Systems Group at the * Hasso-Plattner-Institute (HPI), Potsdam, Germany. * * Project: vrs_annotation * Author: stefan.maass@hpi.uni-potsdam.de * Note: Don't use or distribute this code without permission. It will be * officially released as a part of the VRS rendering system. ******************************************************************************/ #ifndef VRS_ANNOTATION_VIEWMANAGEMENT_H_ #define VRS_ANNOTATION_VIEWMANAGEMENT_H_ VRS_ANNOTATION_VIEWMANAGEMENT_H_ #include #include using namespace std; namespace VRS { namespace ANNOTATION { class VRS_ANNO_API ViewManagement { public: ViewManagement (); public: void setNumberOfIntervalls (unsigned int value); unsigned int getNumberOfIntervalls (); void setHorizont (const double value); void clear (); public: void addRectangle (const double x0, const double y0, const double x1, const double y1); double nextFreeRectangleOnTop (const double x0, const double y0, const double x1, const double y1); double nextFreeRectangleAbove (const double x0, const double y0, const double x1, const double y1) ; double nextFreePointAbove (const double x0, const double y0) const; bool lastTestWasAboveHorizon () { return m_lastTestAboveHorizon; }; private: ViewManagement (const ViewManagement& other); const ViewManagement& operator=(const ViewManagement& other); unsigned int nrIntervalls_; double horizont_; std::vector > > spaceStructure_; bool m_lastTestAboveHorizon; private: void init (unsigned int numIntervalls); double intersect (const unsigned int slotStart, const unsigned int slotEnd, const double y0, const double y1) const; }; } // namespace ANNOTATION } // namespace VRS #endif // VRS_ANNOTATION_VIEWMANAGEMENT_H_ Node-path: trunk/vrs_anno/win32 Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/win32/smartmaplabels_01 Node-kind: dir Node-action: add Prop-content-length: 10 Content-length: 10 PROPS-END Node-path: trunk/vrs_anno/win32/smartmaplabels_01/ariblk.ttf Node-kind: file Node-action: add Prop-content-length: 59 Text-content-length: 117028 Text-content-md5: 3e7043e8125f1c8998347310f2c315bc Content-length: 117087 K 13 svn:mime-type V 24 application/octet-stream PROPS-END  DSIGCPLTSH]k'OS/2q@vVcmapӥ8Dcvt FLQ28rfpgmUE-, gasp glyf&a@}(hdmx,> ?headܹ,6hhea _d$hmtx@Z3 tkernfoT loca"|?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~*>~~ O\_   " & 0 3 : < > D  !!!!"!&!.!^!!"""""""")"+"H"a"e###!%%% %%%%%$%,%4%<%l%%%%%%%%%%%%%%%&<&@&B&`&c&f&k  ~Q^   & 0 2 9 < > D  !!!!"!&!.![!!"""""""")"+"H"`"d### %%% %%%%%$%,%4%<%P%%%%%%%%%%%%%%%&:&@&B&`&c&e&jR  x;.4jy߲ߠޖޢދާ!q_0NA2TSJGDA>70)"ۀܳjSPO20/,1vvhlznTTVR*,(bcdefghjikmlnoqprsutvwxzy{}|~RSTUVW   XYZ[\]  ^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0F:GIIKLMNQGnCS<8G>y  L q | 3 ; ~ Op4=wm3s,sd1bHca)m.Tkv i  ! !&!?!V!o!!!!!!""+"C"Z"q""""""##1#`#$I$%%& &'?'(P(n(()X)*F***+y+,1,,-#--.0./|0!010B0_01Z122c2n2~2~2223D3344+4O4}445Z5s556`667 7u7778"99939J9c9z99999::::4:K:b:}::;;:;O;;<<2<_<<===.=E=i=>O>f>}>??+??@@@@@ASAjAAAAAAB B"BBBBCC+CACWC{CCCCCCD@DDDDEEE2EIE`EwEEFF.FEF\FsFFFFFFGG/GHGiGGGGGGGGGGGGGGHH(HRHHIIIJ J&JBJ\JJJJKK9KNK\KrKKKKLLL4LKLbLyLLLLLMMM1MHM[MsMMMN_NvNNNNNO)OuOOOPPrPPPPQQcQzQQQQQQRRXRRRRSS,SCSSTT%TF#pFE: -,+%E%Ej@`%#D!!!-,+%E%Ej`%#D!!!-,+!!!-,+!!!-,CCe -, i@a ,b`+ d#da\XaY-,%EhTX%E%E`h %#D%#D% Eh #D%Eh`%#DY-,% Eh #D%Eh`%#D-, CX!CXE+G#DGzEi G#D QX+G#DGz!GzYYY-, E#Eh`D-,EjB-,/-,!!-,%E%Ed`j%Eja %Ej e%#D%#D!!-,Eh#Ei@a%Eja %Ej e%#D%#D!!-,Ed#EdadB-,%C@T%CTZX% E@aDY%CT%C@TZX% E@`DY!!!!-,KRXC%E#aD!!Y-,KRXC%E#`D!!Y-,KRXED!!Y-, %#I@` c RX#%8#%e8c8!!!!!Y-,KPXED!!Y-,%# `#-,%# a#-,%-,F#F`F# F`ab# #KKpE` PXaFY`h:-, E%FRX?!Y-, E%FPX?!Y-,CC -,KRX%%I%%Ia TX! CUXY@TX CTXY CTX%8YYYY!!!!-,KRXCe8!!Y-,KRXC8!!Y-,!! d#d@b-,!QX d#d b@/+Y`-,!QX d#dUb/+Y`-, d#d@b`#!-,&&&&Eh:-,&&&&Ehe:-,CXY-,CXY-, +# <+-,(+# #+CX....!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"...../0*#.2V&!!2,!!!!!!!!!!!!!!%''''$!**!*!/**$*'$$*'2''$!!!!!!!!!2!!!!!/!!'''$***!!!!!!!!!!!!!!!!!!!!!!!!!+!((0!2*!!!!!$)"+2!!!!!!2''*222!'!!!!2'$'$$**(****!$$'!'$!!!222**!$'!'!!'!'!'*'$!$!3!!!!*!*!+*!''$$$*!*!$$V22221$'!'!'!$!$!$!*!*!*!*!*!!*!!!*!)"*!*!'$$*!*!*!*!2/''!22*! '*0,0-''!'$$***'/*$**$$$'.'/*'"!!" !!!!!!#!%!, ./!!!/$2!($!==1%"*'''!*$6"**%(/***$'$".'+(8926'(:'!!!!."## $*$!!!!3!#!/0'-!1!"!33" !2/2/2/'&!C2222!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$#%2111134."!'2!6])$$60$$$$$$$$$$$$$$!(****'$--$-$3--'-*''-*6**'$$$$$$$$$6$$$$!$!3$!$***'---$$$$$$$$$$$$$$$$$$$$$$$$$.$++3$6- $$$$$',%.6$!$$$!$$6**-666$!* $$$$6*'*''--+----$'!'*$*!'$$$666--$'!*$*$$*$*$*.*'$'$8$$$$-$-$.-$**'!''"-$-$''!]6 6665' !!*$*$*$'$'$'$-$-$-$-$-$$-$$$-$,%-$-$*'!'-$-$-$-$63*!*$66-$ *.4040**$*''---*3-'--'''*2*3-*%$$%#!$$$$!$!$&$($0#13$$$3'6$+'$AA5'$-***$-';%--'+3---'*'$2*.+<=6:*+?*$$!$$2%&&#'.'$$$$!7$%$34*1"$5"$%$!77%#!$636363*!)$I 6666 $ &!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&' 65555 792$$ *6$:d,&':4 &''''''''''&&&#+----*'00'0'700*0-**0-:--*&'''''''':''''#'#7'# &---*000'''''''''''''''''''''''''1'..7&:0"&&&'')0(2:'#& '&#'':--0:::&#- '''':-*-**00.0000'*#* -'-#*'&&:::00'*#-'-''-'-'-1-*'*'<''''0'0'20'--*#**$0'0'* * #d:":::9*###-'-'-'*'*'*'0'0'0'0'0''0'''0'/(0'0'-*#*0'0'0'0':7-#-'::0' -18384--'-**000-70*00***-6-70-' '''%#' '''#'#')'+'4&57'''7*:'.*'FF9*'0---'1*?(00*/7000*-*'6-2/@B:?-.C-''$&'6'))%*1)''''#;'(&78-5$'9$'''#;;'%#' :7:7:7-#,'N#::::#&##)$)))))))))))))))))))))))))))))))))))))))))))))*#:9999###;=5 '&"-:&Cs2",-C<%,----------,,,)244440-88-8-?880840084C440,"--------C----)-)?-)%,4440888-------------------------"9-66@,C8',,,--"07.9C-),%-,)--C448CC"C"",!)4 ----"C404008858888-0)0%4-4)0-,,CCC88-0)4-4--"4-4-4940-0-E---"-$8-8-98-440)00*8-8-0%0%"#(sC'C"C"C""B0(((4-4-4-0-0-0-8-8-8-8-8--8---8-7.8-8-40)08-8-8-8-C?4)4-CC8- 4"9@";A<44-4008884?80880004>4?84-%---+)-%---)-)-/-#2"-<+=?---?0C-50-QQA1-8444-80I.8816?888040->4:6JLCI45N4--)",->-//+090----")D-.,@@4=*-A*---)DE-+)-%C?C?C?4)2"-Z(CCCC(,((0*00000000000000000000000000000000000000000000/1(CBBBB(((DF>%-$,("4C,K8&22KC*22222222222222.8::::62>>2>2G>>6>:66>:K::62&22222222K2222!.!2.G2.*2:::6>>>2222222222222222222222222&@2<,22222&5>4@K2.2)22.22K::>KK&K&&2%.: 2222&K:6:66>>;>>>>26.6*:2:.6222KKK?>26.:2:22&:2:2:?:6262M222&2(>2>2@>2:!:!6.6!6/>2>26*6*&'-!K,K&K&K&&I6---:2:2:2626262>2>2>2>2>22>222>2=3>2>2:!6.6!>2>2>2>2KG:.:2KK>2:&?H&BIC::2:66>>>:G>6>>666:E:G>:3)2230.2)#222.2.#252(8&2C1EG222G6K2<62[[I72>:::2?6Q4>>7>>6:62E:@*77SJ .777777777777773=AAAA<7EE 7E7NEE*7J6LO777O*7p2SSSS2722;3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;=2SRRRR222UWL.8,71*@S!!!7\E.==\R$$3==============8DHHHHB=MM$=M=WMMBMHBBMH\HHB$$=.=====$===\====)8)=8W=83$$=HHHBMMM======================%===.N=JJW=\M6=====.BL?%%O\=8=3==8==\HHM\\.\..=-8H====.\HBHBB$$$$MMIMMMM=B8B3H=H8B===%%%\\\MM=$B8H=H==.$H=H=HNHB=B=_===.=1M=M=OM=H)H)B8B)B:M=M=B3B3.08(\6\.\.\..ZB78!!8!H=H=H=B=B=B=M=M=M=M=M=$$$$=M===M=K?M=M=H)B8B)M=M=M=M=\WH8$H=\\M=H.NX.RYRHH=HBBMM$MHWMBMMBBBHUHWM$H>2==>;8=2*===8=8*=A=1E/=RMHHH=MBd?MMCJWMMMBHB>UHOJfi\dGIkH==9/==U>AA;BNB====/8]=?=WYGT9=Z9=>)=8]^>;8=3+\W\W\WH8E.=|7\\\\7=77A9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7\[[[[777^aU3>1=6/G\%%%=dK!!!2BCdY''8B!!!CCCCCCCCCC!!BBB=JNNNNHCSS'CSC^SSHSNHHSNdNNH''B2!CCCCC'CC!!C!dCCCC,=,C=^C=8''BNNNHSSSCCCCCCCCCCC!!!!CCCCCCCCCCC(CCC2UCPP_!!BdS:BBBCC2GRE((UdC=!B7CB=CCd!NNSdd2d22B1=NC!!CCC!2dNHNHH''''SSOSSSS!!!!!!!!!!!C!H=H8NCN=HCBB(((dddSSC'H=NCNCC2!(NCNCNTNHCHCgCC!C2C5SCSCVSCN,N,H=H,H?SCSCH8H8!!!!!!!!!24<,d;d2d2d22bH<<##<#!NCNCNCHCHCHCSCSCSCSCSC'!'!'!'!C!SCCC!SCQDSCSCN,H=H,SCSCSCSCd^N='NCddSC!N2U`2YaY!NNCNHHSS'SN^SHSSHHHN\N_S'ND7C!CD@=C7.CC!C=C=.CGC5K3CYA\_!CCC_HdCPH''CyybICSNNNCTHmESSIP^SSSHNHC\NVPordlMPtNCC>3BC\DGG@HUGCCCC3=eCEB_`M[>Cb>CD,C=!!!efD@=C8/d^d^d^N=K2CGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGI54&'-40fa{H=Fʩ|@23?UOCaa;G7QZymz7 Ezd/cX"a8R cc<>*,A(W6/O"c!/?@V<&&4,08@P0?""""8)@6)A)o0  @l+/3/]+/+3/]9/]39/3?32#".%327654'&#"4>32#".%327654'&#"@pY}Ը}Y(22((22(X|Թ|X(22((22(fcүce|8%%8|{9$$8mgdӯde|8$$8||9$%8%0:@%f"&,9$1 7,79@4 6"9 $&)1/)@_54&#"327&>.*,<3jj⨿PN#T7~emGXjHi TF ,}MaJKVUk\>F+e-/AH1>&;T/IrUdU%@P0`p/]]99?3/10!!U@B)pQ 0@ &fw !P  /]2/<<??10]]3# 54:17PQW @$}@"    @16 6 "    p/]33//3/]9/9/99999+]+?3/<3/<99103676?'&''767&/7&'& *E*S8!hJ$' Kp/-.KHWӗ7F B ,$qT\q/!? 4T) 3@       /]3<<2//]/<3<2//]10!!!!!!C~|d/ 0@     h e++/9/3/9??910!'>7#|_tWR6kI-y}@ @/q//10!!-P|/@he++/?10!!|Mh?-@p/3/]3?5&#"T-4xE)I5;c^>[+cceZNIuVqvrQW$ <@! 6 6  ?/]3/9??9/+9]+10!>7ddA-L^+NC6k@ 6 @* 6gy?o l+/3/+/]3/9]]+??3/99+10)6%>54&#"%>32!:%dcKNch{S8|?م>C_b|!gb~UD7H.ٹ@ 6 6$, &#&6&@) 6&@!P!!!!!!!!w, 6 6@ 6  $#@06#####)@6?0o/l+/3/+/]3/+9/]+39]+++?3/9?]3/99/]++999+10+%6$3 #".'%32654&#"32654&#"0hiU-IQ(eNRmiZ0T"PkPFHZE֢_:-f^6{_xdfp#fFCPW*+ x@+   d     p  @6  p  @//]q33/]]+q<<23/]??3]9/32#".'%32654&#"%q#DAʑϑZnLUop];7)1 ʎ7mg-cgz72V(m@G&w  &@ 6&@ 6&  ##?*o)l+/+/]3/]9??9/+9/+99]]10.#">32#"$!232654&#"kK7c7(IeN(ˆ5xWPlpSUsp2UFdHJGב{IqQwzy|~[ 9@$  {   ?o  l+/+/]9/9]??910!!![h~I:j0,팣gT)5@  v ! 6!@+6!@3333 3@3P33333'-'06*@66x0(*$  0?7o*6l+/3/]+/]3/]9]9]++??9/]]q++9910]q&'&54763 #".54632654&#"32654&#"I`,<&8*Zwue|x4_OFZ^IJ]vLItuMLq3?VpuZcV@<9rnh1nքQL]\IL_]?a{}`a|xG(z@&x  6 & 6&@1 6&  g#?*o#)l+/3/]+/]9]??9/+9/+99+]]10%32767#"54>32!".4&#"326fL7b7(Ie دʆxVQkoSVrI3UFcIKF֒{sQwzz{~|/&)@? he++/<<??]10!!!!|MM&hh|d/&>@$?     he++/3<9/7#|M_tW&hR6kIkpI`@6 P`P/]7654&#"%6!2!!,WQABG] |چ^e5wi&ayd~B77=^u0[{UrPa>N9 6ֳ6@h6 6V<$$6J1C4>>J:::::&..C4=G>1>>>>@111 )?77777"/3/]/33/]3/]/99/33///]?2/]3/99]10]]++++327>5#"!2$73#"$54$3 #"&'#"&5432732654&#"}.:Vo˧kwRJmd;se @0I IVV      @96   O @@ p  /]33/]9/]]9]?$&r5!{IE@HSFAOaH@-  0`}} o}  l+/+/3/?3/]9?3/]9]10#"$! &'.#"326f(b=Mp&nDR>Wxr^lYC48|\ )@ '}o  k+/+/]??10!2#!32>54&#Hkmy_oxDl(n?i S@8P0@o  o k+/<+/33//??9/]qr]10!!!!!!?, J@2P0@   o k+/<+/3/??9/]qr]10!!!!!`g89^3!S@0 @ 6 } #o} " l+/+/3/9/??3/99/+9910!# $547632.#"32675wƿ(KdLY1c`c\GXNSX,5 4@o    n  k+/<+/<?$p@B  $  }&o$%k+/<+/3/999]?<54&+ވh[:eQ%_.$1>(Y-9Z|HÌz7#v WW"h J0GLGy,@6"###4#T## # ! #O@P6@ 6*&@6 ! #&@ 6}}&.&o@ 6}@6}-l+/3/+++/3/+9+?3/++]q9?3/]q99]10]]%32654'&'$'&546$3 .#" # G+Fai22'Um`OP! x)ui7Y[<9--(CooqscZC0#@x{ /@/32//??<10!!!!/a2;2P.@ Fnk+/+/?@ /]5}*@/]33/99/99?3/<910!! ! f///3/]10!! f@/2/3/?3/]10!#[I>)7 @ 63@ 6&*##3&@ 6&3@. 630X6 6#79h08f+/3/+/3<99++]??+?+9/9/+9/9+10%>7>32!.'#"&54767>74&#"32>5{SN8rJ4< POlGGL>Nd2'IT[|!"CADu1)fu+")A-K+KUB)+.M!,yNN&.%K< ! !*0=B_L}W@ ;[ 6@* 6 f ie+/99+/]????99++]10!>32#"'&'!32654&#"}=^t}kYCOgOIcaESi@@.$c{y~v{J> V@887XW0?8 ?"i ! f+/+/3/]?3/9/?3/]9/]]10#".547>763 .#"326 㯩\8)Kw7_Pe}|`Pm,yb?mP13DERHg@ ;[ 6@ 6   6 6 @ 6h  f+/+/99+++????99++]10!5#"5324&#"326PBXl_<jQG`cINhFd#.J@@\}{vyzH> ]@   @ 6@ 6 8  "i!f+/+/3/9]?+?+9/q9/9/10!32767#"&54!2%.#" *;_<6!&\?b gTa:% b0E0%w4ҕvfM0_Y^@%@ 6 66 6/+++3<<22//9/??<32&#"@hMk-I-70 &*0Ac= %(IQ>$0@g!2#R# 6$@ 6$.( 6 6 @) 6(.!i+2h %1f+/3/+/99]??/?+9/++9/99++]]10!# &547326=#"'&543232654&#"^}Uٌ-DXW<<^mՃ]|FbPLglNN]&/dp2"-7^uG 2Tasostt{q{Q 666@ 6   he+/<+/?32!4&#"!{SpgJCJ\iVJ]HdSp!(@ he++/<<???9/10!!!!iiQ#C@'  6       he++/3<%jг6 6 6@- 6B %$O%%%%&%e+/]9/9/?<32>32!4'&#"!4'.#"!~|Rv/`th)=HXh @+FZh&aRZYhKe]H#7hsIF(1jy{>L 66@ 6   he+/9+/?32!4&#"!{{U}gJCJ\i&j[]HdSpI > 2@ 6 78  if+/+/??]10]4! ! '&32654&#"IH?sWXqrTYt;ǂ}l>j@ 4T 6@ 6   6 @6  6  ie+/99+/+++????99++]10!67632#"&'32654&#"}}OBYl^=jQG`dHNhlc#/@?~zuyzHl>]@ 4T 6@/ 6 66 hf+/+/99++????99++]10!#"46325!4&#"326e<_t|kZBO}hgOIcaFRil?@ /#czyuz>K 6@$ 6 e+/]92/]9]???999++10!>32&#"!}7uVZk~H*P,?g&qU8B]3>.$ 6&@ 6  6&@#6 # %@6@ 6@666 6@:6,( (9 # %(@6@6@ 6(0(i66@ 6 /f+/3/++++/3/+++9]]]?+3/+++9/?+3/++9/9+10+++%327654'&'.54>32&'&#"# &3ZKR-#.!ԥqzִy(~#0DE?((io&&H>#',%?`iK:zh&3 1#'R[\g8UU@&    @ 60/]+q3<<22//9/??<=&54676763-?? %@CA.Ab~äF*OKMM(;4'CYr57M;$CR"U$$tb,W0cv"* l@ /]3/??103#QW^@c4@     //]/<3/3/10]]#".#">3232sL:uH]`1lX'\>"~ISFf>2$k@ %&+55+55>$!@=I iX WY!IVV!! !   @? 6 !     !  p  /]3/]9/]9//?2(k@ %&+5+5%21k@  %&+5+5]L22k@  %&+55+5528k@ %&+55+55I2DV@ :: %;&+5+5I2DCV@ ;; %;&+5+5I2DV@>>: %>&+5+]5I2DV@ ;> %;&+55+55I2DV@ F9 %F&+5+5Il2DV@ >8 %;&+55+55JQ>2FV@ 33 %$?5+5H2HV@###%$&+5+]5H2HCV@ $$%$&+5+5H2HV@''#%'&+5+]5H2HV@ $'%$&+55+552@%&+5+]5!2C@ %&+5+52@  % &+5+52@  %&+55+55{2QV@ "%"&+5+5I 2RV@ %&+5+5I 2RCV@ %&+5+5I 2RV@  % &+5+]5I 2RV@  %&+55+55I 2RV@ (%(&+5+5w2XV@  %&+5+5w2XCV@  %&+5+5w2XV@ %&+5+]5w2XV@  %&+55+55i *@    /]3<<2//??<32.#"/18(3RpC7QBcV^yL,Е&ٸɋK0:HMUD48 2&!,[% /}ZM,_o&EKi   2P2`2222>,J,f+/33/]/]+/]33//]]9999++?3/]9?3/]99]10].#"#".'%32654'&$&5467.54>7632654'&$C8C>2gfNW53k|}Q(x$\CEE)9Yl3.QC[x%4n-',904(".C`\]XK:vLhm*JaYL'ID@/()8mVL8lCVVEE* 2D)!&L @ /]3//3/10#"&54632LŠŠщÉiQ*@ //32//?32#"'&'732654&'&'&54654&#"whu,8&ƦzZCA#"#.7Nv=29Kx}R$1(wrPb* L,."RL;&0;;-;\v:11:@ * 6* 6ֳ 6@I 6""#2//1: *11#*06 *)O)O))))):011/]3/mjr/"uP( XXHES`bcii}iRx7[9--9:17@ * 6* 6ֳ 6@K 6*/++++.'`'''  5!o!!!+**1$$/]3//]3/3/?3/]3/]9?3/]3/]910++++#"$54$324#"32%#"&54632.#"3261bb͔iiJ&Ci_DNj$5a=abcii1yAeùzQO=XZ$I@]@ P    p   O _ o  @ P `   O_ @P @@P/3]2//3/]]3/]99999]]]?<<<2/<<<<9]10!!#!%!!###$!~eqwZݙmC@@@/2/3/?3/]10!#K^@ /3/?<<10!!%!!b@xv@AV        P p  _  /<3/]/]<3/99/3<<2/@" %-"  -'% **//9/33/3/]/9/10>32#"&'#"&5463232654&#"&#"3276$J_^Kb s@B   P` P`/]<32#".54>32654'&#".#"3276y*4sԄaaK{]HtG~Qe"oEFBVs<;ce~̽iNORYR-^:( gY=PaGu+Q|@A         /7Lc({n22FS9K(Q$%wah.Qh%G@'!  %'n & k+/32//<+/32//<?<<<32#"'&#"#"&5463232654' -.O%2K5'#) %@M-4B3'(: %$q=-C(/9$#*gfC5\zj,D5-6@!*N;!".X@3@ 6#+.O   (  /q33//]3<99?3/]3/99/9/+910#&'#"&54767674&#"'>323265 .,>R}54hV,951 FpoFE 94-?J$+vaX558+",+GQ*89|>9*$0PT '@  /3/?3/]10q4>32#".732654&#"V|ΨN+!@9JK<=K]_dΫmUl4(\ln]]S(m@EYVfv$'&'&?o * o%0%`%%&&%)l+/33//]9+/33//]9??<999910]]%&'.5!2%3!567>54&#"!53'tEec=9JH~a8LM岪WQ4\{b1?Z6~V/:PQ4+E?9@O@10,#J'&@ 6&&#A #@ @=@ 6=3#@ 6#, 6 J@4 6J60@ 0OOOOO:G :Qi&''GPf+/3/+/3/9/]<9+?+<+?+?+9/9/99/9/+99910!3267#"'&'#"&5467676$767.#"%67>32>32%.#"326765 $7Y2I#QץwZS{݇@1AL#'CY=QUTy'5ŞfIX\g݌'jYQHgy}cOB67t`/G-7#0$TZNEz$/ 4 P:=B-j6J[9:.XKcgrhqw)L).@89)DI #-@ @ 69@ 6@ 6 @W 6-$ # $#- ( (#$-+  !+/i!.f+/+/999??3??399999.+}ć<<<<<10+++]+!"'&''7.54!2&'&#"32654'h|EZqV;ZiULFpX;W'1eK!(0b^:| +a[t;,5I~3BIS&"& ?55|l/&W&@  ?55~<m@  //]/3/10!!!~DmTdM@B/33/9/9/99/32&#"?üIg3',;-QnI]<'-~;$+Q"U~D>'/Yc)@     6 @5 6  #((    /3232#".#">3232sL:uH]`1lX'sL:uH]`1lX']="~ISFf\>"~ISEek^@2_p/]33/]99/9?3/>2$Ck@ %&+5+5>%2$k@  %&+5+5]L%22k@ (%(&+5+5G+x@M $P0@ 8(   - o },l+/+/33//9/<<9]??9/]qr]?9?910!!!!!!5#"'&7632"32>54.<5@Jb慹KJy/?x;=|85w])6z~Ϯ[Y_ĤNUǢV;>!(4@"  62 ,(%@ 6%2@ 6 ,@$ 6 (0////")"6i)5f+/+/3/9/]9+?<+?<+9/9/999+10!3267#"'# 57632>3 %.#"32654&#" bO4L$Ccdɏpg\u 3g \LKeWST\\EXavd.4$vA5?p6E>=vaerVztst  ///10!!   ///10!! 76.@_   ? O  ??55/]5/]]576.@_   ? O   ??55/]5/]]5F -@   6/+9/2/9?3/910!4673M^sXOR6kIF -@    6 /+9/3/9?2/910!'>7#F_tWQ6kIiL F @" 6@ 6`  /3<<2//]/32/+q/+q10!!!!!!oCWoL[\/ @c         @/]<33/]9/]9?32&#"!!!! RgN-HB7]ss&*032&#"!! RgN-HB7]s&*0@      /]3<<<<2/7#F_tWR6kI7d6.@_?O   ??55/]5/]]5 '3?K@= 67@ 6% 6@ 6  6@& 6 1I77C==+% 666@5 6 (.o"""(@4`444F::Mo /3/]]3/3/]]9/]3/]9/9/+++3+?<<<3/<?<<3/++++++.+}104632#"&732654&#"%3#4632#"&732654&#"4632#"&732654&#"4'(44('4IJ4('44'(4览4((44((4QȺҺǔPPPPȺѻƔPPQQȺѻƔPPQQ>12$k@  %&+5+5i12(k@ %&+5+5>>2$k@  %&+5+5i2(k@ %&+55+55i>6(Ck@ %&+5+5>2,:k@ %&+5+512,:k@  % &+5+582,:k@  %&+55+55;n>2,C:k@ %&+5+5]L>62k@ %&+5+5]L122k@  % &+5+5]L>22Ck@ %&+5+5>28k@ %&+5+5128k@ %&+5+5>28Ck@ %&+5+5!&@he++/??10!!i&;@!@ 6/33/+99/99?3/]<910]q!#'#!zz♙1@ 6 @ 6 //+?<3/+2/103#"'&#"#&54632326pX@O vQ#>&!oz5 $.k~F%//?10!!y<@(F p //?<3/]]10]]q3#"&'3326N\JJWK_N:11/?10!!:dEl #@  /]3//3/10#"&546324&#"326Ecddc<++<<++<{dddc+<<++<<Qo3@    /33//9?3/3/3/9999107632#"'532654&#"t^R;~rhuV=25GvtO0f>{.%*.Q̳6@'6O@ 6/32/3//+q3/3/?<3/]<10++!#!#E5Hҿ'Ai)@    /3/99?3/3/991073327#"&54ȩJB/Q|XxW9LN.jY5@ 6/33/+99/99?<3/]910!373zz W@9        o   k+/3<yl\tr P@6         h e++/3<<2/54&#Gnnx_oxDl'n#?K +@TYkv )9    )#   & & - i ,f+/+/999???<99<<<<10]]]7.'!7!"$54>32&'32654&#"AAgC<5%㈄z<9&8D=}sRLLTtZ@M# (He6  "wRkˏt=>2<k@  % &+5+5Q2\@ %&+5+5p 5@  }o   k+/<<+/?3/]?3/10!2!#!32654&+*9oj\D[GDa}lO4T@* 6 6 f   iBe+/<+/]??9+?9+]?10!>32#"&'32654&#"}@b^=jQG`dHNhlNC<@?~zuyz; //]/10!!C} @U          II@6@ 6   6 /+3/3/++]33/]3]/3/3/33/3.+}ć.+}10   ' c>;=>;??;s ,@   /]3/9?3/]9/910!567s8[Oh!!-H@, {p0`/33//]3/9]]?33/9/]10!>767654&#"'67>32!oo-/1B+*+>][J$$&5<P(;G\E:;t)-@ $#?*$$$$##@6##** 6 @ 6 $#' /33//3/999++?3/]9/+]]9/99/]9910%67632#"'&'732654'&'72654&#"-1H`\A$APLIc̿f;:08?8 uV<)()!(^+8C0L5-fC^7KN-Y0*7&3,!#67N?567m ?55F6'7 <?55 6@H 6  P0@ k+/<2/<92/99/?32&#"!!!!!}8tWYk~H*P,?g9`gIqU8B]W^3>2*k@ *# %'&+5+5IQ2JV@ 92%6&+5+5n?2,:g@ %&+5+5GQy26@ ??&%0?5+53Q>2V@ AA(%2?5+5a>2&k@ !! %"&+5+5J2F@### %$&+5+]5a12&k@ !% % &+5+5J2Fj@ #' %"&+5+5H%v@ 0@; 6;[ 6#  6 6 'h & f+/+/3<<99/9/++??9+]?9+?9/]<<103#!5#"5325!5!5!4&#"326ٸPBXl_<2hjQG`cINhF]d#.J@@t\}{vyz? B?}0//10!!}Mh) X@6  )     &  p  /]3<<2/]/99]?3/]9/<<99]10!533##5hccIy>F2$s@  %&+5+5I2DW@ @9 %=&+5+5Ah2$@ % ?5+5IA9>2D@ F;%8?5+582'r-@"@p@P`%&+5+]]q5H6GQ3@  ?5/]q5Ai"(@  % ?5+5HA>"H@ /$%!?5+5i82(r@ % &+5+5H2HV@ #'%"&+5+5B@) n }` p   k?O]+/3/]+/? 6   h/_o?O]q/3<9//]r9+/?7#!!4#"!!3632aTfiOVh}C&jbnFHu%]LG62t@ & %+55+55I 6R@ & %+55+55>B25o@ ''%(&+5+52U@ %&+5+5>825r@ '+%&&+5+52U@ %&+5+5GyF26s@///%0&+5+]532V @ 11%2&+5+5/27Q@  %/5+58U2WQ@ %/5+5/827r@  % &+5+586WQ3@_`p?5/]528r@ %&+55+55wl2XV@  %&+55+55E28r'@ @%&+55+]]55w2X+@ 0Pp %&+55+]]q55"F2=s@  % &+5+5%G2]@  % &+5+]5"?2=g@  % &+5+5%G2]@  % &+5+5  @ 6/7ut7r+VgY^ۦۦZjjZg"*327632#"&547#"&5476732>54#"o8&-&]LZ4 D=ӟPVZs#(TP7`*-Q"97L$aoRd_JOl 3!!#&'56LQr;f`N߿lefX-GSh $73&'#G.WfeM`e=rQOl #67!5!&'M_f;rQlG-XfeSh 5367#&efW.GLQr>f_M߿On#67!#'563!&'3PE}}EPබPE}}EP-OO-OUg3&'67#&%55$-OO-OPE~~DOᶶOD~~EPg3&'67#&%55$!!-OO-O3PE~~DOᶶOD~~EPbjk3!!jdedh!#>32#4.#".n$S^{m`qr]0vۥxA6ˣrtN !5!5!5N111{{{{{{B!!!PLPdR!R10R! !R170K# 2#"54$kpf 2#"&546"32654&kehhgGhgHHghkhhhLdKIffIJe #@   /9/3/9/2/910!'67#YnGyzyl}0h6S>6$T@ & %+5+5I6DX@ ;&;: %+5+5aB6&|@ %&%! %+5+5J6Fh@ '&'# %+5+5aL6&t@ !& %+5+5J6F`@ $&$# %+5+5i6(T@ &%+5+5H6Hh@ $&$#%+5+5iO6(|@ & %+5+5H6HH@ &&)"%+5+5iL6(t@ &%+5+5H6H`@ $&$#%+5+5^3B6*|@ (&($ %+5+5IQ6JT@ 7&73%+5+5^3L6*t@ %&"# %+5+5IQ6JT@ 4&43%+5+5^Q36*P /( %+5IQ6JQ 0@ 2&21%+5+5B6+|@ &%+5+5{>6KXx@ & %+5+5]@   @( 6o n  k+/<<6-dx@ & %+5+5Qk @= 6 @ 6 @ 6 he++/33/9/33/]/+9999??9?36Q ! %+5R'N 6@( 6  }ok+/]9+/9/???9?3/++106$3 !"'32!"!!F?g=6"qbh<Qt#P pxtJfR=A@&H   ie+/9+/9/???9?99]10632#"'3264&#"!!+Χρ='!C4MOHKVySi#' t%]L62T@ &%+5+5I 6RT@ &%+5+5]LS62@ &"%+5+5I 6RL@ &"%+5+5Q>65 &+%+5Q>6U %+5GyF66@ 3&3/&%+5+536V@ 5&51(%+5+55N@/     PP/]r33NIuA6>6:x@ &%+5+56Zh@ &%+5+5=>6<x@ & %+5+5Q6\0@ &%+5+5w "@  e+/2/??92/10&#"!4!2;.&y1= >6c@ %%# %+54I6D7V &@SA;&SQ %>8 %+55+5+554O6D|@ &%+5+5E6@ S&SQ'9%+5+5#O6|@ +&+)%+5+5I 6T@ 1&1/%+5+5}@ @/3/99/10#}B+ ?@"@@ 6  ?@ 6 /33/+3/99/]/<<2/+10#!5!!5!-BX+>6$ %+5?5x/3//3/10!!:i7(  %+5?57+  %+5?5V7,@ %+5?562l@  %+5?57<@   %+5?56|@  !%+5?56@ & %+555+555>$%@ok+/+/??10!!!;<R;x@$962@! 6p/]33/99/99]?<54&'ddekvyhde|{JF=9Eoj"^mf=;R=Y@)BB  P   p@ 6@/]+qr3<<2//]??9/10!! !3!2>5!=;Z__[}VOeLLeO^LY@"  @6? }  o@60}l+/392/]+/+/392/]+/?<<<c# PLRN'~xWԃ4C_-5>ɉ%wj%X@7 6% @ 6"'i   & e+/]<+/9/+]99/???9/9+10#"'!4$32%>54#"32654&'jy jKLd@CDKVF{ô] iLi^[Sf j%@(6@! 66 60O ]/392/]++9/++9??<<<9/<9.+}ć.+}10 !!Ti\%5`J K@-9  i  f+/9/+/9/9]???999]10! 547%!265#"/ļ-biehg`X6;`w|@JZ=@p@ 6@6 @@"66 6  6@ 6 6 @ 6 f+/9/+9+3/]+3/9/99+++?39+}/]?3|/+9/+]910]%! $547&54$!2&#"3"327Zɼ"ojghRGM:P42:A^RNR<@"   0  f+/9/3/]3/9/??9]10 +254.547!!=_BqF2ّld! W][VxYY~voױ!&{N% @#       @,6  6    e+/<3/]33/+399]?<R% P@ @6@ 6  @ 6  ? ]3/+3/3/+3/+?54&#".x?@?TlX;80Z  .~[uhxZ^j!% @   @7 6 6     B O  ]/]q33/3//3/99]++?<<H&Lk|h;3^4H5QGKPJRhS6L@  & %+5+5^V@3@ 6?     oB}l+/+/3/9/?3/9?3/99/]+10! ! &# !!!27DyohC+F%>sdGy6n,82,:k@  %&+55+55#- Z V@4{   / _ o  }h"o !3/3/+/]9/]<?3/?9/10]3 #!!#"'3265!3254+DK#;J`D\L)R=z)Ql Zb@={o    @6 @6/  }ho   k+/<+/]9/]++<<?<?<9/]10]3 #!!!!!!3254+DK#H<)P5V=@!  h   /32$ =@! 6   }o k+/<+/9/??9/+103 )!!3254+\MB%@ok+/+/??10!!!;<R V@    @6    n+/3/3/]+3/99?3<7.+2!>7>3#"?F>R`GTGptg4EB<;BF3htpHSGaR{CDCaX64wN3Nw4Xa ;5!}@66@ 6@+ 6 } @6 }#o"l+/3/+/9/+]99/?3/+9?3/99/+9++10! %32654&+32654#"%! -}$^azj{aWckc6G ^TQe[Qw/}Գ O@.7 87      n k+/+/99?7>3#"?F><;BF3htpHSHbR{CNw4Xa 7@! 6 n  @3/]3/+/?9??+10)!#"'3265!;;J`D\LR=z)Ql0+]L2$@ nk+/+/?54&'ddekvyhde|{JF=9Epoj"^mf=; 1@    k+/3/3/?3/?<10!!!!!3TĞ?R,@ n k+/+/<??<9/10)#"5!327!;лf`P!s >ktj7L 7@"    @/]33/]/?%F+Cbqxssd@) i   } B@"6@6/}ok]+/<+/9/]++????9/]10! ! #!!265!  ;x*oz<xsaZbW5B@I>DJ "\@;P vy  $i # f+/9/+/9/9]]??]??]10]63 ! ?67!2654&#"I+9{Cݞbil[ehg7ItX$ G|{%p 6@ 6/_@% 6@6? ? ie+/]<+/]9/]+9+??9/]910++)!2%3254+32654+yzavgfla2>p5 r%zVX]K.,`%$@@e+/3/]??10!!!HZ31@/!.(' `  @6 O  ''@6@  @@ 6@/]+q3<<2/]+3//]+3/]?<7.+2!>3#"Z5#1/h.1$5Hhk5HNVXѵc\&..&\cWWNH5fiL%I!q J?S 3#"5%G4i20[HpRV4D-,U\]%F$q%8X, *3 9?%=@$ 6  h  3/3]/+/?2/9??+10)!#"'325!?iˑH&RdC-z;% @?      /     @$6PphO e]+/]qr+/]+qr9/9999?<<Rw%$@ he+/+/?SJ>F%;@P@ 60/]+qr32//??<10!!!!h)Q&\Lj$/y@7 %+% VY.O@"B (B@  6 @ 6 0 P  /]++q3<<3/]/]]??<3!5#"3i+1=FrgŖqiZ,/03 hg+h+'TH2HV@ $'%$&+55+55f$]!@4 6 6! ! &h%e+/3<<<2//+/2/???9?9/<<++10%#"'32654#"!#535!3#632*|>628OWhwwٱ5w#' Gku^^2U@ %&+5+5J=r@ @ 6 0@* 6   iBf+/+3]/]9/]?3+/]9?3+/99/10! 54>32&#"!!327m)Ъ9 ,3&1wp.u3Ѫ3>V!L2@  %&+55+55Q#M%n@  6 @ 6@ 6?i3/3]/+/]9/+]<+???99/+103 )!#"'325!32654+?5ˑH&Rd2>pC-z.,`%n@    @ 6 6@ 6 i  e+/<+/9/++]<<+?<?<9/9/103 )!!!!!32654+T6eh2?qo%k.,`[@ 6 P  @% 6  h   e+/3<<<2//+/? 6  O @/]]3/99/]]99/99/9/??+99?<<<9?3/+]<.+}ć.+}9910]!!#"'3267#"&'33267[HKjX XlHYĈ MV&=D`BUӑk+@w% _@ 0  @6  6 6/++]3]2/]+q/]?332&#"!!!!632327L][.+ )ʨo$-j:G+1 +5(34կ K K !!!!Dkkͯ; !!##)2}t #!!#!q|;t. !5!5!5!#llCXͯ !5!##*} !5!!5!#=*AůXH 3!!!kX;ͯH !333!ͯ2}}XH !!!!3qR+{H;tX.H !5!5!5!3.lXͯH !5!333֯ͯ}XH 3!5!3!5=R{H|H 3!!!!kk ;ͯ;H 3!!!3>)կ }} KH 33!!!¯ͯz) KAt;t;.H !5!5!5!3#llXͯKH !5!333*֯ͯK KH 3!5!!5!#={* K  !5!!5!!#(lkԯկ; !5!!##*)}t !5!!5!#!!!(*|)ԯկt;XH !5!3!!5!((ԯ;կH !5!333!(֯ͯ}}XH !5!3!3!!5!p{֯Sz(ԯt;կH!5!5!5!3!!!!#llkkXͯ;ͯ;H!5!333!!##*֯ͯ)}}}}H !!33!5!5!##!{ԯ{*,t;կ;tmH!!(mm!!(H! KH! KH! KhH #'+/37;?CGKOSW[_cgkosw3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#3#%3#%3#h}}}}}}}}||}}}} }}}}}}|| }}}}}}}}}}|| }}}}}}}}}}||}}}} }}}}}}||}}H}}}}}|}}}}}|}}}}}}|||||}}}}}}|}}}}}|}}}}}}|||||}}}}}}|}}}}}<H #'+/37;?CGKOSW[_cgkosw{=@Ի{|xsokgcplhd`WSOK_TPLH\C?;73@<840+'#($   Ծ{xvcu`Z_Y\F3E0.-zzרzzxz{`zc\z_0z3zz{{{cc__33{uEtDŕqAĔp@əm= Șl< ͝i9 ̜h8ѡe5Рd4եa1Ԥ`0@Y-X,U)T(Q%P$}M!|L IHy]x\ -,)(%$! yy y y yy-y,)y(%y$!y yy,,(( $$ 9/9/9/9/9/9/9/9/9/9/9/9/<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</9/9/9/9/9/9/9/<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<103#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#73#3#73#73#73#73#%3#3#73#73#73#73#73#3#%3#73#73#73#%3#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#3#'3#'3#'3#'3#'3#3#73#73#73#73#73#yxxxxyyyyxxxxyyyyyyxxyyyyxxxxyyyyxxxxyyyyxxyyyyJyyyxxxxyyyyxxxxyyyyxxyyyy;yy>xxxxyyyyxxxxyyyyyyyxxyyyyyxxxxyyyyxxxxyyyyyyyxxyyyyH}}}}}}}}}}}|}}}}}}}}}}}|}}}}}}}}}}}}|||||||||||}}}}}}}}}}}}|}}}}}}}}}}}|}}}}}}}}}}}}|||||||||||}}}}}}}}}}}}|}}}}}}}}}}}.H=AEIMQUY]aeimquy}#3#3#3#3!35#35#35#35#353353353353353353#%35335335335335#3'#3'#3'#3'#335335335335335#373533533533535!355#%353355##5##5##5##5#353353353353355##5##5##5##5#35335335335335||||||||)}}}}}}}}}|}|}}|}}|}||"|}|}}|}}|}}}}}||}}}}|}|}}|}}|}}|}}|}}|}"|v}|}}|}}|}}|}}|}||}|}}|}}|}}|}}|}}|}||}|}}|}}||}|}|u}v}u}v}u}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||||||}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}||||||||||}}}}}}}}}}|}}}}}}}}}}>!!PP=!!~0! 0u   U,,0l ::lu UX #"54324&#"326L՗֗Bו|P3!4&#"326|vTRxwSTv,SwvTSwx&3!4#"32'#"&54632&L֖ז}A֖ #/9! ! 4#"32#"&54632#"&546327327#"wv\@A;/"!00!"//"!00!"/>ON?hu w@@d!00!"//"!00!"//$$ #-! ! 4&#"326%4&#"326327'#"'wv/"!00!"//"!00!"/gh?NOu w"//"!00!"//"!00$!IU'33!!#&''&'!5!677674#"32L6P6᧷L̏1}P1&$-.U7⮳E3}Qr3!Eǚ7 -.W#!!#!5!".54324&#"326M_6^Sړ6q6mkĹͰj\'&'#"54325>"32654&W#~InL^%桢\ * !|Z5]3ঠ㚤9#"'!72654'#"&5467$ ]z_Yd˯Z[iTRoU]%%̿ Z\D; +)7>5'#"&54632&54632632#"&'Nu6`ra?dCvsEj8ipNLX"!G}*tzwp3kKqo^]5oxcf;}..54632>32^ yeNmT"]mQzTn}dX?& 4UeD4V+3#"'&$'#"&54$32<(#7fݒEd^L9,B@zy…^0? #"&54632#"&54632@KqTtE;}|_n#딒`lu2R+{qw6Qo3@    /33//9?3/3/3/9999107632#"'532654&#"t^R;~rhuV=25GvtO0f>{.%*# @@6  @ 6  o@ 6 @p  /39/3/]9/+?3/]3/+]9/3+/q99.+}10632# '732654&#"'!!KgBH/8IG?!QA\N!l#+2>/28 PA@?o6@ 6)/32/3]+/+?39/]10!!5!#&dD]8' 6@+ 6 $@"6$@6$@ 6?o@6 6  !@ 6 & /33//+]q3/9+9+?3/]9/+++99++10#"&547&54632%2654&#"254&#"Ǹi6@7=yA6F=m(w}|x)+jfkkfi* (!I *e-5beb{#/@ " # @ 6'@. 6-@ 6  @ 6$  "#@ 6 */]33/+<9/]3/+<9/+33/+<9/]3/+<910>327'#"&''7.5467'4&#"32619o66p9Ӎӌ=q44n9֍pPOppOPp{я6m76p:ՏՌ4l89q8PppPOpp{      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~spaceexclamquotedbl numbersigndollarpercent ampersand quotesingle parenleft parenrightasteriskpluscommahyphenperiodslashzeroonetwothreefourfivesixseveneightninecolon semicolonlessequalgreaterquestionatABCDEFGHIJKLMNOPQRSTUVWXYZ bracketleft backslash bracketright asciicircum underscoregraveabcdefghijklmnopqrstuvwxyz braceleftbar braceright asciitilde AdieresisAringCcedillaEacuteNtilde Odieresis Udieresisaacuteagrave acircumflex adieresisatildearingccedillaeacuteegrave ecircumflex edieresisiacuteigrave icircumflex idieresisntildeoacuteograve ocircumflex odieresisotildeuacuteugrave ucircumflex udieresisdaggerdegreecentsterlingsectionbullet paragraph germandbls registered copyright trademarkacutedieresisnotequalAEOslashinfinity plusminus lessequal greaterequalyenmu1 partialdiff summationproductpi1integral ordfeminine ordmasculineOhmaeoslash questiondown exclamdown logicalnotradicalflorin approxequal increment guillemotleftguillemotrightellipsisnbspaceAgraveAtildeOtildeOEoeendashemdash quotedblleft quotedblright quoteleft quoterightdividelozenge ydieresis YdieresisfractionEuro guilsinglleftguilsinglrightfifl daggerdblperiodcenteredquotesinglbase quotedblbase perthousand Acircumflex EcircumflexAacute EdieresisEgraveIacute Icircumflex IdieresisIgraveOacute OcircumflexappleOgraveUacute UcircumflexUgravedotlessi circumflextildemacronbreve dotaccentringcedilla hungarumlautogonekcaronLslashlslashScaronscaronZcaronzcaron brokenbarEthethYacuteyacuteThornthornminusmultiply onesuperior twosuperior threesuperioronehalf onequarter threequartersfrancGbrevegbreveIdotScedillascedillaCacutecacuteCcaronccarondmacron overscoremiddot foursuperiorAbreveabreveAogonekaogonekDcarondcaronDslashEogonekeogonekEcaronecaronIJijLacutelacuteLcaronlcaronLdotldotNacutenacuteNcaronncaron napostrophe Odblacute odblacuteRacuteracuteRcaronrcaronSacutesacuteTcedillatcedillaTcarontcaronUringuring Udblacute udblacuteZacutezacuteZdotzdotnoGammanoThetanoPhinoalphanodelta noepsilonnosigmanotaunophi underscoredblminutesecond exclamdbl nsuperiorpeseta afii61248 afii61289 arrowleftarrowup arrowright arrowdown arrowboth arrowupdn arrowupdnbse orthogonal intersection equivalenceH22073H18543H18551H18533 openbullet commaaccentAmacronamacron Ccircumflex ccircumflexCdotcdotEmacronemacronEbreveebreveEdotedot Gcircumflex gcircumflexGdotgdotGcedillagcedilla Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonek Jcircumflex jcircumflexKcedillakcedilla kgreenlandicLcedillalcedillaNcedillancedillaEngengOmacronomacronObreveobreveRcedillarcedilla Scircumflex scircumflexTbartbarUtildeutildeUmacronumacronUbreveubreveUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexlongs Aringacute aringacuteAEacuteaeacute Oslashacute oslashacutetonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammaDeltaEpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiOmega IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdamunuxiomicronpirhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonos afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061 afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109 afii10110 afii10193 afii10050 afii10098WgravewgraveWacutewacute Wdieresis wdieresisYgraveygrave afii00208 quotereversed radicalex afii08941 afii61352 estimated oneeighth threeeighths fiveeighths seveneighthshouse revlogicalnot integraltp integralbtSF100000SF110000SF010000SF030000SF020000SF040000SF080000SF090000SF060000SF070000SF050000SF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000upblockdnblockblocklfblockrtblockltshadeshadedkshade filledbox filledrecttriaguptriagrttriagdntriaglfcircle invbullet invcircle smileface invsmilefacesunfemalemalespadeclubheartdiamond musicalnotemusicalnotedblundercommaaccent fivesuperior sevensuperior eightsuperiorcurrency $79:<$&$*$2$4$7s$8$9$:$>>0 0 *H CkSjy|oĠ?00)ъĽ5ǛSV0  *H 010U VeriSign Trust Network10U VeriSign, Inc.1,0*U #VeriSign Time Stamping Service Root1402U +NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.0 970512070000Z 991231070000Z010U VeriSign Trust Network10U VeriSign, Inc.1,0*U #VeriSign Time Stamping Service Root1402U +NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.00  *H 0. h|,-.  WSu3* [4 Z%}XsjxqX)X^-bXq"X/6MJ;"V~!lJGj6 -Ӵ90  *H :>{թy=q#+(ߌe,ZbVkbEƢ5"r-| CMlX 5ʉp*}a qfbB="2"d$006C!FXF%`0  *H 010U VeriSign Trust Network10U VeriSign, Inc.1,0*U #VeriSign Time Stamping Service Root1402U +NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.0 970512070000Z 991231070000Z01'0%U VeriSign Time Stamping Service10U VeriSign Trust Network1402U +NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.10U VeriSign, Inc.10UInternet00  *H 0aGܴ^i b1FI:?xZcEO n06- o' Q`5OTOз,B Ѝ^㖴"IBlӘV.:X"e匫xGBh[-}0  *H m`_i{p+b#D Q#tI'\q5+ൖ苧KsH ڋ %VNGWF8V!&;-%2Λ@GmGv0;~*1+ݰUApF-,~0 0 yfnжneq0  *H 0a10UInternet10U VeriSign, Inc.1301U *VeriSign Commercial Software Publishers CA0 980416000000Z 990416235959Z0]10UInternet10U VeriSign, Inc.1301U *VeriSign Commercial Software Publishers CA1F0DU =www.verisign.com/repository/CPS Incorp. by Ref.,LIAB.LTD(c)961>0<U 5Digital ID Class 3 - Microsoft Software Validation v21 0 UUS10U Washington10URedmond10UMicrosoft Corporation10U Microsoft Corporation0 0  *H  0&dm{AO o*q.S26h5IؖeS zpm̳*02X|k%gw #1,0(0u0a10UInternet10U VeriSign, Inc.1301U *VeriSign Commercial Software Publishers CAyfnжneq0 *H 0 *H  1  +70 +7 10  +70 *H  1|8ӛ C(0Z +7 1L0J" Arial Black font$"http://www.microsoft.com/truetype/0  *H $2p#& +GQrvDR$;M KưUm mGrI ]m m|鵠Vű".)'Q,mZ: Ō?AqE?7lхa}2Hc!o5e8C1`UۀKa:et&|LO6跟V+P>?9H|5Nm8j+ QW)~P|lp0 *H  100010U VeriSign Trust Network10U VeriSign, Inc.1,0*U #VeriSign Time Stamping Service Root1402U +NO LIABILITY ACCEPTED, (c)97 VeriSign, Inc.C!FXF%`0 *H Y0 *H  1  *H 0 *H  1 981110215215Z0 *H  1B*]7W-0  *H |4J: ۰$sz7$fjbpcxHĭ!:| ? ّ/슩fDeS\K(%Qʢ:.&] w5Kx#' Node-path: trunk/vrs_anno/win32/smartmaplabels_01/europe-small.png Node-kind: file Node-action: add Prop-content-length: 59 Text-content-length: 1264222 Text-content-md5: 2276fed5c7e13797d2d0aab5d9cef9b0 Content-length: 1264281 K 13 svn:mime-type V 24 application/octet-stream PROPS-END PNG  IHDR5؂Z pHYs  tIME  :3 IDATxْ%ɑ%vT|[lVVXCo~_>H E8"#=FhP@mDfDLUp# @/2Cjxp1w3Ws&W;:FR' @.*tNhdJ)R#!c.̿oo|Ϻtuucl[7|ٿoW?/x.踘gُW?r;{M?dqCk嫏?;ޕݛ?|r>~4ÿT?0Wo7?qnqŃŃiޜvj%ϞOhÖVGO\a>={y;ʼ/Tk[jg-:>B:ϙ LPjѣ0no=ӲP/rz׃٣ʂtˮ Sh9G)T@FcSrCz{D} 7?l}`fL;]]]:h? / ~Y:v2Gc~N_c7J?:ǙD30K*8ivzD WF !c4%-RYChk\J;m1Pq_,c1[Ʀm}<YإXGy!Jd 6&3P5J(V-kH3(Z@?{uG͗Ev7ז|8_56/~͛?ηWpir|Ex:y5d~šby<|zu(OOrn6,}7jK棫ղ%O:np?_?y?LTy7 X7GOg?ǿgԌZv~־dg|uO>:KMu%tO.\o=|{)n:?lX]G/kv^_~TgoH|{s .g?~gl?3M=SsEȳApSf_|jZGWGOÌLֲ :&q<~K m9ts<jU6V۵J|#vc1%qMA,LD|6ow[5xyy=Lq֧{ xdnߟB|{w""z >A;o] ww: @ fbgyZotb[ ; 0fs@WU3F#ISC72g˥&"YX ̀ 8y4F`&`NQFkqxqˀ:N`@ `LU ĵ E&*%}mtH߆*'6q}bg|uoOl*;Onzff!AZJT74pܼشg<]7W~r6P_@?o対}\|˫$a<ujZF|; fEۻġ,<0Ab`UuYbaaP +"OD1{dlkk16ZE8*0AGY/cY%@JFduiH`i`M 7VܧRhQDkEq+"0n7fThtv|,9[mqENFUT31e%n bֲ̤SUau{eo%T g@s~\1U(1qIy.ulZ\BL;{e6d,^L*aj0Bd `qqrΰ@XZQR Jl.l$Y.ZrlڗxN&RYhj} LS!DZ*&ơxDQ-Ii=ʐ$zȚ%fi;RoB㐧v7dzH f `iDkiT U&,&9Q#RCH 4&DYure83)m^CD@!֯>GoG>Q ~9d?p:J;зM1OZ ]*0 r5eK}tʑSƁ)+ nwWw<6Azw;Z5&ՙ*%.<TU6X4 "U RE5f8 ŊQTrYs OݪEB Ӏ&0?\"M};RoL~bEw NN wy˘P82VLǣ: )z(u~1g?hOr>cdo~i.̿|~}g\z; 1nwrulĎ֙zԚ]TrU ?|%"8&5T`m˫a8"qci85!d+b׵f&'SoCD3藱v[8Tz&?xJ5śqxLՋ~n1Cp PH:P]'Im+JV$ 9PhpS6@܃*Y0OchCZN#alT p9ަSxpU]ڙu>G߾+7^6#bv4&0|Xv! lլjvi8o^G G%89ܾ"*Hd@kȈ ~d4\p/t#uZ[܉L6n;g,{:U48(ss;am͹vZJj04m#(VSI \{Ш7R<L d̕Ȝp\|($M<_.{<+8dH)'iVgǼW1O_>E׏aYHy;~u~;b<&)-Ux\]6yF mzMгCĠ]bu8e0r= ~ Yq_UnHN* # V ۋ/^/W 6W1LժMTĊ :=46qȥf :&zb"\j'~13'+b y}J.lP3Ԓ)*Z^Qkik dٓo}Жŗ?w5ҷKݬ#D3ފؾA+;>{*{Fȝአౖah.6Wݗ/#Zݍ|vx|do}3^?<8x>h˛RT ?X<:kpw_lE}Z~Cݿ~EUr˘ױ"`ieRQI–2cHm 8}zIQXՁYMH)i} Q=cndu~2aoUfafjew8,'9$&I:c5VXqd7 † >e71r'տ*0xd+] ĨF2h) i}cVJJ>':4y ݮX.vӸƋ>_V^cz]AIm{%zz^$̇ë'Ye jə\&pbRhVp;ͱ^ΨkP(פB;K9-Ca?TJnLͮ撚T ^U\QAM y/"p&n<[.fML(ԝ՜Bd"> I귲Rkխ̪ bfH b'f%{1 :ڔc,#4JD!lz/\<%N Pi(qLS:>r>Xٌb 4]ldѲU'$]KF`՛v!hh! ]ټմ88sI̍:Wt]l >BΏ/0,|gҫGTǗ_?>_}n_^}O~z///6۔]ALcjiba TFN㘺2fsPwb+% ]жa*ٛ@wuJqt KީŬ_ϛIN/oϚ|щGZBJbG!n둽' ),6Ŏ" -Dm3;gPZƒ= =n p8)cvgЬ}Q=O,t?xq[ypxdW1!(b1=1{ԾU~&7vg[?SF Cbh~poL%T0q{ Obua3.8$*v- S7KF2ܛHu߆zb1Թ% cf# Djn<6Xж3n_%)ΈDI/!q8If)jUj6"$VAq*Ŕ= jvf>f0䜫hu^]]]\\4AbFW{pYtp  q*STU)08; !okvNqa*#NAr>f!LyvI2Cfnp Ҥ&OrAJ2b(Hls@gxr-=;͞F4<\͖}ՉUfjE}Zu^,/#40tRt5Va/XTk9_։u-fQ6;[5I[B);{g_@9{V(6|O+ (}us  㴞uv[]?ooy1>KZ-VݚK˻;'Rnn}8Opuv ՐQk& aŏ͸<ǾkQ?sR0nwk^ ;müS yG # 7)Z[D,3S||_7x}PL0`Da6W4":hGX*# ml#PS3'G3щv9 OݛB.lc58݄y,$!b0LSy糱 qx K6| ,/~KR4BٍD)3r}Z1V4XqsƸ}j-D`:2:Ԫ41n٭olpeɋk>T.G+ewf\_?]F5;{g_c@oi~Do(_?r\N5h&;mdep YHW㬼.ϣ|rO=|W?e)/8wxcg.U'*Yx]r8ku;˫,{s;ur%=lX8o>ί6 B4X7v5W~q!!OMߧ٬}eyݞ]R׻\[Lqۆ@Pbh%r!pP5huIq!nUjSZP*Iq:BW09M=.xqtd,e-dgV9'ly+/4g &ze s"s Wuwc%IG^S3C#G9{}SMxTCaQ+F %Sqwe8Κ23ILY d`*BcTn S;;9߫~RE 'w7eGݗenmœ)þYdfvЩ#"S2/D+qlVјq*)iFv]ٸb?{pNÛ&ZK=٬i~ٺaOS %!C.9MIP f0թ-\D$Z1tb|w8v2 |ЛL TsuZ,3fq4]sA9"d67sXW|ZoMZՃ%ivOgnrD?* Ա.bf)y:p ]&o3RK w]MMh>K1x酅@L.]ew2St2gF:qK64`FUaS 6ilP|?!W7FLjN1MuCSIܭL}mLr1Jfoa2 0ɉ0IN,9FSWhO~TX2QTTOd'^Q >ub8 cӓЩ5#fD`~[k0$H\PLE҇]|04”,כ:ŘYD19 @^)L갹I)x祃2z#UANПb_tqW]lG`P2Ni?Mj֜|q<wξ6= 9_oݷ u.@NobE/RF*rCw|߼n^~nwa?ƛDgn5k.vqYofV-=xoDXaZy7"\ؿMAE;͍c]w_踻|XÔ\s`oZȐ!tg \J9qK !q5p< oRMHͬ!\ DHMi# ȮdL&kJN%Engp6,^+$ O_tCv8?(C)<Wv\6CG\se޴bf*do;%&Z j~^­jJU_j9>P`z?ܼPȢHI"O!8N@'B'iƦ~}o+#0n(Ǡ/iO~. zz(6͝V' z9TwqߝEf!c^b5RA| $9Dun'1x4f]2У V4zwvIn7Ɗ^<|'r^ &ۮ ajvi6&}4N(!_4MwxlVvcW͘YIeGtNj`ĄN^9H1Ʀ__:&nG.\.fm?o8mKu/pkm/p8DD$H`2\8oK/ulopnaPmgقfUyۑ؁4p"};I:["aTߙ /6"bDR7*+QH Mbezr(Dup&l|%%KTXīWEyr< >.UTElbP y/gRvwξ. ok&$?tSeKjLmD͍$8#(C1~n4cçc~_|~~xG{~|߻zhiq&ߵikXKLDU'idya8Q# ؈p̓ fIS3Y33@AEdRn5d;"$X srطS}d)˪)%9+b2`xw8 <Ʃ!O{y BULYI*rC1h&OI*fE\ y,4McώAj~qI~(PT$hdY9tEIU7w4|-9e@Cw=D"C,PSeia8Mat@EU`4Rp F OYq)jTMl6g(!)Ĝ]Dz@PcX8PxƔD$AW9DVOl`O+QӄF(h$, (HjXF&Fߝ l*ΑeES$qX%u.o*)һ_.\-_.68M_7i=aK7Egyʋ/TM{q˵ZYD݇͘w?Ǐq;a1|uVUUY4oO.@&ֳyߵLAwC :9;kf*qH9cw0/(|2\U8􌶜7cתbTbT͛MX b v"Ifo,a*>]m?v_U\AbG?driJq;yOPzK_G:{n0yE&ICLfi5՟BݰXx*M3 3S&`twbZ?[QM^~v}Wl2ŘDЁYˋ<>Xz#7«|_L{f9eD#@hm^D- 0 Y2Tд){H!СBG}Wۂ, tld ,~xOiZ} snpV9 ."RWԠ9QA (u=+&Ȓ),8ŜۡM!'%K)㜭!ei3+[Two aI0i)%pP$shIiw-(lF˒/3lgB)=>>\,ۇ@SYX`\b>3\ϋP+͠ 0NCYrV/r,fw*b=.NٲbǏx9|5 e0u;GxKK\iƐQ͘F ٲɫ0(e8LuB̄9!;QTt} Q,fU` Q@iz,G<+Yj#hfJh(ɓIFfDM~G:=LDCuU{H5c )T dsP+sY0 LrJedVT"n|Q Q>89T,L^N{P黁hZe94 3/ܗժvS7W0Leu>}~۫n*O7m3q߭XSI(aAe)Ͽ(.NGz!-ՒY@3HKw?5?Oi@?~4Cb$#P=n&'9v)U1(:p^cZoN owҷ8Ʈ.m1Yen6WMy#=ggޞ4e{T^>[~vo.i>YpY_g?{.7jfMxvzZ" 0>~٢$J9u3ŔrW4[.˪!!K"Ʋ,M+Jb9sʦy*J_Oq4"&QA١(S k՜09_= =4C W/0b?h szb8a ˘~Q̷\tQ|c7i5F@/օf<\,]3&`c&P7\m{K7>=>n/lfէ/ݏcQ[ݬ|RS־t˪an~nt=ޢoʵS*O~/̗+ɨnfreY92{6L9x. ٻ~T?ՏQ303ԣ*"YJ̀d9 smaІyiDe撳M߿Y8WW8ɫt9o҇?.^YÇgoppb_b.})5Wo|]P|(lت1} 'MW {VWYY4YZ6SpSS?'/^<_]>ӫO΢|f6wED 1e9;Wx"KydajfAF(˪.& h 0JOn@`J, ]B"vsj\-Z4[[?F@0=;ק3j}:lnO_frvSCǧET J!ëOoE`JjǬdQ! I IDATt@H DfHLhS:;)F2r8]O˂ӇO e.#z5r]\Zrf4@o[zA;vL ^VX̶0{MԫEa/uN=yOC_>9_E1Sl1L,=,,$AA$NH` 'OSXD'c4BE=۵YA~tP$i7E:BvCݶ{7 vWC|s:=~]m18W邜CoN^7^8Y-*eW߼7UywT1O˼\]|(&Jt0m>?'Y?HV >*[^fW(_)97|oâi)uU(IQT0<SRODqq: )%=W0+fd fs?a78Pa*}ʱ3H^q~>z7|  lV4 )b=2P]iCTQe&ErPdBI:Π1 vh}S͝Qtb<qmU&vdl..'mH;IJN\Uu&$fG"2PdhH {u ,fơw\VDyȏck(q˚0 ڡY團n'&MOVUdr b* H;+5<8G%(?@D)*K =~C̈́؏j4 ۻaŒqY3 b0cS QY0B 8ۇ4E`+)LWeU'I$ ݤ5!C7eLAboL9%d^6c!oyd6Lx 'ǜ͊IOm큼eES,[Tۤ7.X>[,nKDM`R1@~"h j %2sF,fQoX54>NWxvRq}vVJx˜j_?t۔_~bbpR(849r?_dU+WyFf+I[m7ƛ7go7XQ13 <ݹmMX.cWeۨ:s>+"S0b4,H4Ǥf*")O)F3}G ƘCf:M=&K|`œ&<#3V9)bH͢߷Ɓzq1$>cn8gQ|76t/^SXi'A\fIi$r`$`c=7CI $MUDv`x(m=;rNק4 &٬i=}qeӀzӳfW+SDZW$fdl#@$!uuS6QH@=  ÙC+˜:];`-nf@t/^̼fƇK/j:c **"&e IaF!"^mrai.3ռtiH]I\/J4KfAH:WT7un(n&-ݮ{x*ٲP1AhnS\סj1FPY*((=I?@`ed"d(9: FarMM}2\gd6LHšھm' 콟R>1IcI$&E,ZM@QNTGNh?_(7aڏ :#U=.?Ƹ{`a؏D q;\b !i/*u0CR)ÐMEU,K`8&g0[es~8C G/NzkۇAU31~§8h̊llY,#7lphCti =]E]X5(~3> (i2qq0eC8ޜ-lﭻ3a0RvH>w HO OS@:"~nFeKΔ%&&RiJz ~l(" M^(}/qv2&nU9[5~yYSrzYV_v?ы/Nxxݢ*Mb}֜R0=CI:C^/xJ;/ bų瓯YRwY!iX/7o_|Bg7ϧX~IUUH.! LL$9bi B(='  DsLLlSԡ@6C(̈́H2䔡haL!zuT;bJ~cU\cߥ#wF@G/2ڣ>Y}`!Z\" `TTi: F, .t1 Uԓ:Obٲ5;4d:]LO2:?,N_6?z#xgSss3I$Q]ZsɨJJO~/1tH2_Wr~~xw~0RtMM5+#5!(=pq(eL S2=}T4YL D4eA)RKDB2۪)WYfhe >=0vdӇqSFHYH)oP, *<n2J5@*IʊOO8Ne=ɾs]" s~W. }EQCcFa?CG6վ~29`( ~,  ɼӀIOO6NvlIo ac&f&oX].᪄v8Y#ox{_믿 /Ϫx}pͺ ~?|g+7ƊZq.W"͍^V?[A9bS?_0;Dmo.g.grunVg> P2ZTuJDi9F_2#0"J\ )E!!Fbr@&"8^ 1-tQb6|xh/ Kɳbw}3lS.#}\_\0TS@"b%N$H]Bij|q^ŹݹӘC1 *q 9a~ᇛIz13ʲi|vZ4\)3f64Jml Fsl#gl@ tr5܆sDU8ɘ1YA4_.NC4u9J>r_Z]HNo9n`9=1)et0v>4.nHUSK@d22 iHFr*B)f5RGC5V̈́r3*ے n1 r v`$$,0xʼnvZXi EA 77n>Bo(DEti: G0 `ML,"v_-^]o A}&$EBc VH,a^/_4N G49~Gր 4~v~x3ڼ.Z6100M~lu~YbdӠn;?vJ] N,c ` xldba eO9%sqp^ϚY)??p)yd3@Bt̆L@NL @0xKUl. LcG=I xIM!އiLCE 7u} gWxW98YTE 9cbdU}t31 IOcP9GD54M,@hOӛxOiMcS2M^bLs#9eYyY_/CQiJ" 6 j9gOE(3`]үOf(Z%#plCʬ  JH&TyF`.IxyizhvH+O,MtJ܎7e/vLoP_4?syjm=졪4lV#K_v-v3Nޑ̪Y2͠T %?5P4zx1# AЎvx[ӕ8o@c4TQ/{RÄ9o?P >GƲlkqzHdq2r }Tiυ7Rx"?6P {ՙtKsEE'>~lEþ{/}yw}?q^,/}u98M UjUr/geC>]sUUnca{:nw};X]\<$$by27fguaH]4+-WWY;8eԾoSTHUYPg3ѾYdƈȚm QZڥcfMV>KR lPƛ._g}ySVu.Ôm" [ߞz"N[7kwMUdVYص5K"bm{uyTeIMz3OФAbK-5%f472>7Y,g䤐L69pZ_|:WPf֔ep$W6_ݳ_X~J\rfQ RBIh…j=N7ٮXOٳý XUȼm."Id'잽_r{r S34f?0nE^<JJnur:е[4 f>gơtyRYIDcv0aކW_di>-eV9e${ysO=٢㬭uq\ǮUQ% Fd` BU4ni2"FtBUp54s?HEbePN݇5yE""VI9 ZXv붾XF%l⯾} mhb1F9uk>Yv(`;~8M97Lp-Q|k˫bX_/Fq -UkN):)s.|UjF3nBOq*0rd#DSIY1Z4Ӝm~eCDRdj#,)wVUMJUQ?r{y?fE*PXeqJ{g vmM[\׆'TCE979VQD0(X՜sTQT IxS/.Ĕ 3{J)gs!*񅜻+cDM022"iZ#>F?yqg/PX `|ovQZH(mQb2RR1d  esH!u[/7`hj q&u0Xo QrMyro g2 IDATX5HEX4/@%u63 kR G<%)@Q@O(E&HOE@b@'W5YMb` IA |L_xSs E4 _pJYS&Oߕ97ϛ_7 oX[3O]Ad&K(DDpm/ߎ/]Ǐ].^^n9'U}nVTNËuk}]㫷*[q^Wwq>}~r}YgIq펋YU(Sæ;|髫gLn|7WeQ\|IZGg;:6lMEo7"b10:o5>qZZzhì 2VֻIvK++ʦbx,L&vLU SYm.J_vL7>lǰ f.Ὶ"()=f*D%_I@ q>*ť%c Ɇ5$ I$L:c0CewhcӇOū͋9NUㄸOh:N/u{摢VM(jsɆDUx;-8j@&hm)>BuyQJs&`k綸"f8ڨ\P} ԐL M2b1ZJ9#IZZGTO~7m?MViW7ۭvy.6UG3 MC2߾=QmTabmW05?iR%>οh8~e_|INW&d lJ`c ֶ>e:<AG=2sB u uؖl,1v[0xaj٣:" [^mmM ZpqXfy;̽ -CzͻvudO#˴`$9zފ%˦>w1EJueA@I֐Ri+@)Atn,JZ.-wysN|]a.u8.MNaʘ6Dlg_ [V8k)YtpʖK F|m믿N,:4/^^9IUE]]ցsC7mٶuWY<4XMG  Qb6PweXw]Ṟ?ŇG]i)e p2du1a@Tc 䒦i*oji -+ZKd|nc9-x scH @!PD!4 $2(U%4" g6d˺tA E9r- lEI*D`̙S р:șs.ER^/e:Bo} h@Uai( K!ckAap裀9#83j10) 3(BJ ,.NJr:jF}F\Gxݝ(|󍑎vU/ceNd PQDTahXDPl~\,?("9g:DAЪUr>AQ9y@N$\ P j@E̘!T$l~tz0޽XmwŶA܊/29 >IdԨ t{xr[_eq.Vxx|ܼxwUp8^,o~UXnK)m1v7Ô7Ӈ˗SI|Yx:LxDޘ=lZ.&`.6WZyBeTkMeVqx._$5URؒ'):,y^^x9݅Cr1p[l?5 F#<ⳌӲ Nёd$@ɿBnesȐ(3!%0hAu$gJo]u'>."__jec) Zs) @A,X@ :v%c95 I6zM= h7ڄFB{ܢ̏o1f}lz EE5 Ţ@40FT8XB?>zC.W˫C12wjE2 u!)L ̠ď [CE8m7E8xfa% ÜDԋo*7i"y̦4{`A&A#EP mTZ y"&ÌXDGQĜwviCnQLu,sqRop ɈBhxr Zr]!詗ȓ )+%$(`Pڄ*F0F8֡9ӌ63<b.)#KԴoI DK.뛍O?-zyhkgERg=QόfK !crN|]׫jhY|V>9҉w&Aʭ5ZqXpa,&u4E{rV1*A5 5֦0$ ڶVXs1eNQԭ[oץ$-\0<>r蔓nYYk*5**xjUUD +?6??@"G>QAT sFߕPAb>J`@IH|%sP `t=?GpP 0ǡ^nO+?a*޷Z&2DAQ-׏.t EQYNmC7٫m[WWW"@pnm”o\gyb6_O$2JrVSQV`,:α Y2 `Ҕk4d&2Θ,d\)X*פ\8jbA\>lj˅i^~ؽTV@Ԉ(a͠l@ , pg]-?R0ASQ3-P 8y.j>[6M&eҔ=`vj.lQ,KPD5E)d^\/N ߮_|]B6ZLva/ꊧ_`E7+gdC 1 R/kn Y] })ֵCɩllPTud"**h\Xr TL1RrƾhvT)v^yw٨iξ OS^_\) \ 8_"Hjq1,sI +Ű&TR:iNb=@ۻXJ.n/t.WP\pL zs \/1Sݘ&@WWY*lK`jy2biB\, u畊@ε88<h7E$9k|0|jUWԗ\&8 cu9 b۴agɪ3l*OCD,iҩk<=ӌ"ֺ X\"CߋsPrcL+Tr1Fvuh*|sްY O<G@σ@ HrjT2BTТr) c2HSDQ3.YY,!% 5 DbP!U-,E0X[2ޔ$\\]g ' T8:SLZ2uC@RR6Fr  DќY F)(@\,}9i<4ijo:F#89c-!p-[^3pjihK+\1R`U 813I݄%~L0DrI){]8'u$Xf*@( @#=w5̔ec. ˔Ldtp~,jߏ{M×ƽ hHP<ɲ`R˟^.w阦^ǬvEÐoAT̨h7K{,ld0!7> U6Sʪ~b" HDՑ6X)2:F'֫Ӣ,fc `F.22 ٺ\c{ֹHrnU?ABnCiL z沈:h.Z眛9C ((22輝%ςijj8m-B۞t;֜ Jj jgj!晟/|_4~sUX|^^ԾLIѢhԡ2gMⴟVцӔqj[%[/تqD~$8qU&TsIA\G x}8qq4J! ӘE^.8M({^\ >e!S:Ӱ4Tu,F5fra&M"HJF q>yOib<iy,k2@֢2keRk)wN.;!HWSc$y3ɻn7iގ:$TYc9Fkapl)fN\bйbJ]RODm>[2mww"+e.~j`;H8eQ X FTusbcx:A`uu/D lSKjkT')UdP`΀A1H*XQ$czvf^Ns!rZUu=qqzw|(4HyjkY@:G$EԠP-ECyݝp<ԾmmYϋu7k>1 , y2eߍacw!},e|x:KaayF~~ IDAT<ʓ5 scQȔLX4)ƹLߘ_ t,///'hu!`Hp"(`GBU",W[>pE4" (zVe@Kr4qJ%P.Esd@!S*`ڢ=s^r{oGܮzٴM.8y.1_nכժ$eD̩0[kҷ({y:KH\:>c!UQb"9;T4qd`uvA qTWAeWԲ"}WqbT("h)"ъaJeb& y\= [zcU+cER1C?&"2G5\Ek;cQɸPqsT9쬮=) i\-Рtġ P @@-';OzQ@%B@% U|L͚{ h/JYiI/ =*Yt8DRpX^˪\un;.N駟>v/}:S? 1ǟ|z=W/\\S9=>jY['_|?}unoU@G869Ĉ8ʓac@3Gt oa8?MQJI ʘb"ˤɒEI݇o"sX(R @~ @hri}X`}Ut'񾹹^t8vF4g~MAnSDGZP F yo132D*Hd<( EW!vQ4뚼V9N}OGQO\)ѫ;m:`2/i[ϻy;j)Uy?2WUyY8Tp|u5MEPрD P"B$`,!dk"-5G=K{r.P"%3 `{qZ7VNbmRJΪ^ NTAqyY OS,X xtck "ra.uљû lqlJ; H9SK̹H( )8gsD?~h%PBg? @ Pj@ 8lX#ƊC%=,!EԧdYZ:/ $ $T<1,x^U?mO_'ـɭĀĀj@8-NZ}\;?6^ޑt}}!>Xw\p[7vf바fj)#``7i<󄈩0OXSc"-몫*ߍМf3bvk#܊cfBve5aw,"T~*5HYP P~1!ehK16ݮ6?Rʘ1P" Tي{۰МS?Y8m2Z`l*?`ZX^bp2! Yu=|cLyER@IK6?+_FtCݖ%APdULy2c=ȢUB"2rz`|:lZc]cXi/Mf֊g2Wvu}5<<ȕ!ݪI9v}iLRX=< ~jZk+h=rq<2łBhi8Iv~|mLiX(E"]>FR|j?ko^lw1ZM|i;C|ƢBFJxk8hu\,Ea{m EP a&.e3,@I C\Q{DZ !Y6kb״vJa!)L. sXTzZS1Na-1e_bmBEKH,Zgq8J(8gLfl|o篯yMc~?]U۹<cB3c4F$qR^KLMzUܻ\t`$T$&kiRMjf_<R/o!G8=gOxfc83{{ 25n*:*d Vy2it<̧HJC>< +8Ms)}Yu[uM PYU !J&|*1#UOsřAX@iT֨Yِ(AT2kE\*& gA-JRJAza%pn1X\;'#NB))'}* dV-#2!#h)ƹbwh 1%(V]_ՍmİY/6E!$ըtz )>ˋ4(eFN"ݔ@\cL]S3@ٰHgzY;g-qx0>8[+C8?^,ViO?{l}rzlhHe:KTJ|NfsQ(Ojs)4gɉwK_-l.ia%RaPW3> i!qBI!`3T3B5 Ԟ7LG|} -YP(gea>=P)vf$@B@D^+E >1}_x|WY~V{I/6x7ucᛯŲټ||w_<|?>O>d)ưNSR4"ꭝ)En{[iY.|8L?|i2SlE!2W]WTf҂ mq' |еQTWMbo>8D EU= hBCX.[<&J-\bXZrſMZ +_**Väl#\^|yaܚTـdS4f fȋˆOa<8XTV}ݻq~QE/$)g21)h2^>v>SZr0KƷ*&/_i\lzY~y!$H9N4yd,A!Мnwv<3#RIѷMIfc?OaL@"/oxzg_>_N?͡o&s_.Wq{=kNB<܉1ZAy@?j`k 4]6ES=naӋn̡~\[17'pJ/nR2|q0c`9:Ӗzr蚮&ȄZSzΘ&zgt 9Jn~\x|\V}dR Hb橔biDl49˾-RPTaE:RH)PҳGS|P)b.)UU7jh>>vr8HyLU|ӰLaԱaվΦkky}].֛˺on_\{!lcI.]S[_5Iq:.7YT~Ue\14ϋ~1ӻﯯq^شv:CEJ(͋K")LrT[VXnև!Mwc1Ppz1KJmm>2b*A:bZ~r>f$s^`֋7wv{][\% "=U Hl;J0~=7 &8NHw]uHE)dIǸF2sHaVP[]e|Y_wce=*H\1[$IE 0 *HƢ\beB)eof{Y4mϟ+.sgsJԢu5ZAI!xBLm*>Mi sW8yy;땪a:y\_;@Sw'7o1aeElUTQ(Y qZl10q]-+{ۏO_ >="+/ (a E9A׾gǀ0%\bQBƙTy()s]@Yq E ,*X)`{T([U *>)1 2i<|ܪT?̵` „I{2,2O_3jsz=?wO})C>e;wCȁ!'0><;=t K88cK)CJO?qekp>>Sqo5 X˥E!T[O!~G0gVC.i[,Q,i{ YD0"  H"SP@Oxt__?&FLdǟpcIQB##hG??J}73mfN /\ئsRw>%UP(IKfOӗO)'[ f+Cɩ8MuCq !>@ouΧ}v .;~겵lSy<%hV0c9rHKFL _=k [^)sJJ: !7L4I9'ZФ Dl U5HԂhA4/+~N#ד' ݴ-Vz Q˾o60|ׯ?lܼjwwLiAsVԮC Y5JȐMl[qUSAT1 sNZNQJ٣aN+[_-û}YȾk-ief1y^?պun]!W7xWH)4dϦp19@Xkl(Ѧ7[Xj=Ng֒59Ҝ픷wz0/[=VQͪU>wbm~AúSVJ1p^1uGIPJ1Y08<gtݟf Nyg.[d)fFkle*%fͦ) dM%PvV @)ڕ䬰lguUѵmĘTBJV1D 6gJ1Qђbs.r1k!L"qG\Y } ޞr[_ʶϾp7uvyy||EA6bU( ?"_B Lqtu4}ډq5Kȡ@! )Q6x8.R%,j1m[\7_.ڣ#R\/$Ac0ܜh<)jbE?\ZP#]VkqsXliEH~?LUYTLEd}J4ήjra62q 䉝dIųgnOf\`b:CΎ,ClhL(=ZƸSC2hID1} 1ScHĖ>{ Tժ}K vQ/>~]ISK jښ_1l0=#̴1ơ r {̆` FQ)U8ViԚ/0wo .z*,!~omL^ͅ UDEPE ނ\D)Ϫxn 0r6\!Wdh, ZՕvNaW~4vۭ/p<.Zh) E*)IаᢒE fDBBQ,IDHH9gP!ͨ@H lrK,$Ts0P(0 7U+sքy\p\5z|4MJBO0Nnn7g?~iq.a#QYW򦹸qHYK)Jdi:c-AAP zw !1,`ɢ}u;Q#߉/`hd_ii1ohҔRuv>1QHRD<_H\TJaJPHhA2<)77q^ s?f PBPϤ1xJST d'.5E9Mm"X[}G%w|ݝʙPokCۚxoS3ZQ8bIᠨa^/~]}61__z?b l+LjWǘ?ܥ2Eqݷ' 7YvnLCȄ E!KoLawuÌVU j" 3>m]WE |.N(QS%k([ PH UR]X**heC% )q\7:X"d4qD MX&Wi2屿< r`5K3=R}QgkyU@3T@8[7ꫜL(3y7U٪cd C)(@Rػ<ƄXd7e**U"HPf,l2ħT" )*)";[/jɊudV}Ǚ BvpRʢq8f\5uMl;9UDccH)DhQdQRx9@LW94Dge:̮~)gܤ&*E J"(*"*.@U."XCb U0 4`VRe  XA**O Ȋxfu BHY,1 RT UD<4n;R̒n;SRHĆ\Oa"$e*K9hђJJ$a9i;CY}Sy=~ /mBq:i 0@HӐn*`B2"!(1ʹCR4**}W㓧`$} `FDQߖV훯9?\nϷ)V s#F2`Y=LO*h$d GMbõ3Bh]cERJa6$ |,4hjr5gwcPbh_Lض_8۷Zrk/?G"Mc[UiJ qo}onitƾ{L /oL:|nvqYptO`ճaxں Q$"@( %w-(]\o?32zgo]ۯo?)__XMw.MnH"A8J+f]͘`L!Crbqaa]$i $S 7u4UT3UhY (IyJe̮B)#Cxt{'tet]s%D"GF]_6HPDVmeM˜A41za9NsHah43$Dlݲ*DQeEPhb dpXlja-{k;uB~NjQZҧ/:3yng91bG`%LI0sՈ3%Mniz{w7LJ 2ūW(q*(8P8}M F躱AS.P)+y>lPe%OlkC͜SH’1PP f!,Y%EB[ObV.G%ɓٚ6몪ioC7|؞ TTbWE1Q$,./ߢ֍rR+N~ESkpú}*U8cEO,[D'%@)B ǐJMmL&%T\1[U[ÆI%o71'T%H C|F ALަHeS-ݐ-m2HnNouPc<ɚضKrv*M;wӜ s{d\M} U&(q*l0)ur񔕑ehlaALtX__Z%/(['RZ8?8םk#`m;=4 (ÄB(M֫"'6KE\.6Nba<]|K1eߺE{S`St6^,?tS\{ɪI 3fwz80 *ZDQJ j)(31e 1KAlŒDU-֫SX\nvN"A|+Wa2Ĝ>U5NcZ5m[϶$bq rʥAKg })% l 1UX*. F3)DI(L,L (*96FXՂB\""bJf$0dYwJ J HbMUVҧd-Y!@h3ka#b0O,g#fg0UDx:C_O0Nt7)wjP 8&g(!@[pTᲕU+{]ݛ?dYeK%|jƷXX S?~mpU/`RJ , I@֪8uu]|u_e)<P 77K]?o:,f1f'MwQ9xbrڒes*B=FS4uīp !}1HeYUO0"^9i֭9G  "Uug4) L ǹ<}WM\.ǟ|~/%{^?1a7/^qn{D_ۺ]c."69m0kq0oraw5^%'?nko67}dbgi8 )hܵ-ydvmsq]/ONazl͒Z߸3UUWfIQmd eҔnvk8cN{ƵVDbg|a0v^$27"VT-!Cƪͩ TqQn{NҒ'LG.L6YzwnQ~zw.b|=fU?[ThYEURQĩ:0EKL3D # ms>\cYl_, ?-? E y_zcNi~nǿr>}@h&x8ƫ.0ںn8y8iYWURΒ H̆L@4w4}]׀TS2gO6 +g5v$Y]t˪jkwO\?竀zXJA^N}ݯ~nqi1ٞ@j1@sl8_g;f@QCpaZIg& \|WҖz8c7:R.ߣ\|g*:Up S{g<4:Nd)4X Ct5!9eTQD$TyPx>Y[j=ha_e3z<׿lŧ]ׯ^__Q?Z̡^Oq?ZTp An8u?4eEp{:Yu=jՆ,CS¦8%tlQuyE[i]/R yN`\ܟ:H. G2iu$eCK"ӪY L&n GǫZxHtf_^\|xMuT|32޾m7mL"c W|?yE^f u[4]'dfG$vRLŻ9Ю<` IDAT+Zz7춧~ >"ҡe1P+W˪j<B6AF >=@-]]g$#fNIȜ n q9[h1a_WY,I8%hL9 1(dӢ)%8cR{xvz|X.8@Ι! n#2Sb(d䬬F& 0fF 3STAER@1ೡG""R&aV<3< bVvB R dyC0"U ؓ-(x,1$`V8Tgu5uL wӘLqnrZ,* M+ǁt rJŠ4Sdբ~Qt<}~doڰ߁]/-rnJT#~wߞ,VgeDJ!0e]jYs0K, W_^{O="dxOM׋j-HM4\l(Hr.ɵU2Cvh6q, R-Mpaizx8r8{R0kQUŜIW £̓c0v ٲZUvQ)" h P19ve9}7Ʋ^=WEYx5K[.nW={@ `DQ`bIrUWWח"cYr0Cwݳ˦~ȀXg Ϗ4x3H,2)zEgٙ1(yEf04f`()"&6%$H1c3 w*x  A}fj(9eٱcb1y 3>)`,+ m jSs]9w$y2 P4O~l[bT\' ~ZB\ :3EQ>lYwr4E9Kږm٬ 1Oq>N7b'?2j*K9d ]hz$jz$m;"jg닋ΑGjI,{/-vN#v g^O硫9`%ʒ֎4%5a ./i/9-T"BȦ"MҋMtWlKǦ9`JLUaY%-6-)97ɜ++޼,?Z5f=zSX!$}MtlӷyތmIJ|O|]W-̎ f"UP3A4s 3`@ol0u @A2٣LTȚebʠIQDT/oVuU AHEr"$GhftA "0qQRr|S]+oǿ|nG@K}j2(~8I/ڊCI\ T_Xf)r2g6tє7zΒt'hOק1I az0,dp˾5Of;~j/n~cyE/ [>p!Xj K}[V/avi1MxyMҗ, %1ߥ_Uk `^@r464 30tH2<'-A Ͽ6*0V]@z=Íέfd)Ь h`j"gi&wa䋟97b*u8>Co@J8-|}s'?F0Ŷ?x^~,|8=H\xh FzQ:A(@b$+'٫ҧ)W&OAY 39Tĺa$rIV~wgc/sf_2mѝN}wT+em* *f7bY릪dr8;ِ)Mn~g^eYhY!DDBYYYahg9T8WD΀#pd u~v~b?O@4CBB$D콢()cv,X:G2*zv%)*3̖fO & <2f2%U/x`d@ 6FfP@L5r0Y5C.PTMt&9DFӔ "JDOi=vY\m͇ÄmYj%'&dv}u}ISYq0$}v]Y=_9ȇ8.1i@R@EBjLX~LO_ϸZ'ɏM gSل|:>|޵0ۋl*UV}yw۽/?82%Α t8LJD)w|~>b?$:dY',ͫ.{Eamk@'9I8y? kC> Pmt4q-a˦D0r49jvyn~nuY]^\DqZ-0cUnhrs>~zMC]TRXV]&b_מ}2@Y yy5|qRW䙍S(QYէϗk5X!9j4Pǘb90n} |&j/,)вU-|nY,/?Kf,?7Km@ cvd|;.I3ʿx38eŨN+|(s?ԗ͗/ v5nuQ1}zwx*-O2M?YM[}*@5ewm4M>佝X4 ITSҡviq (f0C`.p(]% i0ⲩ<Ӈ뷃AMCLlGǺYSVC\߽˓9Fe5msW|ȆPt1\,~bvF^M0˺L(Q<„&OۻEXuJ'YH$s~[0DɀPrTTUbQKИnڦgwQ}ۏwwM]^n~fmqL?]yʑc*hifX/ D`*) Jm|<]yV;:Ϡ& O} 65~}Li~w?B ßL= "cC>* +R X7UX4zt:2[ƬbՀS3,כBrJe nx@ ̠ @TEra8N6%14$8xu,ESq_˒E!%U V4CQ#PT4Q7PʰY]V3 А4' ҽNWh9ʹ }u_xW2昼#u38uYVcV9d_fL4k~]\@Ye}Dtw{L&&5O67óȠv!~afbf ySG(i>ܡKdeBF :9#W1Wfc뫺\&Eč '_sq/ʏ@y&OPxvEi\%\d2{uJsNGUXFR^ 3#! (ٷ+|"Ȁ2e<0+  0yC``P@PTa~ҝl #̢11+:LɌyJ1TH hΒH Y56tCc5_2Q򔳁9?v0D9dh8 }JoNq߼^, ߸yJ 1Ū-k]ǻ ˕wC*=|K,,b9u|)0}w?~H]4Gd ϛz= ~+/_$r=!&J' ׵MX|+)>~bGvMɎtxog]fQlCw:.u@DPD=,G1f9pMLkj;]OϿe"K4եs}(ʩ8)91;&IYݨCC?m_. fj.BJ L. (P6hX>Nm=T[-+GJ/~E?섗r]T@~:ia8 xyAz5_52}/[|FV}lԾ)BJP6.Ab0 82eMNR R!\MaJ2Tוs#S%gX.뫫Ų1K˫Czb\ش+')\bb B(@ ]@eB=g r%N)(%vTqH A! 94TcC VWpX_qg 9'%-(yQp[nl<XI|1 g S"ag vF)"͈(@FKhHaD!2"*(S!DB؈O,mw'̥MҴde1񌺥%+3IzΉ?,YcpÀP"~* "(gdvqob Jdʬ@џp!gHH#$AX/_Ldh`|< ¥}"9gH!B4= oO1Gd4rH9ϸ\|sеcab^)tӝb4<ڪW[wVBv??~ʩ)}*7.)05W<~Us 'u7鿺h{txS.?wYʋ.W{Z/ !C N$Ѧm! \o/kgΰGFn4(~JWjtG>p)ELWtl͓*4N77/noOղƶ'6bR7(*w>`Lm 쇸p)6׳nCSV73j)LLKq>_4D(j=Ъ_<T׳P{x@WbDZUi^ iVWq9z]|_ 0иq>`āg!=릜,پG2z b6x>F eDe]/qfq`?{Yз6PuoOw~Rtx>C鋺|1/=v5!0DKu՛ה;^/v׫\~hOSv`X)wŔdalpx 6W٘”SBU˶ZΕ'4R?=w3T?ˣpgorY"g/V~=k2hP$YU5,(X2ɐN p~3 7׎);$ Is#pu&Us՟\!-#ОyQJކ/qHEnvbDv(bEKF?MCdʠU~1c|||ِN'C? ܵ'pۧߍa"7Ds'`ʁ,#n{'m:u8Uj7+_Td`Nl^gM>ň0ŶmW Yoe^0M8 wXbԏAePzQ%x`fh1'Ip>yv859v_PTW;LɁK"D hP,e !&RC͑ 㰮C8NCםekjj1MhIL%”Øfc01䂹2eҕ:fCGΓ `F!Yff{.,|o *̦ Ȑ̽dCyGU$bwy0BlD$"j@' SP@ ".ZT$CS4C!FlDd@CPHs@"Ɂ]RH hDL(9M3p~9s)@յtX9rtmɍⲁXT~;}g^?wfNkSUrJb$4Bt&fc Џ/Bd.?~`9o W'տjû7/~ﱮ+[}`Ų A tk;MlLZ(]Ez87Ulzr_m٧׮|RP-AUOuZ*ESf]mVMQ1*3}'fuCC; kfpdF0$ѕڬc /9!@?fn؝$v([Z6<}/g G _O}"ɐA)x(*WM0'9Bץ"IJ+crqq|RĜ<)RQ"*V/wE_k~= ɳ%]9Btݤd4uFB-Z?ʨ1N~;rE&G.) G (Qdls~LҼ];(s}gR:ZF~ZW Yͱ;>y=5>ց{f[I>M{%,m+K{v):4ʂ r”Bq9P^ &ĄّMYޗLCs<FNU~{̣T{Sp%d |Z&\M2M>4J`u5_6c1#A/>&P(%cm<;eϖƩ]֬\&(!V3H,˻v p>+gnp71IKyBMI\ ?Lm> 3#Wsg)u^2ɓw><>,nn5^w_FFUߎHYf$A@i&&e~Dujp<"6t8%S˫uSֵXpPٗrCTE pF '(HY GK^KyvfU}N^Gc(޷I(PfriU,[>paJN)$d&@6#34`dP0* P9cTACUR ]8.B$$ $JDLF U"QUSb%' Hŀ39&ES堊f D&AMAYM@h]R rZ:0l"2$f\伆(1g BǜlyQ|(1&ɑWm+)t_eyJNɇbw8ýfsϖ$@T4NY3gNxq{]ӏ /a}὇=U-_ y[U7?~ C[7N aV0w'u푮1)Ǒ W9ڕӓWZFD   󋬌2PPPN hS4Iks=Od>)@?T;2\?^=%g౪ÕA-,)IYULyl{!J4voX׋O歷<:Ƒ)C6f͛apv{<Tq0+"}.3Ӏrf> C0^' 32*:GHs&rG"Uc"p/F)(ˉy=0?>슜x< JRw6Nٺq;E즨SgVP93oi_PϯQSꔐ =.+0J2G2@@tlV0!dSsޫ(i̇LĈ94u"!ţ5)q vb|%DE.susx^W ~ys"KdL$纮˷7iᡕ.1LJ&p.[d+ϧeqc_\Cھۿy76igkfMLXA 䢨 _ogA?Y?k0c(xNUcXUg!Lc|}fSrL=k7b0|x8$FhTUvY,h,4:f3)FeD`h4ңWZBplCzy4TecvJV H"`NDU=XWoVds*d,NΏ€0T!ah(@AQfeDu ^  L@X/bjdFdDhvYN Y*"! d$Ɔ8@`SX A!dFؔP& Ԍ2+f%AH fjjC*sӋۛ!EhVE!MJƛbY4KhQ g6nofA zsx<ԋY).1e"41K*I@w'>z_u Fh7?sާCw}oO/gw~;k?^csꪫ,t a9[|l)\4,"gQM͐HCKBG]`li\ouxV86MۻEU]}fr@:Niu}>jmʺ)_-$91nû;nߞ>4 ?(d UU>MLы%2 Z)4!xy1vi<<1G! &P6`^-E$…)O6W~ C/Ƿz",t*ɕ P$|3ҿm8$Q#(o4ddPh)`͞0i|xlVM$bAJ,:@JڪbRbU5U3M0p,,S|~S7__|P%#Uq4B whL %:¬.".On^s,rRf5s@D|ww۲ӡ9kiŜc3`ѦPC.-Vj%MCT+uƢWW\?y=sp5UC"@r! (&`=(yAGet~j~S)x|‚# (s+5eMxHpjfr*QRLqy>ޝ#qьE^o֣9RicԶV%(FrqPBXNJ8MI){(V4'8hr> 'P#8/nEX T.t6yTg0`ȥL"/?{vUahS?}xcV|eM'lnBya?Y Gه?&)y:zõuv%MU=!R蒈1/]0 X΄[|8-MqL`QƞdQ(h̘s6SK='4f1BqQ8D Etc4ٱHb.3dBI)z34!BY Q ȐM#03d?$vyqb&b ~r)&U03cd$b_0egB b`h@A~_C`;fj"& ¤h!S0Sp`]jxU})\9%ԶolJM-R >L}̞eZϫzG)+皛+w!dž"<)<'hM ;W)#K{!9 SUAEU EeFp:8?Οc45D50a2ܧmj[,>/:\b`w~SK:E5}3wvۢ_5j˂._ϯ{y\Uǫ% "rx^=mea#X?q0ןb@Fdz5ϋi ̗Y9wW'״jË9secC*o s=_}"NY-i8(7zy=7塪 5a8S3 .)Mϟ?ݗ_EooŦnnպ3qS(8Vۧ|Ρp-H5/ y8.f7X bLtU]ciRΗ [ɹ(|{}5~xۥ; g8k_e)ӧV|noZ{,kJD.)֘k_lRC32Y%RPœ!RH숱NnfqN% #1P#ݻv xWv*ޱZɖͬSr.PDKIq(ʲ~]> !v/B.cn<KN.AJϧqϢtF3!Ѐgʼn,X" t(.bGJ( Aա*)yuR0SiJ}570ĩN[,jqHܹ%arJZl Fƙ(c<>춊TW<6XrC&=~jrl?'4gV*"* @4whk IDAT*W1aS&4a3.$ TU.*N8&"w }G 4CAҧ2uY('L#@LрQIJARuAPsj+93uf\5I901d5p WSB`"FAlxsu)2 {,_MKD 1"!0!!(]. . ``H1   fDEzĂQ9(Y*d1103PΆ@ x):6RSj.m/Qn6vpܽ}W,|U-<OCd,9бz} eCB~u^<]UtQ=K]ݷ/FDqwjRH8~JKB|E@QN\w+EG 8j0YZJoya<{HJr6O4Ƃ0@yƼ/1ٹ;s*?@p߶ϟgM4N])r;g*%g6"wd#`:ӡnau󼬖QP<ƀLWsM(gBߍbM }UaX`GUϜS} w{OOvR|;g9 {fZ}:ݘxY5 %*AF:2BNy˟<+smJaB/ogկ]/6\ ~Ycw>(L~ S]9PϗLn=W+,L3G)x_5)$OYJvjV Q@Uo沘 }T)E$H.xW>w]>%"r MUx>?sp~c])4-HEDrvqv5TL'$0& SN2QrbP,3 `M̚UnftZ-*_WǮ?O]4M-;X#a69l7b LuSv#MEu=N-OWXwX4n oZVmާ)=$Z\<;Q<]n_~vd(0C4KE޽B뫍M=J4)A(#S7< :B,=`a4`*?Myx9 z:Ųwm )fEܵb3H,ȁl"D`@䈝)Or9_U?SA=SB=92h>c` {1[F2a>kHZ |4LБ2Tp$J D lI,$1@lQrb1 ޙ 84UtF2<$d9]lfCVdq2 G^`HգJcN;"VC$f"͡Y&cݼTT $qeLќ 1MY<(es,8㋛nfoVy],r^e`ISSEZ.䷿bEYO檢E]Jr߼zȒR o^ og/<@P"lf.r$$DF(,?.?Ο5GXԞdj?F FCW?iS|sGJ~auW6S5O?zVG^m>}٫ݫz [Ҁ7n?~7j7}D)|E}B{.j@eC6qO \ 3D@\R䵍_ݓYJxqonxҍlq}: c7aԔV7 `0cl!qΕ4q>YmNX7p#i26 NmVO6_{@}QOQ0 g)q}u8?e9d92e@EקiUJ •"NqBuߵ*R5 bƮ]Y?/O?*Rt &PGʗWr ;_oo]pJXIJ5.Qmb-fSz띵]@b\bX!!ϮY^0DW/} 1E Ɯܮy2C?fQ0* tʻ0/yhf|}DL v'\z~~ӧO̘]Y$'ɓjdGc;%s?f\Ĕ>Fj`qpVf䡟~qƱ8x!4j9۬fl4>ޓ+ƻ ɍ5ex"L/Y$rdԃiȎ 3If9q5YS 6/у,B eG}G ;8ZP("9Qtrv )FbX_- ۶9O<]>(JDvP PD@rTB#0"`B o^u}k8CW50Xa IQ!Yb&N !OȉYb}OBΈ @/DĄ1*];9ۘ0Ĝͻ ̘%'bDb 2i; .fjh`YQСcJx^ՅwI"\(?S3KE vs̕,"95$`v K" ӓfg|᳛!^AD31 aVb\qm;[>뒚]wª}v g7'O֛YU+gєM/E@U53I2 ^.H%G Џ/l TA`N}jaHVQlʻO1yݱI^^6v)^fe>w7݋_Jc?慄9|<2W\p6CshC3P@BKYipbD,֛U < ܍^~wEviyƭ~_qIS Kg X:]_sb&_MAu9 |]}CMb6yp8gRnBOz=14R>Z:NI(t/~zVO cۛ m{7?ygU7|N|z7EM!B8 pɸβI4}x zf!̳ؠ@0̆| 9\@pJ@ 0#> }pb<>͓·w^V,=?˙z1K ! ,2~NWaV ?|GWޑ)2^E6Յ+n`+b6Z}ozV]~YVexj c(`=~f˒;0\lC$CHF+Zo@P ͈d7Y//5眈"_HnEnH{s}PF \Y|qW%Œ:qr yz|UwST bq6b$gC),8䬂.:侼}xXmW,K.ӡ ]tޱo=-]=L1yzQEEL>&13#sBbV@ޱy6&u(~GdK* /ܮ3U5UR5A Nb?kpzoۚ`ͫ7x"lzgT%$V߾_~3[rs ?K#M?D)^Cm{F֤JW kWӟ~|CgT!_nc>ZY_Ng^~̪o_Yu6Ge+Y%: }:G_ݿ(htX,ThxYܢkWk>Oy<*`ZGb0xzڎcA縪G#{4ofg7+rO߇?)g97'I)27j6pNyLn? yʇ#M[!S7oU DcJiv\q]Ӫ&t] OawIL{G#)hBb&+<'m)$:=N:8SY;rA9z}|wwx<ϯ͸P)8X>9"d4MLUU7h=jFnj2aZt|fwUk FWb8+pjW\h{C*E' U=LnO{TlXi?fy졺y돟]]nC ys٢aI"BΆ):qy_ޜNu b;int] o)*h̴ 6,hqUO,SNSPlƁ'~JaM*ucpTէh=m؏^-ϠrC<7U\|VTh/yXTAOc.eT =J"yB*b^*Z,oNtWmռL0)e1#4T\Y{U4+Z6)8_eOjoVe<3<g5xty*?ᢃG*J0xG\ynG"fzc/2iSg|lXH@DpWGʈH9jv}ԡ@7w^o]6lǓwi*'+g r pfN" !%;>2!PD =9 'Ow IDATnvn}7O<{ [^߾A_ܬ &:ެwj0f-2)YXg޿{{_ܼ?BU4]8{2LE|uW ȑMR@JHy壯jSŬ\&H  A$1 e9&ɬﻦi<~46_3&-O]a޼[=ٕQ-E BQV 3 jC3ޣKNNgk菃|XA9ֆUh P0'`މ!!˺嫫k}:z,I l\UXU2)M.)q m,euUNq, <)CEsd&y\W70*D?e9we S9\c*>gR8 s9ۧ/:vasSn9bXq,S@J"ASA=`rn Px(=fܹ`* kTe FGdn[2 bFL lfjYUNLC2-)x%c)7M}QSQ0IR1;Ӭ#鱫x,i *Lva(UtFX7asz _>7NpZx,e쇷I]^6!Tm+iɨ6[7͹V(S)"cIA%RKrYWQ2!0@02FcQM\`Lٸ\XЌ Ș4e!*Q&.DFF(0:Q`9aw* ]rk :2 0# cLpqgg~)1Եc(CޞOSĺs_D=s]U]ۊ ^T8yJw1#Q14%SR0+3$d4c$pQPq;y17H)*.*(]n99P(1&eJF;~Wߜو~y;LS[grHMFbRf1ǧǧ|]5o7R!̀^X*i$<yO7ssϭyW\|@mHt,]μ&gդ\x|r|1cL=M_?n0EY^ub uufM͆Ӵe,wPXrbS OrAMWpme,9 91 VZ J$z<CN٘E,$Lia =̜ CĆNz{xiv~QUI5IqimQ"fɊaǻwoQ‹U5atgq?~#4EӴXyMlGMsEhm_]FFsDJ\d^箖R"FfY]qC3lj_@7E+ytYFKɊ1C[WgzёfgQG2Ĥ ɇo4DJ*#7W{_u^4A*BFA LJOf6Ơʊa6솬=U~8'R4lt֒1}:m#n?WmӠ]ey"SptaJbd \CZ.e CYBɤfdĂ^Ջy3>y?ڨjNcm]]Dj%⃢CdĊKTAq`H@hpx/]?ppQHz$&B>F;% #{ >Xctj"Ԅ*Hw[^,W iKT}]gYb HgBe<"S9+]z ł@2pB`S)&t=1hKzc"?5P3QQ8s]Ôr2T,żŬϓ|ыxTzRcnyſλ/8~-yۜ?Clo/>"/2&δp9Rm=︄VŋTAͱTŊ*cӔ(r/`2Oź!4#NE#J=Pce30Dx8lkcɩCƋ \NLjU}||.(qxGSU?M㽦=@݉)ar.u"v{jmY?r̎CqD`ZB%j[1!3BRI8WIj|i(g"s&T5DO՟0UJ8 cFb߾}3!>MϠZy< 6mE=ZH)yy];Bh&F"Ҳ>xBd1uCOiG,4PTc~?Ղ#/PJN& %j~_(χ,Ĝ}FFˈX/V#@q4Vϼ#2^>HιerN>M9F\-H,Yr!T-ŇN7^R2P" ]=XVX뾲UdƮu 4mE}wHEO}.522`qT3)1jXszn>y>&7߼:DQIdTpȆ)`#4MUIXZʇVe!9ȘF<8nc/4E )(cF/a[q//`ʹs_R[vuNy*\%UPf=^t4k/ 括'¦jO+5V&:ox$L~7>>=~M;'d)J,\Z4)j"YF-DM"8AT)1hFB]Jȡa@Cp9{N4qDBip(@$ӈjjz+FrDqFW\ ( j6+Z@7aFD9+(ML T/. #c-v&MD_EOH.?(A4$ !1dLKi)Cα$YȍЃ>yUE,XWs < _ 1(V" Bpl]վ5}Yݬ] CYGz|_\͜t'i1h'\ !MU"6M!x}_~|xp/~r_GhX/cw^×=O=}s7a ,U~cUeXdSp >CȋE" hE9Kj[VߜneC| sIJ?5#sws-6OT4S4ceRDCPED@mzSoV][lT.4%lt4yTĤ e *74ca@oFr˓4ï/n?na8ADjb5ogc?9w[G98`Cv>&$W9ȶ?lQ.)g}~'5ޗM )8(! Аk8^vq@ƔR[OnӰ?11{n~-PݯzCTu8mx>%` c*v{♚;25G\ܟ40YYQ(Sw$ߜ' {z-ogW Y ^_]-` =AQ@r iTE<cE,I", z> s.~ן \̢Yx =X҂ǏKʓ/ sB-QU(7.߭o1Lc+ԟ4[,D6S?-Ϧ8PzP) 7Z,Sɪz8W׀bftS ZԜwuոKQɠ'nPW<[DtZL (*X+7ykg2jAƂȀ|y(Yf/DUSbX@Ycތ a%$P4j 8䅼:PU"Z\Dfa*z|lbյt 9UApm]6wΤhiRNDL$H 5fH}A$aD0rz~̇by^>Wi>:n=3h$eCE.LTEǠ'D1˅ >8Aӏ\>=^/M3uy#Xe)lYd{OoO=<}Yw;9߬4N=;7LOO>_BY&av %:DSƬ6^/E?()~40#XvAWcQWa׫tai)ꟗ5U[-ɦ҄us>6ֵyr\𱭺ZVخKSpAۛ7/~X-_q;wiq7ǃu1i-L j ^a՛S謃騨ԸBeHgV1Zu9OzHՂ41w Κaw8&sBn䤫Tlz0!U ?Z‹B3SBcigʿQyGy~p]-~(LŧYV0[$myȬeՒrR8?aT}:-6Td&Nŝl毻~ۛ70!-gn6.\0B:%ghflz|c#a"2f&G1 [r6X[UňiP $H DN!B\a⤐(Q6/ 4EKV/:d=3`U1BeP)i۸ZgH&yd4ǔS2S3 4U$Md8#1C ,+ y{B4AZ`:VuP4o}m`?Z- 9λI$k?Hޏwo^a \% tȕX\j' Uضn+m Vx*Ӻ󀑴H> ~=m p3UU0f Cʯ7SX9*ɉB@@f$ηd}#mr1XV^uT-ʨ͉kHuXż|ٟg˚mxϮ`"]C )_Wy$iZARst:Rͮp1Ϯ,Vb7Dž[=H~>n6YfvruUj?JAJ>wm^r+b}ts3ob&4G:}?jyt^UfuLaKrHt ?/fX&B @ـ hꈚ޴ooVX/hts-pˈ"/:{ږbU5 +pIMR,um_ ~1`؀q ] Hv^aƑOpqGzXO cTFݫgT@A"XnOPm,xS?'ci9̧ig@)65yǒAa8ߟiޞ={`֤ |A{0~|XVhQe0ÐRΓ'B)I*tCJtAt~sm͜sLS_dJeRT{$HzS 4q:,`HnF4I+S,ݾ?>lںU2$ZɄĈ,PcEn< pAܬJ ,&-&ncg)u0]iFVp}Ϸ^=QӑM ԏT)! ֛/]Gǃ#(i$k%'-k0[ IDATBy8eƂK.?p;6a:X?X`NeHݘ(EP@ɖБ  BBVsD{O\eҀ[AK[c4Cgl5ko/w;*j[ 둔11RA|8a['4nggM1AWTrTq Y2__z~%veϢQR()s)Pk"9VeUn.S3آ(Ġ +dD3hAQETfQ<,$e6lU SV( 脆!Kh^B4Y$昩tcȘXRLXsQJ ! DDDJiADHa0J;c2? DD%[ K| ( <8rJi4V(fzĚ?|^v̜1>e?9sºmM]@ԟ>>>Nq΁1oǘux)TD "HD%B)4Xom]?OJOs!Vtms J?i?458(5fUJO8&(QO{ڮ[₩X ,$H D:VqE@OtdxRS3ӈ@P)p$9$Ry.ە? ֕ k={\/^S||K]z2v\=]4ofR݇uM,p(B)SϿI, Y n:~vմ͞y @V)mRI*\BRV`8;tk󕵃V Iz<[xx9}9Dah[JHޑ u(%@ ʌܴZ[Ym1%AE\ <ӯ1D82ej S13]4`(pHKlܡGA \U"$~ {ł!T9ǤI)=̂nB&P@ c!==-+a<]- KA"(3&( FT RJfa]*A΀:TNse{xBx㴶x ϭ+1P^- ?qZ4Ōr$341vE/AY9Hϟ_f5;2Y)iNR i rFa1 CzSoY#:ω#! 0S. 3@C`'(@d`$2V(Sz 1BF%L("9Ɯ 9V!ddAH!0E HJ)"̌ .!E g) j#rIubC JւEs??6JTSPi\pDiƐD~B:ΠX58fZ_Uvސb`9X4 YV0 1L(gi(+U3iw|֙ riR<4kUx| 39 ,F֤Ӥ?Ο\(,(Ir ^ʨUeIhK\׺ҝ>~^}/QM]]uUӞҬt;޽ZTŗ۽?W.1 σbš6~>T~ZWq˶n}X ch|)Ɯ"s1R 0]&ȇS.,$Ief]?}|z=ji4g6qμ ]]6MAm*=կ` XklwzB E6n85~EcOe+g*q1CXϫ]];{=;&w{kPK쏊5qgV":Ũ} 6exWշǛ}ݛZ<ގSчr/w?|w6Rr0Cf *SJ1!k@bUQ}Nj7V/tySi%W:ۭ IH5KCX%Snoۣi׻jW0Pm2iP@l!r1A .V@ (y](@UgkUpKh1~V$ E8 _؅a c'nM<@)Q9!dUY+(9OWԭߦ|6(DΛ4a!F01YKZBDsmm;8< HAAF)xeOJ@R(C,P00 S4(X2c)PrILsa3><9Oz?9zPJ1g4R!EXH)RHĂPTHyjI.B7&e-*}s'WRB%~8ͅ(2St&]u~+3ΙA XmN&`,7YͥOc( ݷ>ߪVrm>wU_^6 eCǠeDA4) D1(\,'U.8z$QJ;"hrZ >OSz3.~a?bÉyXb<]og?j̵ޓWU]>;ZU |q6_oE5_uNMqsz}7StKk_GSA/Q=|;vN}w{~-F@6b&$TJ%E@̈8ʨh9Tќsʒ3}[nuԭQ?۶Хjg5Wg7jɠ5`ԩI@9,x0vb" 6tς39DdƜQ4 χ&0D5#q@UBBòZH`yMFHJΏM™cԾ|UTSTps#&|jUl8Bn! wݍ!]mzIX[5%J]hgk(&jn7b&n|sʿf\nFKݜ<1hJ!#}I 9%KUWWfے+#okk!p:]sl_I<\mA+Y6uc] P%ц` dTϺ5\rT>% 3{]jRÇc,QAmȯf_O+ Eߗ,9"Rұ -ZTu)nZԠ5`O*4%#bTFmVGX^ObXx8_}na9R?_VT87_xcAYd )Xkj DZBxi$-"X‹^oS{V{`JSTr̊3^l盏ou}NU*#cUs =%aI7 kT!T^WDZ,SJuc+p9 RJ1VR3k=0C)Z᪩ Ѭ l61O7%.   8hKFͨh?ç $&?mو#@΂, Qk(̌O7OD"0 3|4 ef|Rr<#Xo@D# )E4hSR&B.VƺVZęE@'m[vx<[%MqiHԏ1q1f3GԅXhY`H)WޝΦ/ p=9䘌O%kf`Nq"R xa͇Ū43(,ƙM4h,Hd'CX 2ANPRY"N9po}sPW7^яGO$ IRhb.w։oA(o-ٻ ~PgLJܟ/ꗯ7ݺ`<E T8.???vNrpYP 2``[-ήSd"4fLxZh ScBL H%ݔ%k*'"ƻxJυڝILk!,+VHE#2WQyW? 1 l7C`Ή1QZ׋NGնK)FU]JTܟszc>*Q꺍 qO/g㺀Q,cĿ0 !|]K3UXy Q8b 9[cv>qEuUP]?p.%OSe[g߾?o~u_gk "0a,pmcӠ+%]psբm>}izۺUnisF)A-"P1B@ZIRvk?Ϙ590sn:k|K%K\;1ʛ|]"P6H5]*NED(3 $"@RP*:<F,p.)mWYw 4YBg-m?՟-j<FywZ?F4OF8JDq!rU.6n#SʩE.˟,PKTE\H&m0΍9VTX LWj>V8U]whJُ*eݞo6Vi.i\u'IB j2FNE"", O-_ O3 @$Ҥ%=edQYDE+rHz$V&? _[ks,7Ca$T  KD, B"\@J.kU0Py:4KfE "2YrN%#\BNdVQ (|=_3q PB$Ѣ0ّR*acjb~q*,\$Er1d6mVk %g&M㠘w+_\>Nc^/GLSNǹPɧ>eA:47ykGf t  +BAK̐4Z+!׮v~?nG$rDRUKR`8U8w*o6Xhy|h]Ͽ~~7?Qq8__?pۥ~`*.>oA&:tWu%˳nޤ.(WVՋd!R?_YUHrP/eYјa9<._ݪpfmyq63!qhm)yn9'D7E>_}=Oww.6wǫWJLy\m|.϶I^w4L="jYqJr14%2) fC3p9XR J<"\yfNm$+zq_Uwok'-/a?\U\8GN3p:m(/vE|w@9;LyiN]_boBI1 YU}wg^xJyf93(CD./ΦĥcyjWJAR40 7M=)0O}?4ff_W6W/_8{wobaC__##@*E4ggŦ<Y~~.f[?/?SSߑs!Cl Z@*b$ڐ%*%7Āb*A0A>sE2puժծ8(aHH ":TN?[-v˅Q4+)X7UM^xlH!dF@VRH@H ɓ5QqOaOg PlVZ}'> eX(H T CsN)FEI 0 #2 3"%PXr. "D䭫!QEr)NTJa )*L,)yJ!xm5 1tnO XBjzlW8)Mk]nE%Qɜu嬮qH1+1v{!/onSJ)%R I$ m##)s)>|x/ӯFbsUUݹ퇸:+"V+f9%\dG ^/@)^iRJxIks8BL e(j^\3w#]m7oq?yԝ$T Ryք9d rȳma )g}a !T>/;ne˿ܸ9L}."l!PAFh Xd(<ΉU>~s`ں[e  RrhulLE9H@\320dKqNOi%z~}s:Uـ^9^[:ot$ SzY_^d0v}1uS{}0.B$0BHU5¥ pJ !DPEb!{IykbiE;X].Az ~.un F_>ΦOZ5{Wt$MEeTiHQҏJxhH^1l$fȉfF]@3Z*SjVfm6i4ǹ3 KHDG v٬47:{}_G`wpzx8ĔnO90gdC@E [-uSY쌲$%miRtA%Ĥ@Df,Y@2 ?Q759@FYrr:NbuٸuD@luwo'c!6dF[2Q@dtysC|j5u]k912D)E  OSRUaTm4.ïq_}|v~u^=~zgzs)vnUd.Vw'NPXU55Un5Q?ߎuN5KgQ HzX[~m޼ؖviI_:khˋtUWj; fa确b٦1$)?|[jWA~wueɜw < sbUMtOg..8d4z]㪥96ƅ0eQV˒YծMsLJ01ǐKMfX4:h?t/JaP'(y v%@BQS3+iW"zZ"23 ko;ZnPtuiƭZMьSǡ !NiJ" JQw:͆Kf.JhyGTJʥi4OR:P[[{}=v1gs@2XdյKsj*E4Ĭi߾^C4 cQDZ8@THZ5dj J&1 3ǔB O="("@J(""RD?DaRJRD :F}."СS?b,V~Y,)xxƩ}rM YXF&*̤hy1g42JR8:LTN){n?62D,0&)*)xsNwG,0ObuOsJȶL֕1b%Ċ٦1$ђfo)Bҭ/ϟ0yV۷?OC0?" Oc] R@Tq;]~q|祈Tuu턿_O^=ix/_< ^^o+} ]nmi\u.ٜ]1 hy<~daHی#BySS~l^y׎I&v_.=ݽr%w=ؙ촨J~i^DVO/4Pvpfv EݒyL&bU]ym}xUfhV(PӶ0cכcr@^xyWӵǪ[w~ vIصah4ZiNٹD7+2jZR)*VU 0xez9\me8&YLE`CF!lkMם7uf6MgMUD35ϰvDz>_xPNˏp?>s?#dڼi {vk31R.'Sz.0 XDŽtRxjڏarUq2:a|n1 u/;ycqD$ymE2 y 0Ns_Jڮvo[cL釷_j/3 !-eRUJNh3B5݇w4vO unu7n%k {X//T!zY>SWx(U]ͷUe)EA S6fH\*r 1l0CU>a]ɋUp: j-R)9ĆYQ-!t*>\O˩yfuޭL,Yl=LeQˊ][VkY?/}hÊ3ђ5DլFdܘZ?}?HM*B4wru@uŶx/pLǧ͇f EH)nPCyFX&;ܷNo8fۮ68QA@c6iw))ru_Tcͅp.jMYו7Um֞ו{zIn$q~s4߰_}agx״K qe)VuC,.I/Ô4mk%U׭f.UTt9lWUX!g5Ą 3g!Q2`KD 02jUy6uJa$\"R d efÆѐ $$b|/TH ȐT4d)gPLEbE4 |Lp|\֫jI+)zFCV7{|1gPI!TD=DsES}x5!KVoznMO?.cGJ"wl7mۇc,X^LJm[ƌQCZ5[bJY~XKL 6u3ۻ5cOyuSi7V(_*B9}olE`yҗ88Xvήa>T쭯S (eHXuqꊁZսۮ޿؎nl֯-G@Zwc~Y;ڏKq+@A 3qm )aU9Άt 2$sXTƅ v㬯r.*h ݫ6ͻ'o7w6A( *<hß>KU>s=l#7), HY]*XCLi&2_?~R XƐ2*i p&Kw/B0BApX9$o1a z{9')%d;? )VCI XsŦL}mqUY5UzU;P5]%DjrIc1עk\߽kn5 iəJS,e0.shEBߒds˶Qb hA"EJQxo_}:.SLĘ0,2zZcݧcV~3 . Kʒmט1Rd0@,DsqV7ߞ9^>emBa\iW/V8GzoSALXm ɕJrBmъm5l C (@*:%8ߵnY)yM5RBhXm?w!ͪ\Pe d.Jq^xrZoB7nkn0;s$^U,IZ*%&M!-Asa8<)xr:S< 9ơvz^ iLi%vrIpR x_Y_vx_J CS9Kd@IEH!DYUĂB&B!" (#=d1st 2 }~EE%Tz"!U%&@gh!TR@Q< ?vaYq)d-!Z)L*[lYCL$#@56u/O.Ci^g5*YRڲT51(Er^5 8Ox}XBQWE@lg\UFƬYs Pug y }7o{f -/vSdjߙ.B[1 aeWVRAȿx1dEr3-6S;KqEKU+`0s_p>oϕ37;\2rņhHX&8^ Ӷ-18 "xӳ1KIwoߝjjU?A0geU`E12TR*-@P['A9D F6E , J <{~uy!& dB`fT$"E ""(0"!~%cTEIUPT 0kQ)@wmYܪ`. ĖXѸ1<-cͪ"\Kpd8sTH@@(+#<ͳvYu\O*)6l̵.){W7MYwz ϣP)@uSM (q.–KbӴI|Rq78&l>@"֯o^'޽mʒ$:d//=~m8JQBPH(dviլj@@Hq c L#IiA?)G3J5+_F "NKۖzc;VͿwEQ-4\j&嬥iN)j*~ԣ]329px^u nC d-$ra2Ȯ,}?sC#d拇KۮELR! goۗ޾7~Ka8 sۮ!bE@غ֭IʰL۠qߌ"H,VmmKiȢYtS\Wnv%uqDOXu0\rHK|ODKh󔀍kzgf;} H yBIahHlv h[oOS=ӶΪM7È HPH@3\>4%S&9xamgkp =P d)WU.Y.Svuw֨ tݮLJOt~| 5M۽Rq^|qRCQ䢒 [ʌFU 9&B2fKQ296/ncG/&!fa^˸dnEZREhݭn[gX7,\Z6JVO`YA/S^ֻ6?Ml*R)bTŹ_47j˜>F}>M P2H][öٺkq45ćlkeZz&*?/9^1Cm^?,wUpį_ua4aՅ,%GyPiMr G`G2xU ?NUnl?R2\}w~N% #p^BI2 TUR֒fj [n2/9Ȫ[/co?ll K)׻QEԮcp12Oӱ?_gnn:].!0YOm9'df-RTpOL1IV2in"QI9r*:EN~ʥu>|@US-5kj(-j .v8(hX hS*y R|'o0(O"?O==TT@: l5HPn36ܺ涫tn=߽}/vyqike׿鉀0.t!H=7C )dׇx ځ> װٯZ]Ůn_U,"DPBLkۻ[@K42,bLU@[pȰΫCUSuEX3#jn΅=&[÷Qv3/XĮ),?\RVUMz%Hlg9tfdRgU湌SKv]E Ѯ%jbcl޽z| f'#$X%3n]՛}e/7k7nV8yaA85w-*3Z RTXW"HP'V66yѹ|9۬ Pc\VI lޟz/^ತ!iX>=CoLjvsgpUzsXﻊ±`c )y1$Ef@[ŋ2&˒:D1g]fsy缭nhDk{휐n:t MjC 0Ȫ7PBefm2ytLUxW=_.4 @޿X83~IWk?2Q0l 2*&6-KXʷ-Pa9LcD[T!-~QU㧧<Ʋ 2[R^BD$@Ւ uL嗒ϗ8$bϖFB*ŠnW5uZG)sM۴M t:p^U5Z9"[@9OO]eXr1jA@ m-nn;LxFb0[6CrM|Pyϊ&@AU(YP"Z:k 1jbpgexϿ^ͯ/pEv?<>z 7ۿb> >~?6y1ؗkO?|ku|zu0{ĵҺ6z+UMc,`Ȯ{aHw4C}] ˾:1&f K qI"Ї6ޯjZ[bTO]AKȂG,e%Kq"C#n6Ow˧O+0KD(DjV%̄lSD].8g%& "} !4ɴo?aʘ>sdr^&DW OO9&(] Y/P<]4YpݪY]A{:qՇ^=~E>\.3#8H_/tNJƳh'kңmM3N_+ fY,#9*f(1h~diH@Ε>hpz 퇾>uia/ow/6͏SI9ߩc.3Įg| )i3wO+S;_v?wsMng*y틩OŽ!TUhQÆa%C DErIUdw J R 9F6/!JLZe^1iVnD1ι딣)@kRrxHSt>eZ1j%9uy%M y˵o}_]KQER,Zv_lW(uRXy憖Ue>B9뫶[9SWIKlU*WYkUJZqb}ԠM6Õ?M~Z^π*? A 8ҚX($3RYowNOӶ?q )e}suS ?|M;r8#}STss,|cpIZ#g%w]&Q-h HfyګqM?0zWJØSQ`.b<]Ƣa<ona 4e_eS%i:%b%r\LR_zJtNeT7k/sF)"Aۮ#PS. bl"BlD1gcpSVnu#-qz{muq%s1sZTH(?W|N[U'ȴ5#haHIsdY,2X'rCclY7KLElUUj;/d 4MW@k@R¼0wyYcۮ횵1mI^n#\5m~qx`?q`PBAN/^v^;-a7o- eW%2uuR9AX zSYE-KsI R1R*LZ{c+$oM1 }/_ݯn¹VR!k%ͬSQ9Ҥysh۟M'jg~>)Y>P~#*ɢE@ AgF;%E,@bKN`Ϊ (ђ@m,!(EDiA4UzS$%3ͨB,ECyt9/Aj4uUdMH)T@@M~V¹TJQ!max8 9gh(L ⟲m!a TMc)"Ƙ ?Lrd,첄8Dbs̅ty')xĹYM5-dKBQU%;C\^m9m+UO) }b4f[R -r*Jq {o+[vEĚ{oU%RՒmٖ@ڀe$ ǂC+?;l.1EV8MXX%((L>ܦ 6>WlU]2T٢NO{<;[ߍMʸϺ`J)3INۇIpصv2]<_JP~w(gQPbReB[4/ qUAvTf^wf3d4USUm$,Ua׾" Uo۝ KbfT!}wE!0gP,@!XʹjmV.0% Mmp4UsrVB\LJPt|ȩGYWo8Y~'|Ȉ 'U! H(`jw˕A2羏lngYϙ̯ƮS(*TeAii=FNIa(5pvRa28Pڶnڢ*H1a!lr40fSD*q̞Ce)(2&C8e8NSRJ MSd0*[`)OC+Qבބ9ƔcnJlq}ӄvW!MJ>/~S{hS'_^ЋyY؜9OgC ls?}~Kueg1^bތ2 dT@!ɂ1'&L T0fk5mԓ"CkeL"D1 nE%|k%d% ֦Ѥ|Tbm¾]n7nPEyH6z6~| aH1:T=t)ߓżw[P sb)~39Y0狫FckTPӴPwc^}j y!'d\ i:)LSy]j(]@iD*GXcDUSI/~z=lo^ ^Ro, vZô{18 yݬռ:&fE)EPRZ lbARDh!Ēb$"Tϸ(@2;Dy' b$&?6Na1yHAu#t"֐dœ ! jQ@uD%HyZ[;H9S+w9H1(,I!!d rb)wי0fF E17!άC9[lw JuXc]κL E23drQXdDl4,t4EY6V$Ɣ)g96WlVq/oa@zAPZib̻c H)eP@q1CZ@+zT.H$,LSa+?]܋4 1a<^/ qy ^89$ HI59w%ˏ-@?O@DK"* E" ZrIU8҈ kO%, ȠE^QCWP8!CE@3G2sf$AHDaxmw.$haͺ )aόҤ[5m\a84e>[~<eϣclN1S IDAT 4\؆ST:X6neCVetbnszJReR ݰqŲѵR9mUd8vO6IERsD YX1bB0"Ċd*FzBlY,}Ȭb52չ4)Jly2*J,GyeL PP(X3a ̏`ByS X"$碦2(2DMmz=]U8Ę1e{ O$E@aF/"FnjBX.UdP7.)L9G?$4b̀d8&f.%1 (lS}j#5溮DZ{>=?t1Fad(tOٙprIi]xV-H?Rh *H9@\eE:~ěipaaJ}LX'1(EgQ8mOl@k6p4 &k72I// Ezof|L %D0x LPR# ʁOy AγF3 X([#)a^#9z ,1e dXi:d6[ۧ~[ΊnM s?cݠb\QZvQPgLx*:pQ/y˦_Y QÐU-Q 2 >N\/8 ׊)$FWe 3UrQY.gM3u3[䃏C__f~x| e$*C1Dt*,O7Y;R9%s: )FDF AcAKBA㉟E AE0Y&Ga(cҿPN1"m 1X3S|SDMd/GA'f$Azc7z9}Be(Jv^3CQRH3~7m7*m*!qTZC@D03%vVUվ;R( H,¡7AYC$9)g&Գ)ñ 1Qa/lY7B!ARV O 2JAltRhB9 WrYZ;uzT!#(JЉPdHS(Hh!mRb&8Lj'PIrBޏ!pιji/ hPpP Z"#")IDa@4xãJQ2<a;!0(,O c&/R)6_wOx]C[ӻ>(┒&fuc&)]_DfY8 %[ob{'$_}E-B1d?" );x+mIu+>̡J9+i1,V5{:m{֦qFlj>YFyt.^ u9#8.g_Ͽu_^c2JႠULbU?BO޼9t# UiQR:KSP8jYPm.dQiRf&T)5M0lC&pEN<3S׍ b! ʸ{{⪚u4;(¬oW7 oqi 15T(+g+2.CZLCja&RP$BBEB#E$@@N4y(]́ 3b`lA <OIV"JNMZ0fLHFT1$C}S"4؜E+]E )RN""gAH3B{".1ƺ1v%hdwm@2%gdx8 )6(.\a4"d K6y}$Er<Ji?t#̙T,H"κ1&6΍I;ʺ Pj cY"PJɠ2$+;ݿs3xcBS`jUz:Z!&0{)TB X΍4 yV  )dqV!PQ́ ׿v&|IP:g}z9X` z6G[OBLVs$A@bahCkA,\!S7K~X5mNzgS}gIb,7욇cu?l>>}[ oZv[qjViMaR;||ќǘuFyݦ՟}o_`(@|?1D!_|z0nG0#D3Atb!ycK"#BX?.k040_l}<6o? ]nH=83׿O~p8~ͧ\7Řb} N6Uu2eyf^{8ǻټ9[dxB0 EbR1BL$}?}ei$1zH`n{z_%*C)4Ҵ{zH:3[E⇑ä!jm5؎C D;fUqPcVJc5I42Aٹ3ʺ,ݕگ?_5U~>+_t+*'=9V( DҨbճIfSRu]=rB+(h ZXj۱)O2AƲR՜zʑ.x:L\,EBtX)I c_ڼxsY&g*ݷ!fZe 11'd!4@.SEhQ+'fϜVuc)xh%U3RXT,ݪY4hRmڍ#kJ&,2MGa>[ijsspqqlλ+WLH?CJ6B6ES3tzwށU3wVW5bG?ēa7CqMԵϢfAtsbdكaw|PAƜJ,kaI) 㰘Ueݰy;/vS7Җ?RRUa zya1rQM""X$ :X4rbfS)2Z j S83sf@ Ģ~2J9]dtBP,-أcjEkA9r#C`E  3&B`F'$E)10M(SJ3B"a Sn㴗EmU/n^K[y|ب_]L\[S~i'@Zr*kZv*Ni;V+Vͽ3J"H.!n6{mi ?^~\DX2HPS"AtB Xcb Y@fRI]Z;~?yS{Oo^qO3]Sn~R!hto2뇭A*fٟ~?p"|Q9w^hgU7+>~qlC 1b7}/۴rK0V gA #bGߚ_Q2xPZ,Htps>+b@H @0(@6 fs%bf J!ɒ06uUEa"8&TN ~K/^~4Z)HAkcH9cVB02'NQrbY08ʪŔcRu] MJf^z|!%53 S(dzu>6ZȜ 0FQߢdHXcKai18>O ^4cJaoI㊳*870*)T4য়~_M8vydIY,$"1$&JHj%S.$Й!&p);Úyj9:yOyԉSm |y ~lZs]}m=4I3,Qe4@8Nvq9 YqMU/oQ|Yni{pV~y(-]Xqe?>ɯw M y?e,M^񨄧1LE'.1Z+ 㐑]})CY؜pE!g&ajDU3qRDv>(l^;ھ=+ < b@7)0kMr" ř` 8<93éi*xv0X8I P0?YYH@) @P)ЀJļE"A"H! N9؏gd4qB"5VUNi~8#"ҊDs)pPP!eu!d"Ɣ[ʺFvPD#ZJk/lQKHY r!r/n| ]Pj-/Isٙ}-EAk֦4!| &Ũtr5LgU(|\7O]y.z{|z+[q/^fנs2yU{_Sw_w77/]Uvqu͸giVv~I"ҚT˯>6lRtsc)Ȗ{U M:l7j9/.o^8sG߹:4 "Wajg˦ׯ~r~݇symI!.luq]\W:o}&CzUSTiX(;/]7ʹ'%XW)3ֳ?bC&tSe"~ǐ4'W+1/?\fKrLDWe}U5I]&m$Qf-@ 2AFD R Ă @QߗkB͔|b}DѠ1jO*UQڢӏoa"拦p0zDB8 b6WZ!7|x8Ĩj kRNlf0snv9䬚7.TR9a!ouvw8C9[vo녝ّRf) TQaʭZL4׉V)g ՟LN~Y=osn^\-y@m1)W,CrL,e5s)(*&63Q%cY1sʶ0AȊI伲*p)Q#X9JDJ1:JfQQ.]4skWD4YAI~Ð3|WVW6P݅v3;$؍~8nshWvS"жøQUSh_۔k77~=}y^W*JsJF펑L-1C q 0(4 F?}z_Jo?ƻ.P7+X|klQU1e1jTesVJkmЍye}ç3& 9k Y+ߍS׋8U] -K\lsp*@ Q2GFa P4g@A&BF(I@+d%L)g0iE N*XD. f8G!-"c1Ff!@N4ANDArfPJIA"191آ,CSG2Ob(Z-/Ζ+C=A3*3R'*zjHic )z\.U]iE].c|]CQqm! ( "@aEAfCt?=D RNs|?C'\6Eu ;w+.~_O7Ie1Y~7TΚ泲>0o۶_[ï~76{ZAl>OSrl͙s;N|4S/pj5+7D) ˋ<{ucf~6]r(QNJ4\̴$by=ٕVqqv}z:쏚q84Mq>^m?7j>G=M)dߚ6M=j&,x ;+{ϼOǗ"]^][5huek*}NCڴӶKV139G'3II t y{n@P(1 kB@CX'r

(F IDAT@VSYT,0NsRHPWEigM]*M&&|#i~am)cDY/Q&z㏛qXןbc2 1ֹ֓JUݔ)Q^ƴHfBGR' ou92a v#C8=2Cö˺YNW"Lû\ $º^rۇ/; .(}PyjJ!"b$!as2kdE"s`hl*3JʧV40 gwwGWOH!NT^Bݔkw  5MY1*FQک"(Mͼ!<>*ə;&v3[0,V? 1:r8-%?߾6o2JTW4|Yݾ};cqVQ+uYQ&IsN3)޾YnwrQk *H2(<<:Id"Vκ4.RN9+aU$(L'<|$rGΘ{mF d":5 d&a#儜%13<aAP 8JB4B AEԀ 0!/Ν-Cُݨ/\.䋲DYhʕeY:(Y8Wtg @X2'E9Gs>Ѫƺ.jQW1V)fL]*faRJe$hM HؔUżLaR9q ٕZSNY';sN@ϵDZ)V€( "0!B?A! btT/ sjXk FHyQV$$0sNf|pvǦ^0e6Qk&x9b<|ݏ ׿@",ȀyJCSi۷H.߾..x۪+˄.~ %LA1*搔?+I㬐TG7g=0 ï~jnY˺m]EixF˜丙z4Vkw>^_μ2>uǔ1$?&k<4ڻj9wd) [+N1@^; i9ˢ;¸E#",E|gf0\0ѐ3Fh;QIwǂ<]Q1UDhB.8J1vLOeaA }ȏO ( %0a [-wͼC03&FQLSvdVb|114[w8")[7MeԮo3iO!BZ/f3WDgb``QY 2`f HJnSY/]-#vlb$>z+,dhڡ?.Hpbdt={5wʀh|WSL8p轨ZU{JLoo<r%um/ |g7lݍVK.JU 3|a!AA[O9+#bN HjM9UJqfREJ~Ƿwe4Ra*ii’RTSRl%A4dXyyػ{U=_^}~Gͻ;_j*d) \b_*p?%ڗ_E+_*.h8`myT^C浱(\L>^??&  ҼtgrwrfQ)CR@Jf"hjUOPEuuT+@>ieHxtvzi) 2Kjkkk%)93P9~}arb"2 }d3 |E)D @H"Pi "V"$e#TX$RRb.Ur)Θfm K`x4aPUU9Ys tb x?nO{:L>#! *ݬ;cIqMݨ]Y394ɇTc#InŐ"i^\EikHJyYiy!"">.꿞!2K zfFZAm)UD*'dH)mwgf5w/_<~O[:;=IUSuS# Ə b1T֧Դ5#Tm,a DA."(]v;j.?ƀx.`<sS@5+ |vì*四~=ORv*E#P_5iTUawH3z+>|jVK)15ՅZjlgE/ݡY7@C-]~׿MS44l ߜXoc)|`Wm}Wh~%`?S=?ˊJG9_XGp1e P)1& )lsKBQ ./7o޶׭T\KXynCl.VvM%W͍12N osƲMx0*Ei!DaicVJZTTu` C JW0`YWP<]:mÔ(g.~m}Mν /ΪM|3t7ܬO}v]nY&cRLֱXhsLX0 ÓOӕN"m:QLJZH2-TFйسC8_Ғ k,x"Y]OO|J)Ww;}Ǟn@ oUgaL\G%u!Jt՛e4o~8~F$ Lb`BΩؒS[Wu휼}ϝ9~/6_RIRlt*ZA զ~>>lYS P.r6gFVu]ýy>ȼXKy^$NEi )gvV{?,hPek57V3 ̂pbaE3 $I<)0P 8V!8NU*G?䔫CZXXre{۞m}~gOď=i{}S̗!h$Bf&B"ReTJ)`fI%g sC't( tC!+$\ao[M߾ب/>l/c15Y[8THX 2'a1*c @Lƒ>kWy2ܜ"+ݮ.C?6?Q"r2ȂRI"/6,|OƊޛ SHY"W_/]j%E:wiKM^j% \X2 @}JdF<%Y1of=rB,Js(jMd!~^]R%sݦo4!Ry)O엌@1gl6q\jgk 8q!(HNI͹ kmX:)Oy:ŋuզ6,.\|R1>E,u]w^Tl86 xStIJӁ3-Wcd!LTt69jVLJ[?y%%HR jJ/3ehˇ{(dZ sfSYSU(06ُ]aG ")+dw|Lc_xϛ5 kjFnqI6~~"c%%b`/.imO'vC۴Wr]q_b^2@Ƙ)eZBfIqYV&8*EZYRd i 1J:D1"B\",ˆt³RrH'~ )$4 R(,@4̭kww5O?_5ǨSq7BEi$oB(! 1x_V+kD:|2.ú1߻f[Q+ucN?6?xf n' #9Qr_vq6/6r|3osf ֿ:yx:guceo~wsޜ`s\\?UL[Y/?|V)doju/Va.X{Ty-FqSt(-('BtL(!G0R`'vǦ.9,$©APM$AS l*|ojշqYr.m]Y+W}ODHSVaB jT h\B~QFM24s21OZJS*WHUmEU, 6^AβּqQ}e*^(`ٴr<EUc=zSbpJ CEU` J/Ѿ7V!}wV۶z.Qku@HIo] ?(}?NP+A%D EDr*4 c hPaVF""+,MeN9H۶uV OQB QHNG@Dʶ]=q^La?!vU_lM)z.SLEq*0 >e H\iTvv^3{?e:2U_e,X[K~VBUvU;1oF@F!k4d αVC鷗;I9W\XVdJ8 k.jZxk'C*Uݪ\o>l}x]r}= pu&GKK͑vKcRUsy{{ !9w?0CndUǽ-|KNRMA:q2PJB@Py9D#X%wlTlbt V@Y44X) ٜd͹q^:<~ Ʋu-S4/MMGwsWW +!b\URyկ@bN}fSi:e(B<(|s;2%W%Um ehzMRL0uYήstXm_l263  P& 3FPU$2%TfI?\\>Ч`ց ɧ0ONJ{C)(жm[ל㧟zz|'}^vyGR>cTu csWgNk1ukUeKa8N%a8l7&Mi!T˙?k~1m,5bc*ag+\Q2@TYk2MSNCJaΑmHoжJbQJVJi@nQ (3]5\~Aǹ[&Na\"7Ǩ4U$=(X<2\U-4qgTO)V a1HnbȨJ$Hh4y7W5C/7凧LB ڠ:cĉRX\s5 ˛B#lsL\۞WMK?|l{Z*#~םpV IDAT0O)E~_meoñ!ZW$2' &"f?m|CoC3kֵTJ3e5GCC 3$FPjDW8J ;cRVZ j}Q~(9[gey*pJqu'"2VO)(7m.mZcL)p ")PĨ) G)z^IX # |)bRђUɔ3fCӓ B@$*ZgCLQ%J맇v5d@< c6fYv{vvֵme  DB p),  X0ރRȜ\ )dfAvNj"rч%Xr) & X]$gsEgB,Uo}? \(ȧQSn&,N>͠ #)$ %g"rrI9GV*TQA!.mB ǻ޴&9ĩfȺ/VN J)Q! Q゚ֳe!Uþ۷ouGFKR7}Z}$j3/mPc YB#*O)|WE|M~,atMwX'/.~u?<~߬&g"D$UK7&E2ʡrƹ.Xļl+8vU\dH)UPP` 1hQIral+Oy~7?MX@KŘCj9d2Z)gEq(L2)3}@FЅMM۫mxxy:0(:vIH-`&,uǩil+لCAnY*Jb@i.¢TQq"BV!/,E~k__ BҢ +]Kbfi8K!LaFUߵD%)y.W%gY~'"AiWUrnsuUMR a)$K)gPqkD.ϷaÜn:&.gj?fK?P, hM Fn4'kHJX7{(|j>j_^RU.cKLDa}8Z dDF%i|_[\SBi+F8>ܥy(aL`:ntGXfvL;m 6s]{}NR K&K%"g@!a8a*˵KcVYUfXw(,Rj*.р$k0XX{YW'jB"yvJIjHCJx蛇BRFkJ)EOۘ9TJ[}SUZ)DNz'j/elr' 3R2I $ DV\(g,9+y*f!>=#h O3'qR!kP&S2I*DRLa9lV%eH) Jk 0hBh":ycO;R¥ B* S%TJHiZdAEBYXHI+ԵVk[qc93,n>%4<[u5SJ)Z9R) OK"Z#p)1 JqnJXP) ,R ήڮ8RWRIm₥S 9)@cmeumɐḂC1pq+߾]>zzZ۞mEV4ϿX2>3?j#X"<]q?1NfPx!¦˫ׯ +Rjsu+r:߾{`U}YӳWzVDh!T$t~t_<گ0~C,նJP>k]+j\pǃLp{?{>s/gsIm''Oqk 9 \o^\/.A0몪JBP4"J hV1BinuNi R%><>L1OrtM98Mջoת'4ctoR؄ʡQ`92Q萸R4@K\/2ǜHq!@(IiX#|)fdrRm9-[,UfՒ(&PCP&H~4^gAAD(JXX'W77^*]H4IQ>e4Ƅ;kGjԕ1F)?4j}1Ҕ#"ZieY}hE1bqNiCRr󼄜4G軦ʺ0kJI3%W,=5- -$&Gv 0UBĚ|V5I84$<UUy>kEfi>뚩}es!,Ĉ`&,?꼯*(񰿻}/^t=֝Zzu:y?le!<fyDQ8&͑K<>>9[/vkDmYdv5pḼlMO(*) u[RWug,X#p= >f~(MtEzԝV8qۍCTR0U p-Bplϯڋ9x].)kеͪڬ'7>l{͋s\nWg} "Zmѧjϰ]E5IE)zHXb |vI}Z+inx jeqZ[cJ'*"~Kh exkjnVr &k*SnV.)+&U83rV ERJ I&CXe!x.OQ'I0&R$zn8 4 GDC8EBs),,}튀@rF2!"1BNs:t'W|j3ߔM\U>;[9Q5m5%ⴻg_+aû/?&/Iݼ la뿩mNp?}M_U\mCe Zčmf.X/jUѧgz볝4'N"Y`桭tg e1hVŭ+vu2nU"L>L5 u6H}:,,øIn;/Ki:j&^~ogB띂R >CYlW`*=V kI}A@WX 9lgιܒX d EՠBc?҃ *T g fATvmϨƞmL{=Y]V¥)E%=eq9N5 +(AHRyi4p >lD>9Wvm7+sˮ^@ά ۹\ۙw@ udZFCS(9~k];[Qk645oUh,h  |^i֝ݦU&M}(|YuFQXꜝBc,;!C|4}{>UYo0%_4՗kq;xq޶鰼߅oq6nbAP|ZYߟ߽AUW8qi5eS y}W痯>/oj{qm VKYRjc/J7+RrQM |؅u}?cKι\Wd<-Lj+`bi.m,}eU8'@"#Q4#)ej"c -QgnR$gCUe2@. T4al(RH ĨT"\2sœO5@!f|jc̟1@J/&6'P;riJ|H* s4VJ:$Zc5&TRJG}ӳyZr AnN]GԯnJ)K%fkz|:&RJ>hU0"ABHNZ!ZNGX@J)cO<}L (%s9)NNM hU(];}}~Ϧ]_}! @aΌ,5!qba!PEF)XbZVh "k.,~^/@Ha!Xmfs5@]҄B C茶a(=J@.?l;Ͳs1/Pd ̕k clmԻZ{ + _m PAwCmS! ?W7hqG|ߥKsf6{XUIϓO"wW׋m# MAw!+4.'[՟& ػ[J$hho/)//nk[Er~xx&uN'ߕikPVj @4^lH'M$wWxw?O0a.kO0*|;sSOaYU`6ԯ^3j鱝tk]=mEiOy컻;qׁ?Q?qN C. Ѡ;ND.،{@HS9@fphH`B L9Y9EE8>ckDɡ'I|MҨT iUT%-͖bU !Ȩ@!+9 燶f5/ {A̠E;;b MC)Z,HC5þbF.4iۅ44XOnov{-:/9UU5">3j.YM8TbQ;sZZxWp$WO%c aK2P%(ĽPet[WI"zL[]TE=% -}u $Qd@)0wm,ٹc|wOCgdiego߉ua֬/Ds(J8fyW~vc[z:xM=tMղ\v:.Wiؗ}y:W# ۰iĚ=EM}O.7}Js \%W>ށ(|8z?[u[/n><~p鹋Kf@n%Un7Z"{Pe޳l  d)6U &]UJ"XƓs]NuC挒Zϛ-jq$F>Fc FI阠$nj1xH6US}`vV(R'3>nj49~9~T3)h|s)#Ӕpais#b&D102!1#"$S<0_`!AQbJ$@" Q;kXDJP %.F@;ua֏ LS46\mڪG_/t"4C={p@9 y&* 9LEe )sUSqʁ˦¦F< >O|@|ֳ*yQV!~Phon9961f~)zfAn\!oeՔ!>a8*.Hfv* "90: ˊC q]' C).{z1/+T&XB kC˛?|\^vs'T 4tLJoOxK?c|@Tʺꦺwc\Bhrp1Wa)clU(XvsGƩs^cUݨCʓl6% hB lsdŻc 2A38Ķ2`˼2W*d@t}JTz~L3,Rш %+dh1+if&nJ&I 8L\Tᘤfc7|i}`tƈiYeD {Em˶y4cԼs<˫M\TC&g0I>R~)XH"vѩ}s ф0V1EcSŪXco"}aE>NMvaTVR-flg4L$nx0XAGu U[<]5Vqj+7q>:1zga<ii$$S-)L(p,M7zN3펳uJ 0~ɵxn/蛱!=~Ehfl=/jF+R*K˫c?M9Q`v̜)SJ?p. IDATj"rsﴀr|8("+ dw0#(mW4X܄9mLAjP5V@~BsۋjVmk64R`J`MClxVv1$D SSKjlVݿO} L\uf*:z??6RS"VWE29C i_a,1i<NV~Iʡf\hQ Z+>i܎ԌYb@iU=K53Ovٴ ꢶ{\&Rpe~wmS^؀ԟg;eSH4K]͏6՚Ob{fӆMs/y+/$Ju]2+P*K<'xj9~R_</ԮՍ;\d̋ŚYA|[NjD/.S  D ޕCg< \ qYS1`+4qaNrp4Mz2U񄁘 "fp @1v?H|.)Fex{$"d L#߄;*a~B`%Z,eV湛uiUeݙZW,\G;"Zבެ-)?C W@YoPM(RL|Wȏݲ Cqե.bQ4LsX==)Y!W*R]OEɵOHRWb̳} V܏x\jb8yslj2ժz#Y]U1Ţ#ڜ'pxtZƣHIUq8( T> &-q+th<+ẋ&dCSP$#f"@1$C i TEUSu`S)jf:嬘4B\E"iNU T{H R0!}fFhh `s7Ss˙*\\l۫Us&I(+yVt<BJ@ƴB.Ϙ$B4XonGIK̎ \4";50w=p30%84x7: 3 H2 n(@1mᘁTO7_=|814Tʐc$DQP"%qIR0xr:MrhA(73`;û͉>>4T-AfQ3[ꁗޅR̤ddA lj#"hb>tߟW#?D*b_IjPK*2,^tΊzYۙ3@D="z=S'+R؏shBخ7a\-[0xǡYm\S8-);@`bEІj632!BʹqYUVB|e!w1¥PٜStš1dlm9^HslaӀq~~JO8sE~7mTL}e+!EVXsvn.*n,!; `»9.>gGg^Bi0D2<bˀ8@jSLax?囹{@MDטcBĬkV-L,K v;͇#]av:%a/_\^Y?`IqK1vfŜfFYOpw!m&n048څ7X۫??\^^]nB"mM8O׋uϏ]%MKJ!T=[?{S>ͪ3t5~< 1_וNZC;S:>4\J})kQ zp*s V!hqgY*9azݜvrt)P=9&=Fd\SތUKٙ/sz3%LL쌔#bsp;F$<h`gɋr)bU7SrCCNq~h{q:ffbBf{]fj@3ɀ?7AUaR]դoH# PI)yΦ-&DBrVJ(8":(zGRҔ<ǧp0 JQǬE7ќClF\4z8h)"nB|;}x8=t {@bv C0a#@JISg1-7ЋXNe fyhi>ٟWRөKo fQza-~"r΅Iܒ/_ӏfcinOq0|x~nML8y/UąTJaR)EP;uk\\[&G =9ni/zJ/ ]÷:u4UF5Tff| ea $,X諚;(Lu}s9m631rZchT[49y+ &^׵ Gd @YQQh}FɆTf "X q1.K0( l6+Pmzk[V禵kn|tK y7(B$v #hc8F~5o|. & L#ƍSJSdG" }s4 /n/~Hݡ\Oɵ7i7~9 `nI R岙]Uͯ<,aS" ꆴ#)]:%z؟_~=}ۦ4omBpQ@clZ!rr0DR$%)Yxb&}zr:wy7͌IN9jPWgW<~`c٘۵KcJq)OZP Nu !Y8I?B B[p8i..W8񛧮,_|J,OM~Ma@k,E]M,j8wܛEKM_o۷.[WMͳ4CZpǧ!w`FJI ,E0He20s4Z5s<O7#$(F 8RU *:]Ƞzv)9Ru=u02:MSNiz):de_ BP+"E 5@{1!/3r{us6SwRcxw?6(%MqeF̢jG#P25EtL}J> 9X-a\RC~7w٬ۋps>?ʽD|xLJOëβϲd&bc>~ $aSE݀: \ۦvp޴ScU n9F ͑40"CpDPr{- ?|q]O]Ta<-+"#PO؟{<džo/dp5l0·EqyVcy5+àL}3g)ڰ3뷗OOSk$!v7=ի% :Ca,]9e8N5??suxկ^-~k{y6O۷4qƥTݳubnNU?~~T}( &lтYPdaYE8AdY}v;{Ww\v8\VqN>a|:Z޽bLJD7͒.AHbCa^>wBZP|VyV0xSu &*u;NRb _klCL xYӇZ͖)U!vO/[11[ʐ)9ԓJUnF)8?{\XjO*le)lf6u沲*2rmSz2VQ%_3 -1Yq (:_frﰮy~YL_y[dj34̅1==)Պ.ݗ@+"E>+}Y m>Oȃ/e9 WC鴉յLs5L\2B H{s̈́|#yHyhf\@1(ԋ~$dKpzgT)LRjš>S摣77_}{r] \ood8<^D~qꢚ݇qt6}Oiz^P3rzIX,7|xqa`!Ɣ- EHӒJRjj`.,8n2%uy4_nzmu]UOp?|a"@]ojdQV5+F٬npڽ٬*CE8)0Hٻ(}s4dё76a.P;'C.z(0:dfS! 3^ʹ yB%nP|0G%TM,5rxJ_\=y8ͳ!POsFG]dektgƻ/ܬѣȘvbބ")~,tJ4M6fGf+>\8 ЇV8Myɚ ?cH?y~O<+^(/z9 @S X]O̧fLsdv4yվ)U;]+G5XVMeXR'-0> 3 /((ժBrj};]yV"bqY釿 3}~N_ܼV߿}i¦vÛf}*SL˴Yw?V wg4/v %Kh`fЖF*Ë. L uT4=N7ޗE~C(`zQ Wa(|!Ƌ^篷5VD @L ؂ YUKzoWx=|PRO ;vfbBXzW>wݱr(dgz@0;{p6X_mQM¢Z]\8A{>Lf$q1, 9+o.zg/y<ǏUCD4I0Oens\hGk0b6_}4rVsw5WuoWKc Lx/0 c9_Eb*,"NW`!T&+a+nITI~z? ;s4Cj68Gmu9X,obî?S5ͦsGehV%΢YAU3 D簏 P  ᙱw^hDM85$cS&Ve3e-`j0-D=AƾCѺr]iD/v^$UIļ!1%<94 Tyнd5dך p΁BUuL`Se3#3cΰ#@Px{yY5P._B34dT594Uɪ(`xwR |*{Őа{<Χq廛~|t׃hB2h]1ZIل*^&7 1w v1OZI?]4#:tرdZS$ppViYFv8rp목B kp@g(H~oV!@⹐)0)p¶Ňi2euYso:8WCObA>4z74w)~Zyr94.Zj̬H "Acn8;h/o.??_`0=/V@=@V 5]Twϯrf[ p4QQyY !) 9DUX/6$bgA ۰vTcH$j|e~x.%,dqӂQb='29l_M̯mPF"f@EQ I2Yt5_P!uFDN0'2If= *s į\:i~~vc/H@W]# (Ts4hs2ռn?{cv0J;VUwW%Ju /q?5.|!I'u 3]}xdQ? C.Zs|K+xy;Mݴ s,8 Ta4bG!on+SOq=kwOSen8, OKwa/q$Ta( JR, Ș>kSdzp* d:?:PF*m͗y83v=x˫iTws\ qg b t`JISNrh(7\|OqۙX{\TK<ټj+v#Y 9i2^\\lt[,q֜R~vqyJVT(ENǣfjT.DHm9 <*h{D;P- P=g*?""ɏ3B""* TT  20cU9H@ `V(QTX(mpRA)NHL@ Y$'b2γBX7C׵(`F"$SE"!,99oko8K1\sιC9gs\?(fB<1 *0s~HT@ΕGgA$fSxxx(91ZwF>Ao}IE qrl-/[SO !eESZ-a9ռtl<\8ͻ--#Ǔ AE-VrJA%K !=/T33a`̄Rhf"Fr/χbs-*R% NȣFXr_Xԥ jw7a {a%U2T1"iLE\ Q2fbQx> Sl}l.\,[7~P}6{rd;QYSJn7TryϞ5'e796Rf:8N9n.~F|]ʥh+ 2ncHfUŹ#a) *LD% H^LaOȂXLI2 x/\)~ŷoOP=tBII @F$$FŤ1z=oo49&TGw)afmS&X<3J$&CU BT**@%n(LI$[F![sSVuJ?®$%fqcEܨM'IU `r[n>!%6 HчtSQӳ௢Ua#jq!$u20 b3Y60qrz0{{Z acQݚ$ AHQ^edChgbAV L"Blbn:) STt~yg6`r J V+̉Hj)/oMP%: xv{en6ڷJ?sݔB\U%dg\Y$ SkEmNj8WmTgUM L)mcƒUmp0*Rzܴ ) *"Y!$"4ggƐ)xnvYY.vǤ ˂ҬaX]a{n%ⱏxhT4og~ tځgTqgƳanꚽ)k(Pk*EJ 4L*:M)rN|ܼI9?(B GrBr9*)΍S"$A)#8h)YACN" " 1iwe1,WTmHqp֡"ORJd3!E!cwv1Pq"??a&K@ R$?3"c̹ߟ\JsRJϖgb `1ZΛyvyՒӘsX/O54 ﻱhaf?k/|JqΌ>jiU_NODmgǵIA"e8f#j8g S))dԐ!K2CE `9CǛ"FW&TS]' .Pbh̾.Ѩ׍zfdG4S7,sys V.EN~{Xg˅Ѵ}O}&5ۛ óCꊾ;`)~ּ7OS./\\]pZ5vغns2߽~zVRZa(0Κ]< PP@Ïg?aC# s"2ϠAaodX'6>lfC-nW@}1 *GRcI%" fA@%OFt;[iCf\L)?<6Х4F΅*Ǘ%мDPFb{ A-&VDlS5b΄I)g}]7i&oҳOբgVo§K$$ D<vwOcxYn7u~h^d$cNa8.>=ґkg?{~{c.W_X=ᶱVvшTʭ:âPPS14\d v[Mrj#YJlE\&F10Wv_}\_cRbG>Fq' P$J'oWRe| O3*I}⋤mFÛRl;u3wSɑP-Hb33Xޔ䤜ʫmm_7M-j+39-b1r1{PAd2MO*YRJ2n?`1ua?݋kl3 ^ YW?kr8^NKe0h^͓uov%985HgZOF:Of0ցyTMrf֋rXA=IcCT?>w&9;H r28].:>t~67o0E)gB&n0 ԣAa(UEN#ʻ#.muV릞qpK{ wUqzy<2pzFahj~N3$䠭n1nH Bb!T`TB*1e=I'yAFDD˦" J"D.R 5DH׃J)ČYh)Jb@}>NJF-$Q49tDLżkWJ6EE}5W74Lv:dei]͆rɹ011w]sYDҼ*obSNƙF@8ESB-XJQbiΙM$yo?2Ɯy{M3[թQ ŔR\vMDh*{BIm[DscRvozr)hk*@R,˒es}! LXWu+E4 c)X$BD6Ɯ_E4&Pb9 ,ʐǑL "\x AO3qZ+qbU/됇[gbtܰ/M3y3v}klx5lZ޼>u~ Q;/^Pڼ o~2QLN<=[ӕP4Ym?a* 蓂Tι|fU@e-( j  8 RLs2ET 9oJAqM quscY-EGW5U*1ޓVtoe)Ma|Hox?^WXCNWnI:s`*0Ud}[1LtӗweYq4s7ww߭W~0Ť*-O_^\|mWO՛`79W0xэMpogvh+X̳fe%?/CIBrt׌RT@E$YZW!qβ?qW@@U!,DJAK))Rsrv s~m 94Xm g *\J[Ȳ/J)眲LD-WB-" " 3β [[a&d\0RRZۦa 'En!ec]!|H輔.= _D@YcǝsiRJz_U, ]?VVZ86oL2$Qj}-z7ݽOESEpQR]Q>Y6*qJUZSWZ7i(Q1)H S"✊ !㼭x 9a&ճu2[s @j#Sn׳F |Jn{-nv ܞZ4pE=GOn~IH amx`Vb5]۹;nd__+I30kXQZ$9 / ͇8#*VW 9%J-Џ cDsx~~woxu _?/a^j%`H4&#䏽{{UZSG\(槳^Sq5[E|4藜K m͛ՓڄwoRǐOg+~,%%˶Қ"khP2Lj*DS7L ɷco*7sf1ώoI\-P h&+PT"GQVYkʪg3 sO*IPtdPO/_ UIF\WBgCNπc\$cOC  ~nnJʽeW$ ٗRĘ d5rI ,S}c^^|^ C*.Ph`3)Na ! IDAT5i0sum%q9P ]fMzOV}}E ]Eo-eL QH-CLX^>x(ɫ)!uPs-Of޾jWovaCUSF‰A(a]QDVpEBawmCNY~sȕ4k߮KNa:}pBcdiFXs|1k/i53~~$/H:l4ʩU1MJ%q8fun}uQw}MMr!8NYZ.wLVK*ZA’0ŒQQiݻac( VQFVRJNSc>()b)bP)"AFD5F@H?:h%[l Z-3ä"i0-29wWqYS k9naf7DBB1U)E,k_8c,`"EQ"lRgkڒsV\Rϖ~:Bfvu]?DYB*.!nټ'̏P+`'hA@rg)ʢ"JhreR/unpb. 8Qd=M(X\_Tj}&pBXF )BaȬ@u5 ):g8g,$QB/tl6'v}?mլ~w2?zѐcDޚYBQ%d >ƃ~<Gy\۝G@W!cfOQV:A,*A)#'/.MԸ4IɰM7!>;+rnJ'ǀ ơaȢ bBWYcv؞Ĝ 9PgKI*"1X؃^/2!T0U`0!_֋e=|}?L5 bVmN0I%lGV]A!vDPH$K 0׫movD7( SA`|y@Cnxja8cC6}wv=_Z5q<6 @03ʥts&h^\ۋneTX]Љ[?\4%Y̪ 6MPr]Wuw;#s}O>dU dǀ4feCUTʱg\6c:}ۦ(\0n8=^ e!c %Tslm(0<4(HD#2 G3#Yf&"$"B"@RJ1M!Ē8HĐU%B[2 b!fBDYgM*c @˱ơO1zkȚ3O *Hmגqq QNK$J9[umkN%BLHXJֹqT|CS!f眵,4;1Fj}?MQཟ| :K# Ʊ9_V]cCO-~bZX(SLӴq5_8iKX~e4e㭕ٺj!_hQ˵+Gq;s$Bl!ǃBֺY.]=nn>r!$) _ߏEH2 30`P)DJ~x&^]e1}ulSwS,SW3fhrf^0M7}_W^=!o :;aЃVE`Bċ3'}ɬC.ámc48H픦Tap hϞ^߯]JGd][:quJT`G"TJo*0e9cUY hAClZ@PBd@# dB*B) PA@G(ʪX"yh|~y*E6ӘSA1$y\@2rW ̽v{rͼ\ h "h0[CĠ@_w͞AM7E$:Fp$V-Izyz>~Q/K}LF$`*dUSAmRDA #XIbfꢱoﯟ/+W]c|\M!KsIJ BlÛmȥԂVOտΗsUR ::0s} $ )BD6˔2l`xoDȕ/fЩ|8FMxT| iTƒ_T (SR֒:ɘUYP%)!ݼ4憁16~>2`bMa3GPB蜷N)kƢiuqe2\?onq|Y~,@Upߧ59 !f[ן+_G߼;z{[.kt>_|ߝ,6QOeY]=ڸ&2 q"WPL4uƀ ]G?'}so߼>eѤ ο{05]CHpږ0A{g=qܼa{ko1 Q,<=Yr7CeGiޗ0F*2rqy{9CӵݪgTy?r{/?e7k1h' !{ڝK8uПکkcsI! bt#@<` 9Pt;>[cX " Xc1Li2 4dɢ"2ϵĈ3q9ۍQ*KV DCʵk@ITK.,*#X]]. 1s1|9.4 cR#)7H$zQMI J@B'qDͺnfn}ߟ3 368oTmzm-a0܈ﶥpBS|N (jL?Ad$ !(TUr>#Pʱs>(GfRbL?ޣDz-K[fc ]RlCq"PDZ#AZ"۳eϰZՀ$Q"}3s4?M8X He"Ci}%i0gi; ި]28QE)+Zxf@Ø+ҿ۩_WTܗ*D2,L˄,`)+e!%PHg\*?ܺWgWϞŻ[jkPLiwHx!JP`.VPT(8 JUU$@(8/J$@ ѩ,h-z?~Wǵ~n-O!AgCֈfg#RR\su\$zsqth5TgOCU= m7f`$e"kXc5$`+4,{I$UT$TfFKnk5&z~t\,7~89L. XcJP>k8LJ#7'|Ar?|NwƠ"J1IR(X&[1 )5-d,RJѬsZGS)0V'f?|,=lG:"iN'^?<~P+q`Z-eap~n3}0={Ԙ֙Fbn+^޼|&w}1>_p}BE% Q=~}26~a*=41`+j.]U/2nV`!% 1 d\ bJAٯ]|7 1_,֒YWo6?L&(86LC`2R"( @C1%DʤCx|?O/ O^4N*ZX9Tk+]N,846M 8.+U>>w;7w&c8`.#1MSAK]lJ4Źvzdmd|uzvcx,AWʠT/OC-T&B$< FYtzfαO )DPEFAgܺ3/EDP /W11ESO Hir%y 1b(sX >cؔx7Hw{lkP,N@YQDv}c5>YnNe y޼pYVJi*8v}?{>H~g\;t?nlg]>[?n'ݪa.QsAmi@):c,3؁j Y+0c 0Q]/]]]wByWX!KvaWrc/")17$QZoY*? PB${ pF|Ӷ4\c#B`"P9)@ 8 BD0(yBЂ "<Ǖ*j)J ԮٜyHYNiHO%\dQ0g|}Bd%YvưhZUÔ#QJy;窶LӘ| *BJj2ӿZ;\/dB!}LwCm8|eE)!Dr߿)j:)e0O4T SKZ ahb&gsAKMJTAf I pU(Z"DT qNcD0.}|Ux ! &) Srs6zGH֭ʠQUSt9ʮ;<>4:1KUUӺz&v?w{..՟4g?Zy5j+G&` YPIj5TiSs)Q[2vuZrzkWZU0]ﶫM8,/ڝã3 ALj-:'3+o29Hu4S%, R .dR}*sTs >U~~T\GGF𦮫hYە*'I *U9_59`j")p`fj*De $yu^)P&#=r~fǾApWց06U:4MmOnn%SY3˟G;`ׅCz4( B޳CKAfvƪnCquJƤSP󔺝ēi084 $a w|D/ 弲{i0pjr8UPE=`iݣ.#6ݨx{oW Y?ǻQ}Cuf(4yn LcZHjT9 Q%ij5e .MSV5ޥXV-IJK*O|I '폔\UHƺb J5#(BA}Rξ>T%b EH)Z,fMRR5[VSL ,2t̥"9-j IDAT=xd&~PrpޮuӴxDFoRd0)Im|hZu0ag82{aI (T %*5ulE?뺔v[?@39dR=vPRɭO%kx{{h[\d4(dO/Yp'כ4fF0 r~r\lr@$"2"[6*aC4MdC֒wh%0 ]ImʹNJD1@ZfLA3b>>|,m*?Vo_^wgcAj]8Aɢ=ݜ>1 @R7?LFqC7 kSòruSh`Q^)UULwK?v* :_UWQpY]hLcv< ʢj W6vq`\ScMcM7OOjrar-zƫo7u׿zYMTXS*#b0rQP@fk/ñc@va[;UMp(eXzPɰY6mWu"`m^"`Be$r;e]0( "X%;ONw{UMK0X#&~gXTF䘤z8E!S|ٜUUU  )9cΏ]q]^LSS2_D֒1OjqוZrJmFCcc$8vXrV!b2f}?M4Ř@ q)p8 ?~S/Q`Zpsnw4oJ\JGUDzyH,jk (~t;h? |+'cjRu! ,!/YZ&mR^C QPޞWwOK<ſ7tu~q4/u?lN_||yQ7wB6 ׿>?ADirA9Sa eZ4!j,֍t?Kg_}{Zq6#t/j.oC:e-b@ !0l QBA,* *0'캛ϑa_O&>ޅ.K;:82q.qIθ?,&̹B5%T,B 󎾠A[6Iu^ 0DbaY6gM{.Z1.1ė^*Y@L@dN"( l}Zfyа#Y01h$X&x GGQP'`tq81͚t}6d7']H2uUg>K'Z!UƪY骚Rbp5 rYObz/)q;[T?v)Ĵ\o&XLxi~{b]ֻYp/ WUPXV-4K_v}axH^,M;pҧri+C M맒sJd"JvX,gcRfu")UBlR"+=:6 XF%γ2s9Гr6ɱS5r}9, 13C)(ȳ^>C*,x WnX.1ƪ9g zkeFB2 Z 'c QUJd{n"z^9ctGbv!Q}JJ9 D)וյ"| 3bܕRpHyVΜRsFWb;T2*QypX= ASPe4ʒ'%![%cWZ0rLֱ)Y30"yێЏ""!5 rQ`{;4  `'@&Ւa1eWA=#Ꙩ42]|w*k^aU7W&/]uuQ,]8LM `(WZmWgSΐ\_urh'Ƞ\C]A#0 6rU5gHQ|Oݯ_sۼ>e[yg>Ƌo^;V_zؗih% я2'(LA!UPCJ< <]*_BcGC AAIُ1ʨOj!F6xOSɲn2WQw=P$փ) }w,W~N6aKYnTXDHՠ)2j<$`\MSW/Ʊ#g/?X! *h*Dj\??HKk'~uC^Z7^N:f Vc//l2~:˦ZVE B@N1e(UFoCc?SLŹ6vsfszY5T_0?i䓴ݩ[~>2~\?8E8GѺUբm81Z)o]^ $S?rٺ tkWWהٳIi!(vQDUTUU5v2!ƜˢQo 7~ fITa.$e#")6&`YKOD "81JKUd4M?3 7Ӄe)#,߾y}0/EF4>;yb91l̽ΠTHʚryz¾յ -ucvb,eH!Rע`ӡXt7Wo2V4_,Nݧw?TmuuSw|ݶ;se=Z{9;=9t[g_3Ӱ[dP Q `@Yi.GP8'!l`,J s[ʓvUqFOk(JxñjT[yhm$&#ƾiX Q6Ҝ|uhEβqjNT6rUZ@ @ fŠpȏzsar"u3bv_M 7@3@bfpW`&Ae$R ꜝ{ @Y CcTիo. 4iV9ge? 1He  g @P~T@S-STA§>9-4Pđ]TSq2`Fv Y8T tE@j Gʑqm)/Ekl =nSM_HfLa TE!~_\"CÀzsEMDǼ}7i6FK + ׁL5M!M8ps4ܘB9ʮ4^6z1}v)RcҬ/7ˇ\Vџ]?sּjbdί/Bۤno(&<ڵFwÒMsUpnzxyzx{3ſ}UVI/_g|81 c㫺OβݽҀ<Pp9 [YdP%V6KP-%t(Aatsvr˪|baBnӮ\^U˦.&n7eO)݅ݮŲoɶ ->=_U^ͅCipؙ U.˘zZ-txsckjfٞcKG~,U$3&DJ)*ala$BctäE5,O9JB=U"Y'gZWE +ye;׫yo+B b(q,xZ dfLs]9c [DhnR1jUI45բgYUMD 0*jɠ9MAU"*bFYS _5' 1) H8Rh @e**[[W|wǡ/"aX%R` D* Y!P'΍[߂8cӳE1}{sc d%XvaC1\/T TBc B< W>BRIZ$5.LA] @ *R@49# |a=@E5j:޾^T_\_sw˫wsxڳzs?_.sg[Í͹2BNG<Dq,Y866 X3 _[%O(тax<h!S! XuܿYm3 sZvїx|R5 d7/^Nn\/feIL ˌOf'o `v0dhPivdP|Aif:Srn!@Oю3P$!$bOo5*X|dYV8Ca4j*C18r:['hMJmT w)îoJd@$P6@צr]Pj4Bl!kUYA@޼ZOhJӇ,b*Z> tS:2`MZ.,lU;GUK\7H-px7mϴsXd[OrWwnxv `Ji9 !25^[@;S[=aAKbcC@dNE(RKsGyڿH#? $iFW(lTsIa%!P)Jʀ ETEQV%c|,u֭MhsL8 H *:0ΎX9J!"P,sn70+}bVdC,sZK$BʎH%{BH|IrƱc j_ "E!P$CMMsw8@ǑA"2{m102X P }Jz 49¡ڻ2VvJq{Fvw(\4EcJR"zkT2 .폏aL"<BP4318B%HҨ !F27{ocW]s7 $Ԓ[mm OЮjop)P>1xwk~DR?nd`8?hp>Y-_.?ʧX{]ۿÂF^?w8FS}o?GHl1q'j' M{}h`.jҴ9 qJ73s02U5k@C:|ۻi _JpS)5p#r@kuk?\QoVypb{SYWD֊ev?~xR67eJfmȠH92S IDAT|Fcǽ+; *C @ plTf7PPEC-ȣb+ RL*ٴ@1!lMRf? RUrTa3Vl 0 Oqjj/֮ 39_aX˦ nKM_,+g̡*tD/G˵K9ǔl(nGsr<ʟ/G{`h8؄ ( !Ȝ&P9O9fsI׹Hɱ j%ʄ)!:&!5XbDbHE a^5(fVD`@>$@0|1AR"UeHbmQţ{zۛM}% < jevKEZw?J\qU_{D 9K\AŬ)ȆƕM F`,Bb:B!d~Tޟ]ܥI3;N<:4x;n XW>D#TLWMurǑ2!JhQ/ŲA5@U8jR&T{9iz4t]%FESof _!6Ta^: }ۢ7peziAꚸT^-:ci8auvC;wup*ͩDDZpT7!hQ&*`B 0WWM|vu$F1!q͊nm:-7 jԄC.[uW_;+QD ʬމd3 `.bf۹Ecc7Džs߻xSA婤!fGrJ#jz%ĈCkeø…j=D=i%Q_Wͯ0g|Y{M)x ni\ʼq$)g2n b*6{OU 19I]^qyu~|ӈAE揷ƼLo/ϟ;y:DaQx*)>Ø7(է^6]/;695wczmMۑl*$\MecK5`XT S M1X8GE˚d'z4uI&Qa|{V?"%w>I\ )F SД(qXqSYϺpmDV 3lYMө 00ReT"}ކ?yNƾ^b T%xc9qY9 DE M?HdESF{ej4: qrX̐E`.% .{ d\+(aB'.Ez̃g27K1uR }fs9oPb!Bȡ#zcC'Ѡ ]{}U O!TXL! ܶfhwY"DJD=;fU%&17#ʘ>K_$O]L hf `FbCs@63a6m̝Xelжfpӷm\%ITEE,Nsdhh(HZ`)#H6ƾN|L fq6_rђD@h œd`f(7$qbyl?=u5|Lo޼V1߶ͻt^n6z6ZU?±"V-1?ƞDiasn6|nob\Yu}An6W 4EUZ28#A8Me%G n[fǻr5RI96y;/Ѓ0ȟLB(L93M`֎p|p͂1!nSP2`%NeTp>/WkֺbpyG4 y eb<a^<`͸(XJ^hrU;(f* Y. C?d*ÞN!~?nyMZ*lU3lHsk\\e/S""P If7D̾2Թkn#E#4!CENI&"gA"fP3D@’mI=:F=-tАtNk`GLZoAWepLr?HFJJ e3MG@ڻjl6zEM']]KA8Nˢ[MUrcQ#!{&BTegy ͯfU3o.U|yU1!S)ұ3\ڛ˅'U*nya2z8/NQo FòQr,  fI1C߽px nov.|JJL-68Eݳ Zv)|}VwC?:I_0J]_<{쏿|>M"<s/_\"L7\W.O*3 Y-e1Jjp:<*$)(#PqVH:4eY*L,``rFc=Ƌu032p0[4AԀݞ"MiRkW Qւc+'Tڵİ9W$33My)fUr|u: {.Z_c#}C)>ܽb ȸǓU'8X~p8g;A^޵E*;Wc *I>6XMKr0jFDc890E`Rtvgoͫ/ӝ;M^tS|~Qͳ.ߌݱ_`.Px`s>K|ߩ 3`QiX&@ s" `\<=xF(EC88@' Npצ՛: [fH<vR ,Q!NV7 h>g[n*l* /.~ݘ \s!8@ Xa" FE~n={57?as?!`-K{߿GKt9V]ULmx@zK]wwEN)ўh"HM\b"(m>ˋMJ1s 'T1! 8!ӗ߿ן|PE`{ǾeZҦ&uq}]5=+.HߍDZ1BY i7.03Hg0Ȗ Mڋ'Fƙ]?qO8뛋>M\b8ǃZu8U{A=ƌw|5zy% |}ڴnUJip?ۇpźnqiXjozA)|'kL`0=\T40*3csNf+E=|`)^͜*S.]_֫3@Rj+x~<k'̊ 6oC]׫اn @dBUUf֒2!_@fݧ0gO/6Mҟ<'Ƙ3C *BP8&uh3V]< }.N(e,wPs۞$}2 {;#Po @hBjFN0dɨ3!""΁%ZgO!",paU =!d6.PD !MY ;tN@E  |yUy|hb),ӄH<3g|7c?BVPk@@ˬR{?/(Q j8.VœFautW jI$9PPw ӗiں"<9&r2=77 yEUT=ijC? G; &qO0\pznn)E ?OOmVja%7׫pv.C="חᛛj] ?zKU۴բ*nfc"ˢam6Rb̾!8  f|0r윫WTK]N2!/p տ{{bXݼY0@u6l'T55wؓd@ZDp3Qš8{3h@XYԤR o*g!8L/2ԫ TQSQMݗ_} =q8WMŶ ?Z9MΎ%s瘪vFnWK&',TH^l~Oyr?b%_6W?hy:zzmM`.)βRwulv )~"̥d  [s rfŠDIPn/;oVshtYeĀh" dJ*szC~{+_޼٤!|;Wm@T"&'bEBl#oo*,.P%V+,x:Mʴ\݀!džnvvA8nӛWvv yj*ZLA&LJ9nf q AhTLՋzI)%hf0FfrDv~~7׼Xth!0kAuSw]Uz~gx<5}4T+MsBՆUuϋ IDATt&ѴnL ڄ ,m p<Ř jK* b AUrJb ΃$S|,P{nUYɸA7_=VF^ }J3/p~:M+|k|bBB}?sȿ `V5,@PD,\9Bb&Pl/.Ϲ Q;{ԭ`Ɇ(b3cZͷ"3Bb- >ܟ/x]{=j5T1bfcf^`=B#p}-Jwߤ~71A& (0B7_J-d.(-X b/]|b <=^.sijȰ ,`1}⩟-aH6Ʌt1q|zoUUqPz5-f{O `jDAu2,4%6+jL-Ǥ Xspe(xb};OfJ*S~i$T؜ʔǘNys-" $ϧcp՛O0]<瞹 UU99%PĀ] h1$Y,gx8gM6Z7fO]|NagГ_;'9)!3`Rs9 v8j yV]%4zit&*_2עS*eb]Јda`n:"IJ4f,RDόHQ `=r!( '}5b(`jUS[1~?msẰx>nwCb,R~S!OU-Oݎ|€⿷ٯ0gM :/Ū3˦ %K?dnw5Oa:`׵D=>yι1ȵh( ǎDT13D#RΕ̪)9.|=GNPd Q@Y ՟㜌{sŊ>7?d}q&5e.]XFVi;Av\ϾqyхŒ\Z4t[7νZv"!dcW&*5 ;xa1 C0zE 7%@b2#0`BE+@P|S0bS:αˆxwLe~bϿWTgu6K),$#ѹB6ȔfpycX~1@3#P~VB"2p88z Пv kjxhYqwճ/[]٦< %]s}LyT :rƤtqW^FWde*BAsɎ=3W: :liS>pp uQȂJeU>/oqqQ~blbZ4`oKf|b1}m?h=T`g3#Tpw8shKQd ꗦ: ?SVFCXsS A/+=t(plu_A!\`5sTns5 O.wno0VmXó,NEOv),3!zCrd(fWP=@'*4fp0XJ@(:<ˮ!iuWjKq t( W PLч&,Y?y=N:_?Ԍc^DB$;Lô;\iPћl8 F"ڴ2ϵuqHI#*d2[se]4!ǯFYt1WΪ:"Q 8ݰhOŔH]5xh^t WP6ܟ|w0̷w^Rmx`C\A,!g".R&t?pmg >nꋐ# +]k::UJ:=3cRs*DV٬AR׉))9/v4 B"%k,O"MydċK%TDi+bONF*0S=M^sbqn^jN=k\u.D.Ʈk[/˪0_%v<T;oHι3vs~V5S3TC<P+! J 0x V B*HV$AT;sw)TUkEȑ U p:MxzG]RRJUժ\\H&3Rmdu*y% {fF58 .$7ZѡjfO`n ﻁ^j  Ї_Ȩ4"Hכw_/yOcsHr)zj3ry.(2:$L)t N]IGfMND@SYjjA,duCtSNsr?,hF @(~Dx?g=8h W|Gحv'3l/µ|vy|wqء?SB5&ݝ6+sʻiڱ6.R@"DG`j29hRCzڏn{8=(ikM2\)jOqTNs.&EXrXwML1t7Io1kﮮ[G0Nslgq:̗gER+A u0A!9ⷘ3Ƴ: { X6i*- Nbb_nˏ?~M( ,՗m +pbf.oM0m 9QJeVijWbsm8tӡUCZMD`ᗇLqH[sVrCyj`IG4sچ0'W|ȣwdZhbqȣC5uiqn훯=Wg0۳i~7\h/i.56O WŢM&KY3Hqy਼ D9$~W0ʱ̓3Gg#,~o}EKnZ'LSTY`N#0TpJZ^ՋOwqk_ܿ=CB%Ɨ6~z`6iXDttqjk.Z4p,u` 1xףWP`4NFhRa3.`2ֳyBU˥Y]fN˼H0MV{_KQ5D)HZv<9lv) e~s߮cDI Zԧ}?H {usm(T< }ܒ@2zY\PfjKQ YŶӒ4U`5gRm5\4Nl\Xv܂ygϯaDNj˦qޑIS0pMU!9A@**OΛբz@ALi4d2q Jga-O6dn+/.Egj~(ev$YU\PGb%v۩X*WT+;fÜﷻi{jq{<ǟ\ĠNY44**9'@}?4SCsYaff>"H)ZUuXsPkef眪;[!pZȪkq y8!Փ\:٠8zkeɦ]g(Xq R$-٫Eʸ\>x,HOP"vy*MLPcÖrMMU2<{R'{O0{pش?]K}o-|ʥ]?d2yvqS3M9]vqzNpZsq>R,Mgz [zuZw[NjH;+ sł38Gdt&zY*vzAeBpє, e,̄ƩN/psӻjz52L6Fvz-ǷM?JoWm"7m)^~cN!:H__?~ov>EX8R]h;:7]ϻb(ǡJ ^\Q (O'ӿ|,b?LV>zyZmͼ\ IDAT* HX ( !VY #E@!0rU6gsꣿAGC}{<{6:ڢZI fN+\H A!1F)f{}+8A{,v/"1vfػy%FQSaP,ΛYTa(- :3V(8 fbt@@AL"&)"t" 1YE x:"ǩ>"<^ƆEw}{l*#]Qh4W3Ix8'kR 23焱nbB1D, 6M,ݾ&@]^4|W_ԡS`>ӌ!82qwXnC\,~Wu[VMN7WM%2Q2zpwW5iub\9 s˳6mw}\7WW³epHG#N-[ 8N0\1כj܋ƭ/O%`6:Z'5yk9؜mQ1?$EZeJ7]Tq.\lj㑏*"")q*ywQcLªECsDŤOO3e+gʰ=DFNFgoÂzcziC 83XMfʹzr)͵ RHmJW6 Y@є:CStdBEÝ\gb`U9}V2R sUc#&XB! Xj]L4n-7i j*ШB mV4lihUqK)xQ?47 K5T>G9s/xq*n0.d z}w fu 욶J<\ /pwY£ԑ+6UiClpJۘ`(mSqa|Uɼ0#V#s(VSh@dTILTO_UڡMdR]E>ZL:ۻ?Z_P4sdf cOW6QΜIL͏~Ͳw8?uW7/0_"X9~\,RǸ\ vU~y;cg]~OJ=қõ C΃%3Q52Dob t4FŲc"gF ]ЪFb MYJ-ha7_o5~ϑGfG}'V]M7%5nRiKHU4MӔCju \MӘ *lv;& Liߛ~Mg:uA»|ŧN?>t\LuPwK]>M |_a}wkXǯ~ ֹN>˷Z\WϚO~;0_w"֩MZCUT=bׂe$3COQ0C:!lyP |FeS s8! @@D |UٷOE R1:)UO^/oWa>\/} 3fu$ AY!0yu n7ƁUØ"_߬ધTmѤnqLeӏ8 #CUjN .Kq3V}.Iт)2Ob1s@N )IP [aJ6lũZ"8+;rbllc' ~@[3a[lsSd}XEЮC-JHz~xt/e|`iA{{3̓"~o@p SFbj"zhU Z0^\~vǗ 6f"BZCI*w/7xn';4٩8 ]ۘ;L XbY=alXO!FjS-"f ""fE Z˶JjvBɅUNz$4˦QR,PI{/3aPO%rY@#5S)<שr0BuW^%C맷KZ8i2sT.ba<(-0W7KџS^_(y_<*Y]<:Mx(\nw>uۺUU!)i1F#;VLdO<زI & fhJg,130y!+Sd5={6i\T8yfix^\{##Wݨ:k},u<{ G|0ey.&5>. [S`J~殹ei//r?? ~&U Lz7hMm\Y?x9`ӧ4u`Hy_|tyql/yO$DgVB Ml=׺:Rh>F 8cE%uo_T6 ,S-|]?γ,y}~խ 9 WMʿzZ3ؼ0 ̀>-~Z/T,8g`ba~HMITT,]Rdƪ4jUܕ:M:]tB֙9Q?#tF{E (h44{P͑eh)68|V)3#,ͻ27=`'fBQsz6*Nu>vwp:cnu"lYyQ7fw0#9h3q4\="C`f |#@ﺵK@MLjE" 1\2Ì\xf#C"0SgXaa>Gl>_CaߏxEhu';.qu id*YlOoa8RjđƩjͻ<)Q yŹ@^Hpj/=,qSV#&9}͠H$Jg/"* U f#dTfUdlNc `V`^n{Q?mmbt,#@9iXab(z*F`ɩh-E@+,s)r#piq*2E=ldl\"W(fj U3cbrɷi15_,VawFqS \u j)ܴ|Z[KX@.~P1BЬ6i~ՋEVE첈wQ*4`hR `QI@+8@=|BU ɈL|€OBBP0Zg>Ú !z[r syoSU R3"HMZVUd*g#ɦa̽| -4ȿBܨKq&]h+?% RaIiTf3[PQrތXjBT,Ȣ)4yf:[#znpgAOP0dC'@ 0z03j8"`2b0 ؅Χֈ5vE HMw}WQPv84 Mcݲx_>{®i;ix{qYy]PpjFj`S;dH405;v]-˲$7-a?{?,tWYxbǘ 005s"))B(gf LӆT̀ < :uk1G1I~S"@$+;bf0QS$ѫU8kE0Q!dv2[o.˧WwߌC:Gm_A<ߟwZ+-/_י!\]]vt~\6T *81@lux`h%[.&qh.xę@AB )'wݻ_XqӋLMJ1BaԄ޹uyZRsk-Q )l`Nc6yo4|}*>SkW> :8ͫؔiz8=N'527.6Ŭ6aw8R 1w'M~ݿ*Ⲋ;Q< SRX:kLj FEP@P KGsک9W, %xPz:,ۻB32.}!xb:@gqXTnx{{qWOo}XRSH^~㮟OCzs\>reuFkKUw "C>fN+5u_/i7-~F#,ev`s}Z$ML.kq^]_r:?F9שH%O:8wz5j| q>i][Ŷa+Q(lɸZR`b3+;%SO8+"X鰀I+jntEݩm7 ts4P¾kW+d@Y IDATYrCsok)"MG4wܵtZ,MJ@He8r\/j_|ZkA!'Qt>`AS#vi)-cP뫋zMM]8NEPLbӭVmYBSԳ0BeA`lf`&K{W5E2B"rgvr(3yp0ɐ\b` ,bd@ CZzw}q^uJdhdK:vQszs^m=(O3'y( Yh),"scA' M\]]i:N??> WDwoE`yUԂ8BvS) !h )1 LuC;O>OaBU̳ZGLyY0MssXnPrVO A )A=d)/`Ui~WvӴQh@=EzkTq\i~~<   NPΜ (9W(`.:/7mhdi{/5d'U7  |خ?^7`⫦K.T-Vҽ̄Qȼ2'J(ˁefRtt`Rз^Fv2O<c]X2%Ɏ%6'R1-n=L9dp32auVG̣ =%GL#P|!X*Hot4^}n!㉜8vqWș eaUPT$&uk,>yR jYsJ FLvd]^ql*d Db7<.)%8 "6"A\ 2raU9WW(yrx4fN ]'檅]iPRN˺u7Wg+[gj gN%G,ଉm9#7rv)̦c~rĮ b)~7|/J?b#t|`mIPrZٽ܃/7_(A]GߘHҵcef\+Wyb:*%)M1߿5b݁9dB"bCˈjg DCdޱ {ʊ63*_\Ydl#j٠C 2DDBeP>x#?3 Lʳ'p[(#m7MLEBBKb!lPԀjFP E+Cb(J{6Z<j9!ːhA6,pprtWnlr.ɤ* iy.\«Wo础s\l+r:G8Clyi9}~tDB49LjWd7gjiY #s.s1E02drv((?Ehh?pDo$=>cǦ)i08Ew}-n7) v||xJc<081VTk__xGsPTu\[{(,7FMgI##ze|tXuv8LT9U͐1V83s`RT`S($DT@EXEzƛGxڦ 8v1[ 02$eh۾EI8M8%gҚ]lzY۬-zC.n>7u}# ,K#Ϻt|{7U_ CU 995(D-1zL/.Ö6QALPU8qMόn\\ezm1>C:MMcEDTۘb 7/gO+[=6ɒG zt .U\Nu('sIL At!Ñެk)Y7,ʜn7q6MضmܧMW}n>xs ߭ڷ-8k׫['i껦$m4M1TIIbDdU9߯c*^^Sq_f+6Ji^50*J:P~ݘ]ɖp΢ i-~5r{ݫΡc۫޽}JKCL# j^N;樐*ua<i);f͈Ux3,2+TM.'*y>yo?CZ۶1Rooos*ČĦHx_ضjEIH Q#`Mha T4R}-IF9or >;)u/Ђ[h k&>y(t2QYsIQHhf TM̡!"R(jmKǯǴʫ7ľE3b*L@J9ҹjDTs>U])2V8/l )l/2OkrY+`Zg#^ws9E EPq b U?:3I(I'?kq>QN?GnT iYo. v[O_]C]rZM44tlШjP+("{ O6.M%g$ U35B`F*L9QZդ(%jyIddm;/xJgj@\Y9"yy} >8pˏi"0#eh/ݴvaiHM%W4hC\uV# 03U 1Tt/^nmaw`rk@prR3\ "U5?{4$5 d|&XE49?Äk/%7ٽ+v.Wnx~\Y6ױӦ]b'N9fhi\Nw 9[GpLUb;Z6&Uyӌ2(f% ΪA,q`g1\zZ_8 (XeP293m2C.pHxRy+6@K{4O*w/~;}.!wc~V/UWz/10$F%u  #cp!j&IKhȠZ>2d434`bPL`DrdA1=[\ys`}mva!n G2n(כ J!6  dPK=%k"ޠTT$3r#0.3'n^BwAOgOMv>u`JmbVyTp%!*0 u,%A=ky/_61jz]l8iv׻>/-rj۵ & Hl"0嚥BK ReVt؆ne]^U[Yr:s:{ªE G@Rm4$ϓ{c-Vfgרy%ʢP -jDjbfflrKJD)90Q*ɷ񪔰ۗmi#-uդQWiTDzFbS6!]$K'cf E ͐-{LeEtZl7/aڟ%%evE9eqai٣4{ʎkQ$2>f= ѐ HUjsk"C\V0Ӝ><NA>UBr.I14me9f\fD .'lDZ(UuZVvVr}lgmzTs5'dE=I30" t23#ٵh^@ȀOg,] IDATc,] B{Iϰ)s!4|y9/;M~us /o&.ngWޝ~2d~U^>?̋??^ξ/ K]JK>y%USr8qEߗQHY#s)Rr@gʶhy|hd2M!D(kNbjM7k{ط]L(Cf g=c-YA'1DmxTJyUkjfPr˜3 hUXoZWo͓}?y *ӌr&Bli :fT!s$?e 8{11@"Q_rt\^k}iSr?&A9"bԤ@ bH($h*朏{*Z#*( !);c"HX V1B́!rN)Vk2ŇBP͡8nn.49#Tr8j$FD_D##2U0D,9*IsݾITnx+0oZ:vTpH[﷗ (UCIì#4 u &^ɰh) Z^Psk5l7nt~)Շj ^pO/^m᣶;<ܒ8 (LUBc@R-b 2QS c1xr.˔ӱH-MXѳ.*di$o 62/y݈ё@jRC&@@L@xG`"VV@EǃTLR**@(*$ e1n4׺4[藒{' cU[h9I>M(j 1[6Pw,`hjP T1V)0vBOi̵dSYd1'܊ 8%1<cY6QRLbєEر330ExF`x'?l"{͒T5BfbbvLaKmM>Lc5[(2R϶ĀTeӴݺugz=2ժFZkpaڐluq~8ӒrUYk"iN˫]jB9ץvH)xP洜N'0"smb: cU%sx! h.FGTð9"cV1ZUе9ۖ\FKuɖiP*srfeqCB 4y,Mɓd[rCU^nMhFB 'V DE ~WU9Fč;ݵFCdSڶ; Kq>]v< 1\ѡkrZRèz@ZLu6@}TR4TҸnO9?߷6?&Nw>"j^D`D8nchLcܾX򉤈hL&Pt׍s~8O׭]p =4SM]u2a}2w!xѪ{zj@E2̧u..=RK@8n Z9֥Bc*߽zK9pQ8Ow>)%B%Qi;_x s& 9`DGP*hQ35SgȈj,&@NkkVLuItb7ƇhLM+J%6 Ff|FD10Ws>ǮĶ ȵ`}Ex0)uU 2eb *lV̌ZFf?E+ r2\7sORAq 4"%oyVnyZvG)(WH$ .ݧ FS";;ssؚ6)j\-ͦV6\$Ū!!CZBB!8B#&;bd"g{8,TnW}>2@N;+4py֮zHZr,9 =#S0= UEdftT!g!!:eD# +ɪZC`=W;B:t69iv*ƗiynZ~ZyAQTF9dtZg_E !HUYY@cdA~?WM1)} EC j*뫩UxL%V]O{|FW  yʿDST Ũ"<>=OzauJb *Hh$x۳fs﮻v^8T;cAmi8nYr-rb2/&/n%; t\TlVvI5tv m Pp4jKV0w6nf~:8Paf;iw^DIZN +Ȟ9zb|t36%|.԰P@@4C ]'lf: V <>'ay"жqn_~17g!٪,\z.nhv4yu㺢Ю"Lju0@A "PߴSgڕıe ߖ(˘)Bi pAa7lK@sLxW#64R$j$`Q @@~:h ((LvÌdaX9C%iTClF0ְq)ݼ /.BI @=, H{_ TNDɊ7Cd%E̓sZ+!")T)LvBʨ 4C$v(ț*2th*υ=Ǒm"!SJ^eCuMA_T*Uani_fMݥ*b)f\o0\Aj5fh&l(`lRA`o?SӺf?{n秃@"ZIi5_$o~åyC'}z\/7/7! t7eōݏIewQ,1<8>۩`o;lK#2\כ c5 gvK@9>F!4L$3sHQPuT̋:0)MegOcf䤣D:U|J.i!Аi'Mų.@LйܻveGy(V6;Ae8Dzěc I~|N<[DeegrvyZݺ' suҽ1Շ>_~aׯ.R>&˻aK_}շҒxR+N S^߼!-q_xGe>9@XIR6Ѳ ү vwo{\[uE盶_?qi W˳mfDO~D@@VȦȈ !)j5#cjPsU<TEbƇh2|ږɡd-VTx}]ʷi^nf8r5Z-6-ECӍ#]ڒh:*<̬,9 jFɭHX>>^|P9~1i\Sh&IC0 l^6>sLD@N^@HhjpRqTƔ9MKs.S;!W4Ui)v!i>FJLD\Bjq7/b!D"pcJ CSTBӤdH##t%>9䇧].б<+9/%9Mۅ"!T(*J]9JCt盫6IibO>lp %aH)\{g2 |md߶eaW}iTX:H4˲达_Ցon1r}SA$zyW,<0$u- AUͥEߵEIn)0֢ZAEl(tʾ(VUS #d ПO* ?Mt?i4ix2QA๙f#pX Aɞ @P`Aػʾ,w.n;}\?>ÒgWWmU{V/@~9Gb^_yqWd ML~ZVYR0H]x/?!i '3P.2ER_bovg@YdU},EKVVYm??̰o?+ϜS XA4#4Qk.?OZ]W6oځyjns jEi]f/ ,-n/)Uh"Wb$EOs} jƖEVcTh@}@#.Vǚpn|ۗ֙tW_%d x bHAM0n k׌o9w/dn_y\l_ώOW(G<`tqZT|G ij5PҹA9 jjxn TTjj(\+:#=A&Xx$X쟲$n)|ӯ懶aELJa=ngzs54s]65˞T\% w/^:!XղГgc56U Фea fzLԁAJ06f=Fx؍O `: i>0J*)%EPfPK:Ι |lz`#RrRX s` AIC0&fS4C1&uw8jB㛦vq#t`3)qw 0RC$.FG1ZqRj@@djp)K]um۶U~<<yY#29D#""* ")ҴD&RQC`4&BTnxqqv~%3+Li)U.n^ɇM׾x³R0M UaHAk+חLʰ`hV.V,{Cj>뚳/aXi`rTu,Z++Fvw hU@D}0{,e^vN&`A- z,`fUDjQv䐸M?~߾Оc`7b jdxJ!Bt"(2@x+X@0xBbe\74 ןUo7rN_7Cm<͟}޼l`s!5X.*:VSz Dܦ.[>Dl #y9no"FB(^9W<N]-gE1%!ڲǼrrL'gJ5]%'97 )i\ܬW?˕Zb܍*ap?'@039n|-[ޢsw!t ύR ET' ZԢ+Y׻[u-W՟bs1EfGfL( čm cz?'heWWX5.ȟ~2}r}u꼮F=LX-ӼG_aĪ ,/)1 EudEA OpbU@$L6R$Ɗ'! bZg0 ([5,Yӻ·WDV9<n޷VJ8,%g;N R#qfY< Nz*U4 @/02{R-pm~Nզ E8bMݶV۰*n?s6ų?7ה䏮 ̯m_ӛUv(axH۳iLM@\߽RqL̢ IDAT!/^Ĭ+3IsٲӔjΏZMp-Jl 5k㐩i/o.O{slލ.?iZNhm{~z^MCUO!0UUR>I>фH,l1dϧ6CJ UMRZenupqS'm"x ZTѡ4jAo^\>LDŽkKSIFۦ_+szšjUrѪUF"$PT1"r~Q?|Psz\̌ jӱ(j.8 S5ybH/"ݏH @u>eNg"tX͛78% :wB!rR) Jp-0󉸠W=9x386@tZ^|x +"fJReVFi &]yr5,#*Zeޅici^]Vd5>C@H?A? @"* f@  ulfHi_ ƿ>כWj=鐆*)ɾ~Ջ_z!0O@ ٻE2zvxE0buijy(XM!B8c!Uzh"2Md@q JA#uۢbRR)` I[U$f}lzC="M3z=j) #xg(%ivyH7u_!ݷO'_ 1.J(Ȫ\ 9Ec}sos; |C! Tɤf఺2]oC9ͪv>(Y)@?Ϫ Fdhq__?"޲.^mљ&HnwjVWMئV! 6Ȑn_lxE$d 9/ւcv%I4ma_LGMV Q\ISb-VcTPS&$t@3Ts!͠@ՠ(CwtCG ߥ݋x5R~{DY%e^I{yB{jmI! *C災!+愈cpQDj MYK/K.u9xq͹*]\ eZC1[~xݮ7bx2?+뼸O(GݡUsשk׳Ԇ媃p+xl^^[v٥LQEsQ৯Vf/>1zP4l5U!"@f*V)zO"R{PEGRK| h|N)b M k6Np a(yV׶iۜH9BTVSv~yF:Tū Y sx}9Su3"1Sd3Lλ+NL@BDH DTG3@2'P ،AF[z\2QVߏBoYS썢"5k9Z;٫=ۇbXNI;9\R)/oۮi/CZ0v)pݷ<\sn XXpqq*onz6Bq9sd ,^ ݬϪ;W[GXcSW-{qUe˛կ NcŔdejowqq(S✻AX~{9_Sm; !B<Ĺvwv0ٜϿZ[v3Os}ѳ"7M@}E $ 3Zd@Ŭ#|XLN B3pPQE۶cf؝ڶjHUp4>>"U׌3>N|JCjjEЮAι.Ml|h|SMn؋crz|EVd &BEs .ru!Ui "f%P@U& &%rs+oߖ'B(u򍩃1\[N-[Ȱ !2rjwT۞?|8eYgD9>=uē1 \zf̀ `u)wЄlT;?⋿?ph^ƹ@AV.[kG K9`nXF$)B)"u׿x kj%D EY@.!<3b%U*ECg "HFc&Ov#CEFY1W+]hYjxjuQȜl˛Ç'?I @=35Io6ݯ./n7vV )>+rZAHP!U3ny963Qֈw?TM{!PUbSmݪġS~ep5ƶzoՀWFPDTtRB%3s [dxz?e" WT@'W[R@(DF-ðW?a.l:W*kRt$*&d7xqyʙ L 9Faru|o%K]f˺V/9Ja>znO픿|,b|c5g~+wN>q6glo4C3+9 WMuC!k5UVFwMX|%\ZiXk7avǃ}T[>Rbep? 'Z!ETTӲ}kMt eacǧ|;=&Dyl4%<Òv#GQ^*6Li.dslHPkFEj;R >R%\)ёC:,Uv鐼 ߖǺ=9~CMDQ% mɆn)* 9L{?ܬjv K~0p3̼i Ŗ@L$k*Xf+ Df 'ozZkx_<r/1g $ѳDđE9G*2W땖ݝs< "m0UEDЏz?gb]MU꺪jgSL) `5S|H7NqLIP|39s<А) n`9[nύ(80; A&H$/8 ='5\H8;_>AhC`D /FlL2֒;k 猠x1gŜ5iC΂ƛ)g RVUU%"zq3(Zg<_7K= 0uRBB69+q7,ïټ?##LȪPQY'L@;!%h̔:Fr3[84 V1pʒ|UUFUKST kA\_ΟT3Jՠ'8X0FT'jev&AΊ# `rUT.;t.:J LA͜-qV=guU`#/]d )pqP $,FCĪN6|s=~\o#H 2'bo-#cNyqu}yu1,k^ j#J*!hg(8+WLJʛ+n>Ykb 8|}GCF$32D%ۮYoU~sA9DkE;Ni>T.z2|7T3͟S.֟hH$$ < ZRZFV ˨LJ! xLhg1[-0ZkCVJ(1x )L69{L ekHHxF -F/v~XLɢFHc @TYσ+ b@&F4$`#DVddlLaC1/VI#lY0k >4h=4h/fyK 'LlTB@E0g DIٝtqy}Jp<bPKyV`UKo[tH$R1wS]ݢHpvr'a6!<)p' fW)jJ"BcNvr-%}wbSZ `7_S;M=wwwCcmaB,A6կ  saL!ɔxs! B^/[ŗݫ* b1k9s?C"mge9f "L79ՐrI[2\lVUQB0,13ΥCJi01oܢ8[o $g"3fv1֮:K<:a(U)CYyIYoZ}NWr~w8 hnWx`1N1 GP;/> N -NdM'JIL4żn_h$J/ +Z@@? TEU؏W~-ՕA &Ĕ<wwa \\6tTy]Wn8p@%P*J@% VU4oxz$JCOq9yx*+ ynH䶁1 WE<.D@F YňAEz晥g,I 쟪?* V4F^O(XEF"VЂuu(~no*e@LUeQQ9"8k$2D1QVcEh3 zZc?)ܢۖ)[F%͔3 4&gRA`DJDXVF+&G zc8M TlCNc8d}BphMMv:mA%PTD f&,z1x箝0̯/׆4򶰇HشC?Xu a_nZ8b>_~-}T[* ؘSg!6i/~0Z ɺYWU-|**+$3MBΚj!} @ H^ˆwE*"HETl>[M1r0HKdRN JƂJ]qS.[[63k-3蠃6s>JĨlr]fS? o2ؐeRYrYØap98N1zT3Lc؂% 9Q XX{r-5OCh|{qEQ{$gu EB)dNc'B?;?ԀEP_*@2qOE*pOw{X/fk{ArS3oNWSVj BK.oNBKTG@VI `UYiY!3@&={yJd TNn~su=ͲXhd$UB1'Z * J}j9DV,Yk %pNHSȚ ݾ]73`y[Ə"%paAT  &CPpƵ #4ګ"l~G\tHE\FB̪cJyaWM5k4hFT;fF1Z_^3ޕ1EvdFc`$3j~U'Q*}.}<}1v_z5:iF 90i`rH1i*[0)(268yrHwhSn4?[ u 9W..XWitD\=f0r1[L X̷]bY$'\8\|fRNOms<%y;A_1t:c, ä*D`PU8"4،L <ДP+\4>y*i)L$~6"bQe 3U( Kv=np,6eYc@YQr )f>˹?ߧD9T4hɊ'WX_nQv.,?:Egt @rF ?o@cpĊIH "(I(YX12YC~m/6x0tE]Ԏ BRT rC9/1EQ 2 BnSn<|^ovY%i |<lT&Pgm o0vݏ/Bd 5T%@FJ4 hĸViD/ӔVG" J^|`@(U9Bj@|KHw*];hOݡ)f8uqʶ-a:=&Υ%W%gT(g2 x'FȬ1=P"8glU Y+JMQTpTsHeNXA'lsFf0T*JB8Ы-&4DSb Me?8 jDj4 1Y*L"Am4F!Jl\S`ׇO\{qwq׳1dbjĮ#C:\aXҖ39HW_la:;b**41ؔ]i?i ޗ+n9Ო3~1ei%C>:i<7Y7WBIű50/wZڿyusH8ެr5[ϳțtP7r~i{C>mҼWnYۺTrb%ulF1l pRpm?Rf*%m>1ĉJ d0rzIg91KZ/)LeQQ%j}z z]|hSW7{acpqusnIU6r1?NaF7M pFQE4V&e1HZF̒ @HQ%DJ3#"C3DTQ axqG"Bk+&)F-ŏQ *E-9㫦9GT (~ZW@Lֶu]%a1b]M;CX%ȬC7ASHQp,In ͼqX3PHr攳1 Cf=Wb8bfSYoqJjvmҗ-#hfV=:Uҗu2BELg^_,C}fsoK)Dv4WUs?h]ՈqsqyvN`/E(1MƔdHaħ詜mmmvm9.j㸝cbr~Uff=>}BP:cXX#UU`)03NJ30TCSQ\9ad\17ɖx90ӟѡ8A]Ѕ vcAd)b}`MHթ:~^B c(__7^JD@2|w]?d/J1RL@R(0$0|ep,O [|vGdZΙ,< Yt׭)"ʙ'%Is\pfxiR>ܶt{1)x U Vd&aCՃXBVيQLfL|Zf͛eL=%n %˸~lr0F3f@vxX^ͪO/ }MMQd5$ T0X&`$+X*7b9ST]Wy7@1#&UÀf/se^Myq8~: \-چlH=1#ʖLwMS5٢H9)_E 13D :Y[Le9Jr B""mAD/-sHтDD-1,bSQ#1$""XϰNQ@`Y*7=KF?scQs K *!̚308c?xjd9Z Xz㈈:C y9k7ǜ)0Ru1&WcbH䭂,\o/K1ViAf*&ZCoF``NݢA$: "PED@UfU_:\-K3[qV鸨uiBUj)ǡ?y"o $H~j~: x| sŃgS;2nǹ\ySE6KZ]ûfɮh]f<w7bΐܳΟ$F[WZC0,Zg,Y9!L1Pw Ƣ)d̪bhovKS}q 4eE)><>l}y۝VO^o B.O6?3b2aTͲ}zM,S=Lp02fb]%֬N Zhw?.NOOS4k7q;צ7˺]U %+rEG<~峞9|%nxx6+Txj1?n^n 1 Q2-=K,l-Tͽ==MC ]?omR⋋;+ض-bY7ǻ`ɮe0dh Ο._C@/[PR1*EdXicnt̬n' 96,uwa:2n?/uDiLiO,B[ ) ESE5X7$1I`rX$Nhsh=XF Jf E,1@+˿y?޿ Z,*&X1VxUbho2?Hǘx~,K&G1RIƄ[MMfSb;֬>N}Ǒ#5BB&{ȓ68znBeGh=NBya@S(oQ@tBOlLm?ӨJlGQ B4 HΦUA./a_eo*.WEbǻ1E}R RTY .WgGI^ !ߥ׷׋mc)PvY_c8*Y. j|PUt/||QfE R@*s` E5UPD#hv)0蘳 XCPC؎Q3*>6p[!$NDXL2 jΑP/빱PX֥8ۛ7bX>!˻ݷx3ib}L4*Gg*vޔu?)"YaܞN9I !eP!zfv~7ٛ˶ Y}u7=i¢_j簬5B,fEU1KGQPT2(bk$"g@N"a իe9DP)!x'Ek`SSfF KQŨsR9Ϛ~X}8\AciZW7ua ̶ cMy4Usly~q骺/vڼs.v !DYBayu; # kD4(tJkT b-Ÿ@QL*D1Nw-juDˮlYmC@׬n5 U@=x 4{t !%1@@%h0P<\US]FX>3M+2Cƭkw~KN]0s4C"Z9Ŧ*,j,xPz.ڇ~z 鈆}QKqͭA>އ+CN B44I-:XI"s8ɲYJT9x HSSy4B諲a2@kۥ_}r&*d60":UN 'W3J$¢.Ni,{ʶ%g~viիbl-jh?Zc M-培ش{"BjH ,'d"7rW~^psZ4%O֦S܍k+GmǸ!}Rz:54RNQ IDAT*͍Z綿)eImh=GYYsvf\77[QNc}3J)>GS$zݽnJ;} 1$)|u|]s+߁q^om-lT)K㋛x*X[d~q .;+j#! eI 8t4uάTR,B%97Nt8(clbV"Z㔵b\z}Ig_lȤ*,##&isk*,"8XaBKP̽5˦ig; `qDKM͂+m&6d ( ;j|{ݖuf]Soz*G8QoXdJ y`,!&p]z \bNJmHm9\(è@"@0Z2d@U䲼yf#ɰk&0=E/Z@`1`_PDT7t۶azbs88R,QF ВU*Šz iAHj$hO y<=T3ݠ[ɉ%Când9p8sXFEAUU$D"`1VE)O 0Ntf(-qaoaBE.EsZ .U! ˎ.*5B2$ AL==viqj75S}8}x=To q8llUTrr]t"`}lJYlͰ۳Vf*G[W$@`? KkՋ?gO>i-FUaWqTj*媳etiy\^-Л|8zX"ǔ ju,M6Mkv<},y]Cp$LEp$tVɊ5bBR%4AH,1:1(;4e!)x0/_ct>Du|JaNf2;ml-v JĦuǧSLfva,WݧzK(1^\&0Hw_-'ݧp?U_. <~sAo鱼4k)(Kݧt[ F$'iܢ[Wo9Էno߿Vz5DEn'J\?ӁWaw,InX֝w_-yix BŶqQZY5@s,p9"p6hVKj(xQYV0剋((#x\zُG(Ә9!xk ZM!0@bN3*Х̒ȡѪ h82jY2*SvOtoȩZdCFaPvTTEj =27Αy*Oܹ>4]t VI)j["jUUkEHUyP`1͢s1޽]EP3\蒺 _{U=4dQ+*Va! ODrI LS"*"Y…QD2_,D_Ua1U%蝳`o}R YK29Vp5M`L<xz}4\ۮ1543ylf0?>)* /(h"@BB.BpYB01ds\>^'[4Zk~7 sH@T@D_PU :Tek4u]\Pqھxؗx`%mX.f~>8 c 2qB(82ϕO?_^?2=<<Ͷ4n /n~]xpq:Ɂ;ܾe܍u;5C8>] 4E|:d߉¸KUv}Ċ ꈥ(EP  Cqx4Mg{hkpl@ݻa>?moݰO#mml~.ծTMEϯy?C w=<~/4Zv{[u6jKVHi;Q|Q~>M%!%|\nf;SRO1<= obRuVX#0vjgɡV 5?Ă$A* @FS*2CX],Q&xI/x6}GC_9x[k*(H@ 8O 3QDZoE;O9k u67ҙ)VCr%9Jo_(Mgp,s)lĩ*Bp 66Q!5( 2"[`D^JO3N>ޟN:.l*+7:}w}ݑRu;\O`@ Mg/R9䵲dv4en/t?ϥ>L \@T՛eX;>XPJWNu9 뷛dw=ޜ;KU2Ɯ\[Ø7+Cv?va-#(VfP5DPvTU#|Wn ~ʉbcGudCdM{Skp8/wFy?.\.EјFKjeK(8ݢztNRXEA}c9`4,D@e7~fOwNSevZ/Vx·\@ x P*9ϵV M Cf{iiѷquV<|+Y}/yu;84r{SywL=s}35׬uʕwd,|$Zcpב|S%PEID"k@P @ v515; +"WN`~txC~~߹U%7rzWWכtC|/Ofw*i޷ o>?Z%M7:F}Zr΄M3w?~8UbQ1V;WG.7e2yzoJxܸȽ#UPu o׋[^TIXvBEA A-o-^z:.WmǛ?sP7 $"JXI V#d.uP(\ce߷wm_l}߶wƤܴ*t?uެVK @u5XK!N T! * P, R@E"P2Y%i{ $`/[ӯ˾z,#iÉ֓RѢ2syrcVTME \ZE}|NlBiZлԚh =s~{;6+t[A0F~ߖOqGi%N 8xhs $Ji4V;De\A|S&$4K|,i0)ÐaK80j?}vSfoe+n.Ol9'}:b)_:6ę-ݲe]GXJErR C*(+*e8mBT(̞ * E9{N?]Fvv VDqwݤ[yN9GXsd(!Muw"c emZ%\V?`kkӜ+~{H8`׸itE WΕI d60'+P7[rnǜz1m=3#88Qs,s,NAR],yBcY -*Uˏ!^:*:cV Ћ3{߶NSD*76>t/^^q{k%25liZ:tx:K8n_};>1Əb>YLʾUAX-79M"K:רX] L檜@j< O"f&uGg}kcţ^U<51lXRStTAC OǟO 8#љS_qz+*>2Vwߍ=N6w.~OOnŁ=p_4`d q>wh~O8ewͦ~$S\mMN*Nm1p1MY+c(xFa86޼\:ֿ׊=P\'@HP) n6P"g^Y1"z\ EI~#g.GPD:1k!Ҋp#b([FYZ QbZ-RaI5 z 2b6yMY mQg9MFU?~>F%k8M6o=Ԥz ,L@!c$UQbVeEaE#L*AU 3Q]ءu',V4@K=&8h$Q%t`)(LdξTO3k}مR:⚄+0(oon<ߊRGuiLc8Fߘ)-zl}c!P-)g,90QT$x3NIEsIUTVU+9kbzszյ%]av9vCyGYJU8O ,s̪C*<qZT#EMrDiN:@Ff + !h BkQ (_ >!kL͋륥Lbb݄4Z:0N<j84$bYVa wTAi^IC΄ zτ֤.Ur;9UYTTkRU< _t ۰n֧]ݮ?o߼1!ƻk!"qxvoM[:*1k%uMZ:t7<)Xe.c%i.zٟ] q~7cq/U(ᥘ1][dЄN@/)"$v߫>ĒyӇbp\͆B$μ5)XQP%LJ8RG8PbˍeADPTcgM65@Q|ηWʼn^mW]>9V6$CgIlʅT-9L*x`(T*R"hDA-|X,JQyFiǖCjP(y}wZvprp"BT*d͋EX4s3OVm ]Kx5gCxz:oOi:E8KUGCpUVvXˡ]ϧM՚JX1E}Q ] 2& +r2,)S]abh J2Z{sf9c%UbdN@κpsN߼uU%{)E^i.8z>E!W/yi|u\/"7ͧOnm U3~Әj&Da@k&Cq W8幨EW2.+rNGWAAt0/*̐Eb.vrէe@"@(U-ƙj/e?ZĘS̥RK,ぬѦm[.Wk\qXw1tjNj6~<9?=*<<ܽM˥̱VS̮ U8NɵDƩ4%$k(,x(3UQTE @b,9Wn8e~c=MrΉCR* FDT!DUQK,%P  "!03_-’!,fL9\mn] IDAT~w"t岢w.xfAU pC+(b"` O\:4&66z<^iOҶۗof9lV&xPV-f4zcr5kMK9ky⸺~27M3jI® 8dpNC j)|/'"XB]:KJ,RYڟ-,iq|&z8| Kf6EPA A(J$ԣZֆ@E)ÞX=ЅQ ЗB 8YZ2Ka>%hUZyitQɰmA@(IqM1ŏt*mChn0쵈@b13kD cI(IL /a?*j !(^nWa`,eoWCq,М 5jخ^x:̚љ7o T};T,4McSIjL;C167P3GfoB?|~)3XksLT+:5Xk239x0Tֺ)U!d6IcQ/Ccْ󔘵YЯq2!D1פt?b}{|~* U0ηzqu[-@XIIJWaq.Mx8dFBHg כ􋬄덪rZ(*,!(KQ!@@D @Lj QI暧"g qEr]8y誉uoa5rhIT16^VzR$]4]҄XDT]Ӵ,S)[kMX&j+ T* ae(iU\Vm@LCSE4J`Ir,yC9yAq;z<18;ɂ8ԭYUVB-"\UPU/.PK!$%$"Ŝ4C-iL^Ո@*…U+r!!"$/z/@Ud΅E@cS,Blya4m Hm7!Zx<{E"㘧3nNx>+3UF$ӰOqΈ (T$RP`P ̪ywFo߮כP\?"(猢]%D.ʊE PaasPsm̰^7wh[ӐqdAԚ5$֫8OfS,r5)x D }jԱέFKxS7}?MoVvu\wغEL҄nC١y#T}-J r9ޅj?:N MFHBV gCon5gڼ3dHqi]IPM% r(YV.cFciw .)Nw=%e#J0qk~ht[[&#պslSpf;alG4ofTе.EMb׵> -Ƒ.*8G"e[E/'NZD@Ha _YBڄ8;Ez<\׸ĤsbphERKe1DS1jhŶPTB_mgU'SNIPh2`=by:XA 40TTd/W̵(f4T&k!y 8dS aEp$) QmI)ǽo8z |Y=t߷Úl ee5c)rAawZ-:d<୩ER X:/L"DhzcAkc:;ORbh󈨪"D}P/)Z|pZ缱f'UPEd$!SKr40 9aX.#4$U湀H|9Gww8Sk  >\y*qa)b'"@XkAfV6֊01RQ5 X36՛QY5$\Tʗ2*r#i 'h~ȠiTyOnrq/Il)F}hS?6??aBlA`|C˿ɠ1[_]/޾}Ǽ+˿xO}~{r2ZRNAz&rbbOBHkr3skl ȘYuY_ܼ\Q>zQ~tk$%Tт F36vsͺzVݫfλ;gq}{5cӝ:5fW٫M:χ^fIaN7}8wnvi=vIsU%IVh^s||W ^6}007k,fin]eV&-òkm )HS@Y;V3ɂ`Q+Dc/ԌAV}ExsߓkϋqE P53Q Gǀ6?>~2`9kDetʻUG\,8Mqunz=|3zW3Cb4q1hTc4(jb!-Kn6qy|<<@xxx=חܾ(sB`ؕŠlHJƎ8H|._JG|lVC#R#Q3b\1aIry^Z]*t9BMI+agZ$}56{7HDs1[f)(Hӆ 7O%WR4ƫTjaXV\_}.RՕ;/e|x=Y( &IJBs)N.'=U[YTvw/LCR]Wmyb˔,ԁکw jg8")9#b8URJ0r\d?4M_ǘ+@bQߪKqBFyJf@lg%QR[D2I2XI cfHq.H1(JR@^xj&bnjxz8޾>|!;=c`YdVm ŔD IMĆ)b䭔dVV}A8J!M3 #RwԚ-xODq7+YN׫5QxR(IEѓcD:DDű3<DDqiSLx-;+"Z)yJZRU]<Jiכ׿{[Ē,R~`FY] D Zųg榮1r,#(}?s\1MZ Pr^ x]0aȊi01Fddb>6͹,#pZ0Z au|?'2v{;yϼjWup4)M9ˏI2Wm@)k)ukv6~ãk8 '7NKPׅ HѶ-T5HQ)Or"?]h.6).ٜAM,d&6Wo9`[4o"@,g#Bt=>!"YKvލwLgu@ѣ}SK{qp%$msLEYXeO.VrWsOmeM|Sh\wͥ}ܭqd.í_u=Oǧ}_|Yӻ_Ͳ7XqտK(˟<1C` `n@s&#b!>B < Uh&cۼٶkwD(2Rp LTuJ9hiܤBБ ".(JSqQt [52]2W fETi^{O?O_a8NWΣ seZ yHsE-'9[R `Ua'L( 2(gPAA6P1݇4e%OpA0XKy@AmqW]j&.cJ?G(-x434|3]Hqg7[T+w'zAȰ|17 /^Y0N`㪢Trp8.֗<Çv2<tO_=$x+gQ_VrN=,u-R|uxOe,R0~h,D1y8j:?WuRJ]mNS'r:MEէ5h$Ѣ+>G9.|~2TaIf5%w߿M1ק7O_Kߪ]3iIÃy4@%_I 7U3H3!1AuHʵ L.ſo.*4h+_;qNz MkǼ:nf-p>jr\}_t 5aEZLp~Z)ψS'7lo窭ȡ@\%e) ,2|`$}NQ4fKbƊ$ jA3ΔH+;*B XrhOiJB5szo 0U}sP1@>Az77$/? yTv|jB(0fV8-${M[^KHD$00Xɪb!@UC텨fQ5#1W#OιSEMQD$+9dfDtIY>K-gDM㨀>L;$"B@LMݬUێHRDKM[d )%FQ?hjT@$v"3oV 83RqH)m6O):yb"˴t8 qE485#鹗=(1S%BbF4@C2dU :U`v޵y0vLLDvv.mۮnsytd/_<{<-b]{ix~si`(f%¬-R8GM3'PKrG궃8l_u5|/z9ۇmY5>e9>8T2G]qUݬ*^̐CRhJ$[ݘne&Ibed(Pv]&UȬ83Q0:6:J4>YAK"  Q\=`1oϴ Cj0*8K(@6TD# YT VU~LGv80⎳+_=n4uROp|" Ѧ|VoG -1)Rbhn?|ۆmכi떍 IDATȍ7_m.CsaC\ppep2j$kS}7hd&s;dL`J53+/?믾vqxۇinj3'Q./`|e`(oWmaKjHi a0J˘TðbZ>.ևi4rԘ8\ƭ2sׅUq3wfbkVI3zp8NĔLLnrejxYU5}(G_&f mCk_AN˪tPl+AFOhdKZutM۵'OoyИMt\U~vlws"hf <0&t]7cp^80D 3O\'Ŧqvr%^cLBMCo#V*Q)TER6)~J9fB=h (>2/A]_U5u^+Y_wՐ͋'WgoïBOw|e[WynaAf)> M$နS8- ɶ_eWwǿ'At %]Ncp)Es6WKgփxU/,Ų<럇jc~P-f5`;~\x3XHR¾h}/liUjCK:0fЋ!:#M^idK80 ̀ќ#P5OK,N?fz ?yTf1kikn{>8~)i;VMhݸd3g E8eH=}I1ťd_5fo`Xjn4%IK)^ܾ~/Ұ+);vXDH33o>rsAX U݂{*ԝ-x8ʕ4`pBR>T!;SI9i)V\ 7W[jx~zt1׳sO;=2N!mLͥ"/ty *츛jP,˙edڀ+,  CAެaP*YshTHΐvǤ3={ˋ׫-m^ iI1C58Q 8knO#׎xS#?ޥozy;:<xz8]vٳO. , G+^q]$\XBВH^C"mL:Uh9_tm߯/./jS1+-zVf4DTEqj&{ DEE(k9[gy0 MqDn ٬^ :)jK9GJ.4 dGLCd@/^\vWY-9r"CaT6/C./.!Ιsjfn/\BlЅ7?lOuGn= 4zX^v*ޖ^4=iBN¡^_u0< (JSM{sT}w{=L HfZ5b(w(<]nz]\dJ8":%W_sstQo(Oxѷm[{1, PD/Ly5@[㜀?IlVٶY%7h%MC\؉_UL˜Σ2)V"C6+2eS_o& %j1eͦs$ɹNs,YThH~$Pa5zJ䂀5NiAWtU`Zy+5`x:eK)ل朝c<% (gi*j4RtJjhHlD>Bm[sfJ!GzsYGK @1tj#19tLLU@D3אTM$lX7u{~K*m]\aXA|݃* S2sﷺqDz9jтh|8vofiD x?LܶYˬF+6^)/^^sn?<溮)fpjά- 7@. %bc{aW隹r.kG3 @j/PBp!o~ Jpտoͅ}'jusr{{]Uc>xd||0XRr z t[rr}܏iަk?DqfIQhQ4r3FdQU@z4sy p^Q# AϞ"2`d2JZQujQ˔GcboZzX_X Fr^goM_4&-#Vʺ_|zu!0Yu}z99>{{{GKUMmZM0.H Y+HH`iM_34U\kuJfDjZBH(͛:3UPcf--CQBdJgQ%& ,U U TO8&ZÒ$s2j;5oE"Isn60a)9-3Ud jDy\y(dk!=&Y^ X 7s^d>F|% ՜̭4eCԐ@͊d@R0&M5f/~}v!=ۻ2}_ԫzV;O0oJEEfUA䘦!L.j\i:׮&`i`)>VͶ帪,y@]pw< DZnӜ,\J6S! ETpnY,ESA]ᐉ]$1 a$FeFw"Hec)Z$Iv>,Ub<j< q9 B A4Kl¹>MP.0!%"b("Ul+jM'P Nɦ~v",Kڮ^,M_nx"% : QDFtzv rWiH58MuX0+hH/  pTݪY PJx47wp_O4U>^5UZM[]md,7+ػSϮ_xL JqbBJ\mi`َu<2UQ lg%+砊ĭH6fT;0jxP$#H?1Abg/G_ `DȈ $ɛ=x^yl jXsSR* ZUM$Bnm?x>r'EQ9GWQIS2q~z}9a+]ާ*g|lpȔ ^yNCIY G jKP9_#mz~yK%zgez|gqQ3#B r*%132!2]S`jrII3C:zn!m! 1/&!!ѹtP +)Eb`͍4%Nh02Uڶ r^㬖 ޛJ-}1әNUWmAW2 A&LCh"MԝsN{XCD!/)hSLD&; +"9EӨ@ LQ /X$`t`%'" upħs9&m7n] 04ȇTQk瘈IOS$vvIXtN,ţ@zSS)fUе_vuBix"}xרyX(hn+⽿iiVU ߫:WYƦ|7?{qqkf9tX핰zTw?ermc}3oO?]OCpZ)$>&ބ=_}V8; ̊Lv ZXq&>T0Xr0;/{(- zJ^A\%8„C|sꧽOg"f?fyΣUw.oKq#2quuڭ,ͯR|>p(+M[y.!͎*@Jwϼ,CaΫH&d;fWU$ @K,v`@VvHr4O)~ Dg;|:7$b`#82@u!*] e<륿[s!Tb*T. 1Wr:u2cJyi\ՕaxJö|l,r@2s8"ZWɢZ)%-b9ۋYh4O qV{1K|zژ0dr¡UU4$檪X$i/ ᓓic65iyc31f5rUӠt']A%+ 9"j1 EJH40"ffώ"cE%O@iŘ}!9!1IQBFZTE,1?gTu>]L(!"EĹ1\r/!SsRH2#1XY*2nă*#@n?4GZN1'UNGvuDYq^ݬYw5ϳBWEH`;-[GbD1U;Ȁ@T>PY{xnC,t_c0_N6 *opz\-tñzy5M]/?Oon:kl|}= J4=;aIjSrXIַ3\WwX,οW?G?#sB=)Tև*#hӷ^rU@A,60~-ekrX!]6޷}i_c!e3D 4TĿ!))\ @ǿ.l\|=}<]x~4=c:s$zbTbRp-qc5pQUޛլ mJPw%E2sq؂4ju}EEش_]9Ѐ r`Eۧ߾@UO8>7=:7M3N1QmjOjjc0sh0 [.,% 5K7r]z? oaO\}N7 kX\^i񾕗piw|AMO?nsnyz8gUcQR5Tc׫;4իW_RnC|\<sZ-4w7Kp9BM BR\zYv׋qY} 2Fºnջ1?E!x~tT 0vn|ڿ DyzfS2lm&K:~ֹxmoU}gHe; 4O?o~7ZZGi>WDVXe1iRg'04#v7UG̊btd*,ʟR2;0""e|.aJq:j RD')~=߹ p3xq8WW_=U<$G_t1Z s.VM~߼yvv\ 9kAKƼ엕8C(JuEh (((ϦYU[_wc3u "xכyy"1O^3RTA j&@ FVP&jD!d up>RsL"3Ĕ}]/X-7SѩPƩ4~{I!A뺮09IEbX.RJ4A׶yH VJ,.!GL@ $/=4L`lF0,V/C9@bR0' &z5Ir18poonڶި9ׇaW;F)\wŷO4"@DORD`bR$s41;b/6e<%f^t=A׷a _zk_7 K8?w/~x-˺by]sdPQTV[][ rqF'IQ3 9Ԝ$&BjJ3/- - .h"b) P]Y.=#!:V%S4p% QNf (4e䱚1!)ArXYίG?%3܅fĎ 1,޼yV]#4\X/~=ozUW)t3G/}?ŋ׋tzu_dڀ(q-m͛]}w_4՚e˱DN PA/Y^h`\16F%!fD˺@H40*(0 FhƟ:ll挅]X*{W?f>l87b_=P<{Kez?ݜ:SfShlv_f.eշ\5iLjŴֳ뽒fӶ+)X׍'’4 k|2<&tpzq_~W[ WҬ}8 f!-sF%Y]9NS:췐&E 5 P$dsfMro*]Wv@ %4)B `ϮW7Yw )+C gWW8uu=luK7׋_ xz~pLӮDZZ"ӺWwuS9o<5%e1q]}̇53m߈n!([,wobZݭa\\\?a9 &Uep-)(Qw;x(ql=B6]sJY|}St㪖EeI)y^ uDU߄ sNӏo^mM'og]ShYBcDnaL-0n発+ 7ue秅;vn^`qXyO%k+%7 $8ʁUbӺe(9vh0lS[{xw>9ǡuRDHA8LPL|(.ff?*˾ijY/бjCt *588GX-v+J3~ySLJ\9{W$hU0 +{_UVTEW‹9=C%;{Ϯ8 aR)6Wݢ?NZri!F`L_n2cx C#TkWv 94`,k$`_J&K.\뒁1h-95:/;jut0~3D#B m4LTrvsF/7Sɓ,k+瘊0hƦo"Ϳggh>NӄlH쑰hL8D5}_N_{On:e,VƳ'Z@لվ{ozmگmen/>FfL  <"\$;p1}3Ary> @paOK,'@JXeݿ'U8;2NaY0H֟JQ4# P)/\0"XVU<@ #tH u*~C`4}>X^8EoCȧ 1pp*ψsQE.۞/jm'XrXEZ0J.f"مms[[‚Z6P<7{բ7g/P:wӴSv i;ї qΛ){@uk5TRJ Y[gCI,2E]סs1KSt Snv)%4D%(k[3 _(`?FtUF uYs[_[ -$WQsP !yP(7w;DGxJ!""0)sȌ@ ۍ?1Ep޵D\<)0fF!oi…\^7f*%WL,M5,7_oxJ*@ӫZH3ib"$gjƠ@qdCrb9uUa`g,{!.~K2\|`EW LYM]yRSIL )Sw{k?Yy~\]uuȭ4~}}O-nr,Wp|zW]]c9gbi[()ލ?/.bYh| W\WU9ͱ koօ4O#91,q;ēTxT$x~Du){kYy Oükw3c`^P˫+N1!S&v5UrX۵q.M<2jyPݮUa7|3#s ZA4l7wIMլ82OZFBCk1扽'ruu=iY .>u߀Ee9Ƥb<nz((@B40Rp&3B$Mq"* t[%.,SDt1!&E∦v=Ə^ǿ|u}wsoχѭ8y<CMWB`N %z$w5^Usq Z4xP %\Iݙf2 XnhDQCL4Į((^@ @JHFZIш4 |F4O3W>j1rH y]B*4]ۊ,T D4+X| DDfnWDUwS)U١s<B{L>@ h*LcQE.tbsdYU޵t40gvJazB# ||J@6PCd F.'ɨ hT-UUuׯcil +_,C{rCO/T!}ٝW'F)Ԣ=uWJajoQ}rnYH}ݏ\$ eb>$!4NOsJ6Mө*OΊIb(bc|^>[!rsI34 Ka=yYf28OX3%YAa^Ok/< 0'dy fR Ut2Q!HʖT^0 I}pfbt 3`E,`hPw%fa>_`%3G<=ㇹ)CL'Rw21Fx_-7?zBWfkY+$҅3i7)SxN_hn_?6M\Q+19d$&0f0ͽûۻDz2-s%e!@E@fRS Z_Jۧ|{}ˬCWYl]~W4)P$shy^UEiR2BbƵc*XQUrH`Cբؘ y ;dB .>(ǐ%T2PS+ LUT`#+芐$JlVYJ̞EL؜[d*qUrz.M4χIP6.`?C%+tcr{qw?~xx]·ƃڹyҐ?f(cIaNxs1 .fI% D!#9\W4c]}1uutU|WОX1Y݅8{fSV؊&%[ jVTQ ʢ)?_!q.]Ӿ}?= n!cܳ/kv6U>4}tu{7tXTPո 841dnOQM_uQ6i؞\\N^JS(b`ey$b:ͥ *%f/S:D@BF=/,2) 0^eX/&3"@XJ8gyT4M"-3pRPK~b7%/\Ę mRė6pz{/^7~OCCCPceOww8׻:"e@קj~fѦ㑥H>~]-Px.7 YSF'AuRB6vL)ZJŠ,RT ]ɀL.`HXPRRA4UUs/֝|yXwmӆųU݋-wuNsP ,iV%}yz8Kwss1zHTJ)RB@r1GDB%*jVuS*ŤyvfVUUM0,+j7Y]2z(ŤX3\xGh R߻زD1!#۾_(%ɜbW.m S]7]ߦ"f9W3sYe z Zƪ0+?mES.1ys; e4{%4a#Q6_>8驡*zRFSDCt^O}PvQOk +nu*,Gi% *%$0Y:pv@RA:1NsVh*|WpFx>u]X8<cAT<G:\uXML%BdB,Y/8NA T LL9lSX}8-ש;dCUUNKY4r=g@m$;T @JQ$Q+2A RâkN"9Ev@{T2a2@#2\s󦢛0$&!W.PD͆ LD5]ϓHj9FqDS P0 F drw kW׻n'eeWIͳʑMfgW'Bs*˕{g}؞"&*i)R$yO~*>X7 LB:Hon9A`dQ_!]hw/Ɗa֫o?9ݳR܅pJ vZdAM d1{}<;t/Wqw8V 5K-)nLJE.E~ͷOvC[Eg抰9P(iuWMj@z~Jy=5.>N5g gst̻Ôy<_Ev" \ \rN9DfRI#T󾪻5 t$3U1y2*9v9)ms Bah+ LDL6( lѾ{3yaP|?}qV][#W~x:'fwmKR2MnS)qi)\_ux2溣ݑ)x0n?.c~%'cbYsA1!] F(` HL\sc$$Gjzaxz:ңWY)]YlYP*b<(ݻ7_܀W~]qءmQfan{xeY.Ŝ<al* ٩AG_k²<WQ(ACTi֍,))R"o&8ԭ7ۯko7};U &2ä\ `( Zz7?)ǃ9J ӤAcɀ6A{}I 50MoqRGtb.p3Pihw^]QYSẻ{8i].h{PG p\3?!JUeBb}j. )q|8VF2r?y?ڬwO6I :ֺB1lo]K/)~bӶ@1"10sQ+W;Q9)48Oޤ,Z٦4.0$|lEc$CǁY8r}DM^O }L4 =_lc?e^W*)v7S2^\K~TěU>C?Y+1%΢ * fJ|VUl^:!&%$f3k940M9c\NYEQaYk Eئ!"y^2"lSeȓh^^ri9in;vciU51 /fxG77c̻3Ve%໮ Ib2OU70Ɣ4lO!>ogfpw=RIF~ [MQ-v=ĮXyB[_4E&ݺԳ!GNV!(3hiP3s/]iY~I&ETE'Gcie nT&! QvL_ӪxźHRyDG0 D{8G 20QCe`$W2ƛWXX "z_fY~ݟG?5Y VͿ_w]/\7y8O..WfnAV VYS ~cP,MW*\4UfN1RPbv6_-uVӉcc9s3|RY0z qӱu\h~,mdCKoBJ眳Nma7,]aWCyq{ۍQO} f޵#yɫ4E*lQX:[VfvPi:5m}b,fO9jΑ͊֫5NS7'@9*fQUݩ?(hc cԬS.Y" 3[PARQM)MD{lLQA!g f@JϿ ϶Qc[CbHB1P53FK1܉>qyJEAʜ8{;w޿/03H1v{{XUWv4 н[wGh)ªuQX')ZN7^4Ysv{4f ) *׮Op ޒ@hVO|쪩*zӉ )˛yQ{c7d)GCȌ޻h'f&2}SUΫ"Bb6d-~s2k9*B"IJy yטzo>ڥ׎Nq6E $TȐsh-"EGF PT9DQ 5r1?S4qyW4<==XCu]Yp:?DU}Y7M Oq% 8`Z|^ Ƨ.<1ʗg/fMٛzZXo.eґDžƻ4vJ֧ F8viζW/(F`ԝ~˛EBDcj 1F`eQA"bI] UO")hBE!&N bvҴ/l703pêvm7Kݼ=/|9TN)Ѝ\H۶uՌ Ts8x~1"LVU"pI2d `ǀ1bq՟o\YUQI5nQl97\K lY%ch6W많?Mq&]B)Q`5*Ԓ.lQUFTK8krE6C L*bAɈojE=91y#3@ )pu(N3Oʪ8UV,2E1L#"N,"j˲6ƱWa3\_߼^Vx}rʧsx 5ƈ(ZDUQoM(bٛ{|e( {~QKؽ{*)gy6*"񦬪w s^r՛v)2IӪl|7a_\EX̗m2s~~GC~{n8!AA1/alpqfGAg~iH~nmdgg{/_(*l̬Շ]Vh l.sJ9ΚJ"lJyˠLBd;irv0X`"@ GQʮ.WqGW_N7"{W;LxRʇ`$I)o  =ApŲ2P CWe__ܼ-yUM3=9?~p0f9ߣ9Z7~M$3G$HX39p|<,g1IJIM`4aKj7C=N^g.۷_}\E ٚ* (X,gUxIL\ymዋv4="|G{"*xw:I~궨(ٮ'CR*+-V,.Vg0<>>8΢QVwU ~ ڧ٦̚a)8go }]U$n|`x0ixu1{}Ys4sd/.Bwwo.ʪQ1 Ρ46oΗ<8:NX$ 9O9EQ!L5h $,H%$5FC$T)qdgf)?>n7omŜ>m֧n̒[Lc͛۳yA\nZ]^mW~geX;![kJ/j q:%ǫ뻇8LJ^S\8(1՞wcvsڨWݰۮA~~8~=ճ4DX!bjfsES.,k`Bv~Maʪ~ukYEaP @ceE,rYcg_b7^-ƾia bVZ>Ӕd,@(MaO!aȟ5p] *˹+]fo ZKjQf[bYWFt)&HI$&Ctjyy[@qFĨa"\,Vr!q̎\;[^]ȋ8:eQRγYK#Sb2 c Zc f1%zFk6(ӻw{Mӡ?ix]Ӹl>6 8|4 $cPcӠøz.;rxf/A.NK;4/|> WW/.]!FcHDHf{q{իc?MjmjT@Z,󢴇i˫UJ(|ݯdLʠ5Owb;R\\\f"9C@eQ՜s۶)y6s*2s~Xut{@B*s9+dLcq8rijO%Ƿ-ľ-mPA "szƌ2"N"xkk|94 !7ffk(Gp{{؋ˋ݇ymMmӦ]>DctTB M(< ?9ZQLKL߆a6g_V_{chpR$Seyf 2U0bN˲ޜ0٫@GA|`a1W./W8<Zkp 'g& IDAT,;s20 ٪AS5NK, =˹UDW2aZrzhѻpٙ)Jy^3߶5 >Tp{b^7!!dI1V@xt8Kz8>9˪>kKu`, ֭֭VA -Jq\تiuN/[jڶn%av"7\ZTݮt}Ӽ~ilv "lv,L:.J5#BI8A'|iOT$ 鰽Y |G*32< >s1Yb Qb oM=vu7Ng3]Y^۷*. 0Ep>W/o/ݻƱX#h|)؏|f勳c8a{0uHF(^zf45%40:hL r۸7Eia rDˑ%SCg]zq"E 꽟5n:GrlƆ>L׷߾nHIc(Aqղn-(Jn;N9TXxv],8vxJ- 墪ں <ƗVw:|HE vQӜ1YɆ ~g:1(aʶ*ԖT1t:#VeTq`bj *QMC MEI8,<4F+2~&gDUU2:BRA4)FD(}I!$@hUD%d@8g(-Y@W(٨֠J0×}&{3P t~No?I(_~}՞[e(v&vcu!pj]U-hewMT6;[Ud֬̎PT @C#h3ӡ3Me5!wb  JVH$`Չ{b!M..8o֍tV_!jVχaR;oʙT35:W ׀(ŠFp2T-ˑf#jxk"yN5ncx~H?W j֊mb~:_ZbS5~!nMSxrNz &lcge^YɪqeaK%fu%(7-E1<Ϝe "г%AP(@r␻}i7ww+l~|>&!iU_$!7Pg60L!Ѩu4E$ )KCY[Dᢜ^X @isNq[|2SF`1b4~ jWy:>M%YsҔ,PՔc,PXC ݱۗ/~Ӑ$`tUɀB9iRa5+Π5YƔseOaxc;s+-m~LRSfV4 {Y5aaMᬨE;4,xf"+ǖ@&PGRL˱25frwb(z>PkW^$AA`mh})"8$0qzi{ wr>і.G<#GP5T,KYc |T, i.. Z)o^oIzujgeA&( R$SOnѺ~__C@~/ Ffu%oXz8NKt"Epq!Oh:l0 b mYx!wպgSC.?Ask*[A r䃱H"E?:;Ȏyi 4c?:KzSfeU0ĞqrEpqOӤj(MEHE)q"ڸ,1YC8>Ua^CTs D";G%^X ui]vv Ϡj`@Tk`V^>JECƪdD5d]<ЪU!UEd]̞[BATA :c=apH3AFd@lT:ЉT!Bl &%">t~8=cY=H9v8FR)mA.JG0&$dĵ^.+SW]eN Ai0N{@$<W!3 1pb(+h)LĽ*$vc8MOݬj]L=lNG2ɸX.꺙m`.v1ܝߚڕC'LH6~9o!\Ny31""*&V֕բ(d+W]$ʹ~s՚SmYӘZfvfMFfJgn]~8$̠.hZ%" P6r~6Ky42J搘0`ӖU9ۛ+߶TS_C,!QxN~duAryB,*J0hD  +Jf6y۾>3&!L8QKkJ™Η!L#s컐23fD 2sڜ$e~_i}m0 cl&*$h)֛i<5 ί5cP|7%jNZCq6}a*f3ddRmqZ./D3p PY)e X&$*" 60X!`*ș@v]specRb[m9'[75:%II@N4u/)e%FS$)z14B2SBH)XD\ʕ7tyi OnŢEkyfݱzNST^NϞ/|~֝â? ,aɄ<; g׻a?TRH0 B׏F\L aRYeMb*`Jh,)]⠋IDcd* 3}zdI4sD2~B ALLqYLƔ#>ӡ?Lz E y{ɉ,In49=+⌄_<T"m}(]ǿ}6Zo_^檾<(tk _un6pB3  pb|qjƜᬒRYr=n hD6v&E^hPI, 1&zell ˦YmД%j),'QQIX^o$~) Ĝ]]ws!x0> =@EvUjYa:L!W`;Qջ7yUg3kY(%ỻ#0, sn;dυgE7oP16  e\oiP\.uYM|~;[,/~\92 %$`hfL6TDg 3vs 0<-?Iq MQԖax_ :!nvYWvneU#qC.s&k;\z uḰ)f-w*~iT(Zu׹i|)b z) 92ޯywH<͸{n-CiBp9ɔ4 yv uxvYWzIefC.rQ)y3EeK]_O*OUF F@Hb@;>Su0fwΫ!()'҄Mk {l)gEPPn-XrYWՅW9ni  5 _lM[׵K?`*ٜ&æ*.֫uw4Nf`9 ֫e;u" 1gus3N uS2CXj&?y,r>߾{óUs"dbQTo44Nt` '_qC]}߿zjxOc^l/߽޷b1 rY_w1.@?? ;sԑ"%@A9dO@d]%}?rE[b2rJU+?{eQ;bQ#\)VCfh>x5˲%ec:Nocs9__wVvi9;.`0ßPrOuIBHeVٗY*EH.i )>/;]5u U]U8<~xYm֗E?4mqmۃ 2p]z]xj]W-"y^/.e}QYlns:=ad>m&Dd5sz*"fPr.RJ 3,jlಐnbe{]n߄njUhM]}'Oɴ)bp>Bm4UYT0?<c^KWχB G U 5 ӲYU sݝy6UUe\:Y$8b‰TlI!7E|ώԩ4t W;QZ-PyF/zݖe,Ұ 3?O7T ?"ޓL`fJY!g,ͅ:H~=1@Qyw{_.q$d)pl +{-h44sܕ)uZ z&ux_q?_ץ/O]0y}JS<~^AU:SV PRhf>JlfhFd==s0Ld@s43d@)T (q3L̮\5El8x%9$ͻ1 QseAuYd4WsXTT0d9h'fzrخgϿ }Gs.-WuUv&ݡ-RU;H#i~lB,ǜ ** wp5ϰVU!5Xt:ANyqsT$Ü2!gW~YJwe(y㜟>YP=u9ߟ 2g".e}mDѐٙb뱛uKQbUCՓjrhOoA_^^^0 -څw8%wղ\~;]ne:xǹ,*Th n\QNH 40 :3!ĆN$c9j6$ PY\h yKe~x?>},A'89 $ ]jJnG-fDQL$2_iajL29IBiHGz6 iFH 6w41yc?i /P8IPd5yt.J|9B^luU-+28*|AHsI!9ʒ Ks3IsS.Ufb&HB}8gS2\/%Ɂ@ tJJM˰UTW1$.6\!L(ތ}X&ɖ ӫ+k'5  93xD0;L @5)HiR:0!: ƛsl^?}vpR,CC6N)Y wdg`E竨( p.C]5;:'ضzLnr Ni~\0 i|d1y0 z]_/iEnV"QQfATTSB ҵCgqVb^jj 3ج~?`HM1"@4Yռa&r u\9wӁ.b{ݺĐ4yDjLt4hxv^'-*E겤$tbFQuBH~wUNE( gT#jsZӇ]mU9R M*BPSF "9P"*/4MYJT@أ^ƥ'E<־釹?tjy>q2LDDJe>UYZz[b2օXѴp,|DN:%%I+﫲>2yDSe!OIrQ €òj]ǜsww}U*6Nq!՞P擛&abv1)*[U4+rwOFܟy %C9qϾf ,E,>Wͩpv?I#zQL1TU vq^66La(+iQ{UzCg lڪB V,4sr1u 8M]@ Ih 9}lasC4p)3S DȚЃjs4sg6 \(c<}z>!ٯ*PH$g2CdVTT,JHUl._;_-}Q* bٱ_N3Z!#%yp6!͑ aЌ`'sty: BƗOw/N]7p8-/˼ 娦@:̶D|U2Rd8i6exz ¶4y{?vPTPŔ u(7U.2c @ƺvG t10UuY("+04Iv{C?Ld݄e\I<B[WEYHլ{^]oK9 Liɴ-8.SeS왈Li_x^5E \;,#"C\VeC?#v̎$Ȝ`0 qHm8vv:Mf4fjsc !;CC52W! "'4Cs'٦ AN% wSȆ0 %0sI8 -'uX?}x]4?,7s3eyTBv4Ker׿q_\Q飰)`2!}"9;P!y P 8!)'(@W߹GS7ueE+$B"8T#`폹jWCEp x!Q$Q'ylhIňrYۚ Oj)e(V|YWybI 60N =" e*vr8?Fo[[8 9O9C4<:32~ҝS\i@g!ʧ f.1O YF@@ah2$ӳו)ycdT4C@KM|q/hTb95ǽ2` –|VO֍t|B2{dPA39 bGD Q KGb̃沦6ٰzaDIl%;bS ,@Y.&[>c~) /x mXN^5n,=Rx/۝N)=nߍk_R#ucS_9uFL9R6bCUf/̹Ӻ=[sfȐEKss1)D +Y1 "cU͓5YmُQ"pDdh%W/nz#o׏x@D~aZW{r*e_G4'iZ-. -(z IDAT"t4?7BTmXwߴ,rlL)ؘI#nn% Z$UJ hDc"BB<s+`YW^|m^lLdkڹbGI#*3E HJ2YT-ŋwK]Wi_Ҹi,ps~9*C1"6%A51\:DL<- L,e jX$ūu,_ݧRWT4*N'Ю@kOӮmŔfrJN7mw^Kyz DLUc&IZ|2$#}pt+r ڒ_nl*N0gu.sPq޷^gP:kAЬ6 3vՊF͎)v.Ntr\^exO"SiE2asx8>;fF? ̕L!*ٙh;V-]N< 4|fc"5 ,H<Ř?FE7\wiQ=_VngYխw=LĚ˲fu:sVA`ߊ8 N1dB``99 T,0x&؍HߺT}⩻q뷯n^__mHkH @D#;s5P?e(U@bhgS3;ɀA8%CMb쀝|uaSҦ xn Tѐ %9UTb̑2 [% "& %Q6hTh1Ur]՗O/^@_k.{(Y:0fހc3@`Bbfhgu|wZ.XRK sy*# P{BɢώCR}7G{ݧe[߄3de'TU@%3A1CBM"&YhI" !n\OD 0) z~):!ަc$jŏ^v^쪮2M9UU7߻h^T%y $`VUٝ<-Hl ZLYKʇ.;W?zZiNI2%-Z4/zsݴU(qLoChKEAUM" !hADGᩏA/..ٹ9RwOÜ7zxr}ƅ؋j^VʐNpYKifBl485t8PDw*V8b*n6"\9<.Ӑ'Hik,tX%U4u%];ݏ8 kӦ-jrȢԳ 4׻ժBiLưhr1֭#Sj}?ҪV.B3>PƒXڪH>1!=!!1G&""FCSP5DB@3s(9!rL~v#j%(4= ӮSt9z"! f2y7nc쎇Cd,qծZ9u2Ց \ݶ (Jɨgvy7d$Ked2!PMIK"VMAu*,[0-j Ր)?3a mwRTTUTN0LM)e0(*ƮS4OIP111!3swaCDbD, ,JI6~hzn<ش //6mE$i\6.6/ڪ][ PwW?.v[BZS.J*9-SֻUyE"ACUy͛۵@~x<˜9nTw 럥P`w3cPLyKd=7hhhL< H&G+iI?1};޽7_ʇ th]WW8׎p4xxi?b _⹾ J F@\pVyQ^s)j1_L_,?._}?s} ~NO٥߯ DD=CKa8XAbA,P <'@ԡ)QBZed5;_ܬ)ā 3%[2J('u5s> ٰOۮ6?yi󧥩Cw[ 7 )PF. $!\Pa"ZǷ?Xn$Z! `@aKjIbaXխsjci Xq2r .4ժY_lwD41jSfS~8~\Xԃ*͍8 Ƕ nիWfiz U\s)DJWMޑVr:Asy?lժ, \f@qV붍! iEyi<=<>77ˍc:<1’JiT:r4|r۶n>ǻww3Uvo.er ]?WC"8_bp eEDt8Iݭqj%d&Sח]BDn7m<LR Rzw.jwƨUw~ӟrLRu@/c5SJeQ]X(οyFΑKE-&O-!e_)lГ4#2m#<;7XP04Ι!3AIejd(M⥻=jQ1$e-n|{"YY=' )tq={bDHB$SHbOO|K:~v ~>߽>&x̧OHq | o/}[a^Re~f#q8˘xGbr)q۠#.VaVȪ`Jtv ,F$d 2GHĚyE ڹX:?D!W^ N=,"P\RQ?KWy]?Z'Hd1856C,8!ΰ^洔o0}<<DGl6΅? ͪr/_Iʲ`ɚ $O 6%( @08gUuOUE`L f-g>z(~b.2/:L8q]vUdhS?Lyvݼm:iLpGJ\Ũ٩VYh]V+@V٢ޙyNU?O\nno3YwΙgDPLBmV>]y-Yx(L?⹰7$Ƅ F VφEKB)υdFޗr? NICeIWkώK. Eʹ5fbefOyklPyXRg"Vd.bZPYUUA-En?6"XPŤQ^Ӓ%K{+tٛ_~wAHCliWMےĜ%ZDOdYDj) #QN}umJ"ŌM`2~U/s]x!fnի5 J6ΌQ-cJG0~w>noZ$c6#U"(%ϠI-4J(S0صWs/,jgo}}ywh~X% &&$33v jXԡ CfQCdc=Sԭi~]q?ŧ?8| K3k%b(ГxՑT2挻MWU$P uɕa!00pz-Lf|i~Z]SRa1dk `|| buNfc%! b45i6CՐ7mWv I0IRĊՆN ¤(XGmk|x=į\3g‽֘c$&z}?Asgy:(gG>LNo\ub\~1x 9ׄ1b[MeX7aD_t Zrt8h)E玄XO4Ns6͔C?>yfY?Q1cIo޶oX_aO_^n$׿u1?M\eRi˲a;U:pҢID+O1JMi6bQTj&S 3)za7%OB9X]WݚO2B}dFcԤp:2V5ftN~%b^`8:njֹ?:h7xe[-KꆂT \70\я,ǫW_}zӡ:jj;TUS:0 JZǀ]Qdz cDZftz|x4t(ueCҘ!`СūK WerPHJj<^oVS^iT]7+^/i<^\Vmhtz)%猈1P;b&g">jAT=zDE9T%`"00S5c@3eL5]4 ;ja]֑_ zL9y 1ق ȑ135e6u}FԹvl*b%e MZpN!#zy=~<' ACADVfWnӌR$Әԧ~m7j??RI4FyY8hD.P8˼)C3&j [7 @TQ4%ru .R X4)#WUze\$emeĿOuޑ5)(e FɗbK}aQtӜ*ڬn}OOI5PUOOO{W՗]$0/7m*ϰ@ = s5(P!TRdADg>:I ZmV[y֫i_ozӹnQ ;V>ݺ^]gW!*s7 k4u\Fg@ԟxoqǧ'jg-ЭT?>\ 6Mfi*O;TJ2,ޣGV #@ɁyprƔd`Bz;!X":g @y!4 MDH 6gqe\o9|Z JT6'&0"iD}<O7a"e~hqZr%)E[ J\TpYpR PTH }6TПhZJ%%4AGUE /xA` &^)|QU./-!Zp0'(=㹯@pE'CAcƊ؟WW02jL̩"tX.DTmZ.h:s {2E=bIrKSU_<Lޅ"pZ2yS4/׍Xy\_s `55+JҷF? ;n5g48%zPIvU]]8.}\5i_84`Z_eS?Ǿa{UL+© yQ&Bx{XC4z{bW-OǰjCYH IDAT뭯c*< C00M043HR&zui(n[y?y!7??El{1x:*V}ߟDXJ) 9 4MEvWWWwǜ3{*e1e e8/vQە*i[_ƹ_`E*;B)EAsN9ۦ}j8 FW4-9yupKiJӜEN: >.ZZ'1Y鐖<].Й#?ccj(|58goYA5b9n\0B yd&[;$w6?M+tt)DWE^27{B.d=_ 0$Jhap{TR73BAh-~}i?<,n^`FfUF&@THK'\A#: 9 PﰗNO=CĄd@? $5p+ ʎ<.`*`6 3#CS$1+8Lr`0^BK44X85Kdπvo~iE|!l4p'X.7Z?xWTUtQAЭ6U/&1e!΀Q ${osƏ~vwm픾Pðt)P!I5c|y2;Cդuvfg :Y9S k뀫k4NJOfyxgM4 +lI#X!oZ,04Kð46:׿k4om%qOMAqymhDžp TGFdJBd@xvw%U00$Ω@35ԅhg*!&Ԍv^vH>T2HI,Ls,B-5m\$) CpΘMdp<(@:HJWjwvġR:4)w) ןjwUiJ9v1V'^ƣ/UÒ,Savy~z6-VRRpkO"P1P~*cG+~^ y6 }"8jmm$L3nwocߏ1TeqiV:-=T@8Ʀ$o^>; aU*c:SgŶV)~uUR?>lu]uCl=ٯ&O "ɴXWO rEe\bY,FM uI!z8Gi엏nca="RlnS,YWhg8gιPjF6HC?hdJ%ՕMD$ierVz@U]ԞSϲg UI]5?H?(QHJd@%OljĈ"I 乔Wg6SBc]eFC\Rf@Sd@3*x5ؒ#T3SU1.A߻YWPbMx%jY siKy0Tbup8-E2t61+T& tJt2 PRӴ<݋.\w%Dt6]H(yD#aRTU'4y m'3i9%qF%i6S us]\{ܭ֗21kUSǰZF{aK,b^WUloC'/#zNJB3L>w;1<݅D=ǩQJc dp F޲!Yx;^eM4yk/ã3%a)h*@[ ~y# UXR;_j!Oq.-NF5[^}S:>nc $#9?N`3Ùn@$EB 4m,6N*.0)!`54}&cPylkN:ɸTRBX T`ɬV, Y % s "`M,qjN|(_ٿDBhopA(JVgHx1Gn͋ju4<L)F2NO{8Ugזn:"fH`7Td+2,gBHֵ&CR!G ,FDVt]/rC6uĞhƀ&^52W1z@s(U?nBˁL\7qmiJ/PfH(+U-w f԰G}nxe2Š$t"x ?p:ĺ[9i*lb"a ҒG UE?~ 6 4ËZ.F% m"JӸ {l=S`^͋PsB14F ֯Oi׫C u HDhUӜi\Uo><4{(`պ4tLtza5ZkhsJ!f*i(mմQ?8/K]^ҬٖeBe)4jTl] ڨLˢ&TI 1{ٍ.O,@J*IԜQHD#>g>LQtE\rU5:,fi)>l(eA58gES MuZRF:>~<ټO8 sdow1'Mܵܵuܭ[tx8rO $e S`̪ '[u݌szOz,h&H{YLom>6ͱխbM4ODfMU6gYki璭&4{H$"by"*dLȾq< ލOv_Ir Ts@E,.HY&r2h-4̓Cn<(M#^Ps{0?Nh] SbVTLK5~z51 ΀ Vű )M b HdȠ`ju?/:(C #:Pg8뮻URH 3Ǩzy~%˝]%LFfXe;?BCChN/2ȱf^*H|6/"&qVCK!QTlVnHY2lh]lL!U,L# (!2 ))""*:62sff f*X  J`X T3g5"T3D6q ͳ^mnjHޱAN,bA&Čh΁D {}sgmϞix>xF/Jtdޭ[֎깞ti~=?<{мgd{};tj?b,w׫?O-)#૛+o?Fp&۸L%q8.o߿7ѳZz?Դ\K`msGȄ=}9Ͷ2U XepU1VPC-5q>k"E .sm30$dFth5DU!WjPqeuؔPqDOʔ=ZyfM^͕$A@Tj繀 WH Zs$0r|!:YD.| UEYܵ:7i{NyEZIt̪Zx.EXL~"Jp}!VZ㛎s\a*l賭^ )oVrdھ7‡> n\R I [jABX3c)&Pߒ{H(d6iqyإ9й#:1i\Je.SI;B۴f4%8=Vu()4mW!M:<=O!~%c_AD R(pYcdRR . z *٧ `jfUoH#*@ X&!VLFh.06@S%u낋ZqLƦV8XNM5,(CU ̄Jf|C" ާh//߾k.J, ֮2g/A:mHff=_/?o6S%f@r5|v!)Yk pyK3ӈ(k@)+@e؀"; E(dVsTc 9d``D襔jƌqW}z\ h1E [ }wжc*D dP9X4U7/7ib~{̻?7_V3D-޳h>)qUlax +^w#xSWfHZpŮ\[D9sEg0ο~u  H(9?9iNϿ:Z^^ytيM|v7⺻Olj,_}_mӏju:Ω\@jW~([7O6y͇gPXԷ7q7[9炪Ft 3C\3 4mP$Ek5lP CR 0StCE3(8"8H!Y׷b*}>S]/b\rV"pڝs)mq?n_h~x}U{x>=Lj=1~ϓ?}.s?8S/nWχǯW5J Lur:@DS-JΛa}xZ^4!8>]T: r*8},s~=J{[+%t; +쎧>Mgt]}j>}Qk'vmbjNf>>_b|x>c@vs09hٟ98ZFv~N%DLt><774C׸|x|RIc~~, Mh19m۽p/I1DZ1؅̎\g}ɢ"dbfY-/:w47HYo^tP k-\oiz4TdT򼿯/ƚƖ*jF.nٯwETLفwfZEYd we훫Euzz6$vP8esS";heLL*&V~^]r cf*DB &JŚ0K&2CTsD') -VOKfMvi"i?){%#&<_:i4ESl,"T ]&Ȟ]_sO|:`>'yrdh{̥?*]2.y#06 .v$a24%s-3Azpj^,ʝ{ط]$d T{jJedlXon?y?_u7_?|u۷Z--oT ́:Kγd@@XG3^o;U މV JU K,(4M1F UQrA3$DTjE!v~V)U ,/g@,it4U"RRԙPyk"Fcer;⬹zS-TC v*chU>BӜ=}mt0>~}|퐦pW'5ԸImI}wzv+N=}p# 3Z QeHi<{b qRm^w81Lŷt<#T-":Sh ;UIΓLJ-|X]V׍ڨ[TvVV[vW"Mۏ7 ZIX @U-(bROId"QQDpf(0z:f@Uʙ ul HDD :*HH Z؇e]=\wc/41 lwbnx)(Y=vdjѾja4R넌!ۛriNiz?7g\n_,Pc·/^<>qRSQ"9ެ><'Zw,Ebׅ3?kp{Ͳ_n:n8J>vSї׷y}cH~hg0,R{Ħg]EN'2gjyل8D?퍯'{n_Y-8|zß\f6hq-ejoMryar>vf*u-U $v|>{ nENEpqt;Vɩ00Kqx* 1*` (URΆ2\LH  ɀt&,75O.Q IDAT}*.4 7ƹ~;&S=/\y>=z=Մ`-pM&|4Y4YMcmXJ c2EOe*&fhb- 1\8[tKbb1XTU3ynt)qJZ<1s@b. @@RJuk+%:narSݬ>D"EU]e,MJ͹lRHhrEz ?^jTʁi|_o׫Po(n6 G~8#_f Z.@7H Z*j#*5\-VݣkZg4!xS:>=^sI!z#&k m'aq=[=Lۦc 9??|4nWNxG5y盧γGA7 %̳wP*g':EvX clE d sժ/鸹jsJp Y_BՀ̈́2$R%aQ֒*aR4]'r#Fj-ETQh:'ZBW|;-_/w?.v|չys{??E:=Ri>xVtP:pqwbԥc>lЫ $J|_ZO xPEۇ7vXo^}CEkXK2iIU@UU2$@t*ETHT9cZU3cfT/JR4K/`UbV}& eU,X$5~խ^oBĻc8A01:w6ONFҶ`Q`r^8T 7W@ɻGa_%E$.e9߾z),C^ulw-W<<~zN4O}9g]h8K˰@{><2_wwmw?wGS\6m<;7&6[w{SM|sC}-U(XcYon^z9O?pAism̟);:|:~n_j՞glPsTw eߤIJ=^ j݇alv:țl㢛ޝM!T% ]NPA\"צ]]ힿyի/_n֝o[w q&] Ne`t>pSz.k-f!D*4]w>iYTm쓔1#8WJJPӻj Oeì1W_4[g;LJU   v rR@2M44\ ׷s6s'&b,IY3 S$clL33È=9OՊ〤 HFR3#b&5Rp"T/Ae'ZQ' GCME @Z)8bUjbFv>tpg 9.џ2SUn<ߟ-PM"t}}?ۻߝdUpTH =J qv>#B@b,ėoLsqsj!D&(l M1ƜApz$))#Vj  qJzw=ퟜEˀ7~,99eqiÏ|sf_(vOĥJNEK-3/Ekr.M$r.mů^]7\w DU'\{XP{)!!!֪i'fl YE +R2gȸT"\T^B+F!O t1O34ww\sOof\y~6△yw4bEOÞλ̠ r)bJ4˦Yv=f5˜Uj2Iѫ\z}WC6ҫn)Mw<ַW1F\u{}*fBe[F0 xY^ݾl;hC-bs.W]A ͛؇},)Mq\-M`RM n>M9tv;SUsH~X_]|>Xw8>p|]_awp㢹u̅|LgYuVLȡgs6zZfNA%:t%yUP{:jv{<$lyk|@$` țSCB.]/ X 4R``{Z# [FVm3s cVj>Q^4h&h 0;9 o_o7ulX<~8SX# y&a#wNm?<<`{\OϘܩ]6eEhPBhA ir-e64vVdX@E?k&إ\6,juLa.{%Hc\1j`Fu EՁ֑/dN 4e`& R`*N E[b2U.8@gKJ?xu"tJDT(hFo QI:Z,Nx]Ϙ-TT=NO;,7+| /i5#(gz|kߞ! t޼Nӷsn=*m٨*[bB5%O R#VL 59(Pc[ETZ8 ̙8)ّs:ajuusEEǸt1)IMXcYP<< g4AvR#6k"+@\8t ReDٰrϧgq$筅HeFjƀ& VTHմVl` dUhY.*̢9ty33'5@dv ]1Eb˻309w3J4הkEfc-6XK'(Aꃈ0VD!!K<(,\AR+Grj\MNtpN*Tnqx_x i/m%l[4>'7ΘYłUTAt>ѐdP*5i4!?u\Ǡ(Q׷6m\jFU#3$e3430#3PE0304fQFSJ5fF$Q@ERg.|@VD/oU:NRB> inbCRz8toJjEv1rPiCMO^g)\Mif16]xHlf`lPslͶh:Ӱ[`WwuΝvpUXR{ڥ4idW*,9zg/V:$]wXtu |he$!)bl9ZuG0g q8]>1 RBxFEJ}i3<>_"3hC-C\MXwbi'KqZ\Ҩ/b]8$^Aw~^{Y8j͡k ZD346ܶmV4Y3z`S"LB_J*b(b` 9Y])CpW?z2wflF64]w}jsN7`RfFa *'rqHE ~`-6C֒Az99U{VU3]`!,: P%UU$@NM?O%@)4d{ے%=/L1UA5AS5@)W1~̌ PqdOheDjYT)|QZ,D4`9pPQRLT bS!gj`%A) *,KI D t>!ͳ}δH9CQBpDsCSIu]Md.i1e.8 [ivTsc62ӔyNrl|Lyڍ8x3Cע?/vs ȀD;,]ҠLI20fВ9,}w-}s?it*`T=!~/xpA"XiOk,c_m ώDeaW` R$tmԏ | {{ov|/Ϋ;Z5K.^e(h ϯ2uwlnY R90IMU-T] T~>7^_?.Ts12a3ԬPoi.XPDlBԈ }:q܇Pue3+s?/Љ)iBl~mdH+(IA 40n0䭺c,j`Fܗ[WMQ-|4 dY_8S#@ˢ2!,IruU/w%AR*6m늝pr(i(ťL!stcFXҌy>江S)<[P lO&Ҕf}u2bBU 4ScUޑ)o=0wPiu`H\qZUf@vZf NIv! ##@2gpa,RFRF߭ܗ/~0eپN)&7WpXA#k]G7jyC&?? FS(@yu N7 6~S_*rIS9.+ZL ˈ6`zfPB`3"ӋPB.g6 \yP&"2bšFYA*jq Ѡ)VMd.dDEeN9>A)iIѭەʘr?46 4X!z-0 w\s) //SEs6|:N$qhW_V1iT\[60SȚWl8ƿzs` k@]^-q>wujw!VEOFUiƜXrYn,˘96ix<9GDX.uE\ Eza!,ffӔS&I,ЭkSk<<a^/ ºktLC4#piޞmFb gЉ#0¯IhRLpws曛x<[}S!y|z=6jԿx=6Yo~R}ٍ ͷ"nTu@ 9QҜK(sՉӶf? @Mlujבd&$ddź{-Զ $/qxcjN?|]?k~o^\v@1O%&v:U߷~fi.i,V5 0 Iw7oh o( uݞPUMҢbt~9SB9"ϪBNiN^?9{fuso~hoM>BU/뫜5x/ǵ_BÜx|]_? ~s-Y P蜚&7ma7IY]T6-o O۴Y0qH::⦉+o<ݭ 9B.snՍ0di}> 3YVG]S] dNbxphW/;1 *vp{7'zjK*4MWU8(]ۅS_7_Ukv,}7կɍ.dXL=0/Gns>ci:TΚ`Rf_/s5JCyX_frs*9Y+) *9b6C+FBBdP(g |y=P!sTRx3PP([qc jzmq [}ޝg=zX,8<;onח&윈xEcUM uɄ}-A$$B~+(erevEⲣoַм㐼A/Omǡ?][XQȒCKU0o͂qS͉o֛U{,Mi]3Mlu|w+<\8 bx7ǣi.FBU$/ϫ m;MBDitx,SYN Î1ZJ yJ7e>=00ٕDT-\#:wyN#Żask){L6>-8[."XrUǵ]\ DAFwO}EE5e! GK0~{q`sr9*[a7O2s|~Χ\)o,8sqY˘u(8IF-b%4EU*'lm\uwk7cuUxE4i||ޞ~l~< Ѐ ؄ doZ>4JDZCOt@m8L>}\ViwΚ3zd"Zv?Nk.u]Vijza$+<4!)9%"d8DF/NTE\B%.I_bpPw ;gIxFSu k(y‡E0Yz 2 y$Ѣ;v\Yf"6\HLv> &ZAiV+J6ɱ,(drHTb50h  "AE0+95G2}rN%A@%8G&K3 bkJv~nrӐS T|>vmҟ4ϾM^Q}uLI9}߿ȇ:ɰ7 iiHc hr0Unb_Wc~C{O7?XG"+I !J(06WUC<<ͪkWa;!fTe]U^LuOa]E"h7a 0Y^9KJyvjU7/} L]ßW>UCpQ/,``*pq  _}(E !! 3iBG T PjHH؋p6D0 j5AO%eOq=(gXٹ"R2!\lID&ifq-߼y }MY]*R]q6"^߬oV[5OSRR~ڝ~x<ΧInM1ü\\U <,b~~ }>~x~y]|jCR":e=G ADsvK̃ͪ?պ}zzP*o_s4O4A܏|wjPݱZ u;`/LUW1K9p=[v ug( Tmpݴqi*R޷ aƮdӡĹaTpR!&L81MT+ @,XRT.)"DD3I8mVf㹲mZvND2FP"2gDedf&J!19l5Հ^cbbGFҏ'"uB[̆ PwΑ"]rE\wժv #{$vL,HJq>H hfj(`"`؇Pr)sQ0@c&tDs 2@$BD3DpHlFHuՁsUU5G2ii.%]C@DFDαc":B,9 }fMS"%jy$s2Ͳ^]/#@?|`ti^hC7㻟,]|50_jt-oOӶZ|ó]pLLk򪔏e;v4$% =s\H=>en}p%*107A+dXe?GtQ ,T_}p"906EPY1v 3 ?RN 3jrQ954V87 %zwt\-B=%9"2e lכdutj  i|MU4*ޭZ |8Bp8aWPdqPU~t/۽l* \tC}8۶sp>N -+CIi?͚jUGdV΂\U7umD|~MZl xg\E]M8պ$MeC$8nwo6!0 JEFD3OfUoͲ\[gp.v8*|:/U(Mۦaf`"ut\֕B@<2H)@|"ҏ O r`@W82"!&N8Y>{gVOs ;\-*8~xl!L+_JjN 2(EGz-TIj.v)fc*OkO *3˲*["H d$WE=o%%Ȉ]O8Nl܄fy*2lyC1fws`PPCC5,x(XJSSX!k۹q_U>MM݄q,9mP2dY)[[n󎸔 D~=Ybjs|i9ωf$򐜀 *;Q@8ebrJgW2 AмCvpdQpl !j, }q"(0d2S \0CI &09iʧ"AjaWonʧTq>P(BaOY fq>OETmFu5W^=H!dG4J$ww7iO61}F3Δ+ Ԋy<c]U N\RVKفF^$·|y* ~MsW\wޝ?tMpMnizu9'R%k2+"JՂI@T6Y4{}>Yؗ"CKZ)9fə n_OU+.k ^&P إF̂ P 0X3d_  df ""E洯\AdQ }Y,3߾+>fx~R9_9^u 0c)Fxj@DU\V:պK2d-\uzyyAfӄ.nLP0(c]^,YO7ղj^ROݺ;D>CwOslF?~걋}$b8fsѻF 9gy>x_גEwг͢jHʃr2q(˶/VEݾ2t:쁝 &fժ y5?S-m| Ъ1QJ~USRT),[gb+~})Kd8/ z@t.4)nG28s=`Q "p8=[G.]XqIYa (z˜taq~}j7~[!Riwy)e&ƎиRyk\Q?ǘZ%),n#`E[U`D&$Ta!()C b𺇻y|x:K+(9Ƅ^{q:;ѽ@9xXG(1((TbPsmөp~UD!YJ%"DlUQDE2:.CPTT"p6`gmX 3"2c˘&dkj85qȄ$ DLY-{Dh,3Q &fL06֒d%rl'\r)IYfcܦi!o;K)DV$F ]ZEJE8rJD(Xbx"SE*2>QUZcPQ*j!`YԚyYAM9E!AN: gtƷ1 L-"TaNZJi~]mq>w5Ei:/"X>>%U*H$סYR?U0@\q7Ub $ j4G\"#9&/3ԵSoN?l.>\߮3Yч*RTz$A[\gcELYP jD`Rk{QN#dg.!b( w!Ŭ"db 2*Ve+ 1DmˢNrYQIH1a Sssae_)&anITDʝ!(@ R̨Y"1TbS B5UE բm 0UPJVF6ck=s]v|O &O_mtIft<[1k!lkp[hU[,U w6psn齂ʶ>q:t0M?<:E8I\_ֻ4;Ӈ vS SlwRf{0>m/.ȘជH.Y<}+tʳME &BH 4#C6X%Bo6^w\0;g)|4-ׯ\Fb:`# ta߼^eެ)lUE8{VD+bA<{UBE-(U`G٠t# ҹ*sx歐q@U ɑhZPkIe`T//c6@eZum:@@EHJtJ0ͧ9_f~r6xx1u斡g>S:/O=C  q~~}~/; U)˰RAڬQِae$ aRTFl޽/nLrcs4Z4x9H>ͥq!Bp֢m3fSd+DfO1qh//{`:227Z6Y!8liY52D*211IS5xcxT-;(AcaomUKʆ Zc\†y99wqI%UE\ ˶U08X[$vU+!ZTK (UU Ex)Z}4 ꜵh\%-Z mjcero]3(eYbZ@7m)$AV$BBEDd i'E@YPK^s0 "TEU"֜< pQ&-ZGMW`=O OoLRTD`k[l2H^?~iXN9(sl=7X%6+eMXRYdqLǗfsL)^|z /6\,쮯._2x(yJQky//nެw1}>!|y{$cl-1!ۊƾ0LOW7s7GH]-grś8OSvvF;U\ *dqĆHY Ob=MqTmG^W.?Wכ׷wi|+A tج|ۮ:A'5B5góLһroo.!-r}\yU,SyOuO/u<_lmkMi4ߥ%cyMכ/1r p.L*Mga%<_@ Љu,$@%Zb03veA {x٘7ۋ\Cj46F4vDv>;\̅b H UA,Qt!TE@ϑU"%N_ K l("x%Q14)˓ 'c4\b-M;w.D?ƻ*#EauxWo7(o߾g2Ubl<bkV~_pie~~?ƐH\~iwp LsXɾۻ/׫l>>=H`0.7f ؗ}jθl4{|z;OWz%rMm v^*UZalrq/~vM #l]X5 !^\8T|yL9 -쪦*"R,m%l|#K,tqOUn?aꖸß]_wkn¶qn/n_yb_:y?I"b@ST88#]Q5rZDq4*HQ1. j-7aKJ&2( T!#.XQJxEğ>_}tnԜAxB*v""&(AxnPϘRrNPjxdF %N̖TѲGZE"T@D=sX)f)*GDk[U &&PaQ&`-*m&ݒ"4SP@Һ#jŀ"oZowl~ps?L/7C%ߴ^qC#Ibf5PB̀$k"A8^0n-SA>!7vWo iTuOy4ي ;bþJċM((n8SvCuxy0:\mlxf,4- U{T58Z CZᄌrJ*vCN3Ymh|_7e9]?=NjX4BD$?g ^ݗW_ /O}ƿ}}۰^!_|yaY&s|:e$vÇ{y0zDuj(A1)Ĭ-wn6vWZ|wRp+muJ1%M9Wo./Sab=+,x[ؔch+mnj5ڶ˛2%ǘ޿{yjݭ\<ή#TrZij)T@T-%&3dECNzVNPI IDATNCU*84%"LyfrFXD@*Hh|30"H`RJ|Hx 6*?CIRTjXg2M8b)%KdM= ['Z je fP$b BbPQ.EfE4e%o;ncI E ܸ-i1Zk-R8o\l0Z2l0 Yoz  u)iВ Aӵ)ROefPP)Uyi?'D0,ð?V2PdRz/Z*y S"Z*%RTȒF:׿mWje,U4nWK1Dlgk z/E+4Ke@3DЀMwOa8 PEe(cTda oK>JXQ }Ε(2/Wh>ԫp:]kߵUAA*DjN w(+o4eC cK LSsB`PSJ2b)H͛wI~owL5ZX8)idLl ihvJ1NOq(ovxeN.:aXa9X\cEefL@a8-)2sYTya׊6Uѡz TI9-GP3Z +bx2K@oKL-"d([[o)jΠ_^y<j).Q j݈Hӭ9w?ѵZT~m^DSZkZ~xTJkݜLχWok]Xef^]j> SN癵ʸl}w_ K[Jn"%U}/1W.88<R4 i^f%.z=aL0+\\w|֝SG/Vk 81gQT+>6-A"lZ]5./Oie ^?OZb'(1*h)I 6 Zs QHL( af$Bg 9MϺ" PA $P (01C)ϊjJJJ֢mÐ_a̒K'}{wN{zǺTO<ͳz6I"VU%lھ0b2We# Wovͯ~ zk8bx 8 ͡Ük%f3O?~Ne4mjx~>=r~xx۾44=*9zCmabdcB#k3?fئqx/\6ڮ\a_ivVOcV1$vq yX"Yk FqOøZD\Yg0 5,<]]JcEU"Ӳ *kRfcKYVM’Kޏ8Z/,ϸZD,lO)XvMh  ˲,K$"fdFD1XϠ3G8!Pk=D}XDqFA}h]T YDƥ4/X˂P ! :/ |4DBTX@:P)yƱU4d-[|pU@6Mκ3LE*016Lxg!@ 3բS," RV$g@!3XlYA’ҩQJyXTr4DQZ0hb]u>4(tțI uJ q?Wh]g5YbKTҙbR]yߌO+c5{yo1֮5qzqJnMM_[l;|{#K@\˫&1@YPtOwss ]7uhŚj@`ښd'K.UJq#0jk COA-c5rx/wgc mf*)>O8Zg "﻾k xXzככ^40bUW]۟,@?տ:??77 #1qT)1^\otypjov:qBqq^%;}xN:\wBviBw<=5ύ{XuQ8,[7KXn~R.)} Pr%o5m N-ظAF{?ʼlMjkGo\ŘVC6Ukdl\]Z|^)犂jSp)__`Lg-R-i־c˱ylWJ@@ia]=&?畱ZU.T]uy~ZߤJcWTᤓF2˜QD4ƥ9$ u0aӐ]XmKrRoF-PE Z.ĵ z UbbEmlDԃGlUJ5Rg+*!(T"fG(OqLblC6ԯ4YׯQmsK9#U#TRЀfq D@vRV wq5> 2/SXgiCmA'g$BDX-P~\ W)5dDt^jA8|l "9ZEX8Ri3e)*t_ cF,34%"V99Q=mYv4lwLKWdX#~bfee>w][fΩƹR^F ֎i7iNϟ%r;H+AӅBMl8_D&{ V˼\]H!tջ ]m͛aI{Zj)7MK -ӬU7 Mp7^"z-T3tX;u|zw,L:N-G7lۦPmZǴZaʪsҴV[lreMoHP|PDGg9B.`1nOq~Ԡ|˪Jɩ9n\7ъr>.5ggp|v-]%RׂX8 R&7{h&T{6)5jYj^<[ﻆ- tDWnR4t*iy&xobSsɈ.ƹT:O 3HȼQFP*ZU,iͦq0W (0y36㚵jE2`dT Q t.ݮƞn,f\Wy)K)]pꑥ&sCcߴHǥABa)K *q~>?۷՝q< lLÂ]Iip>Ǘ߼9hCW-' ?=USCwͩR4)s1D\՝^պWǏxpElv $"B(JRٌ+z.Z$y@2I~m )c ~w,EQ\\*DWR@ %TEc$&S@ѱ3R8njNŀ( a"P*1fӵ]Okfk8D:_'Tœs`~Ӹ,CV91Wfd S*h⺦)Z.}Kڄq X] fb0.bcY&_oyUpse}uyN޵]-/o)D4O(v\s:|u0KZT%c,%Ӛ Cp7ۍkC%-E-J`cɵԶBV}Gi|N-ibԻnyz)s|㙥ִr~ul6Rۚ%6^E3.8 AĢiMWRE03DBAsEt]x|>5#+j́TؔcpZTuМ]s0*؃$CDL z7]qY hܵ)- $2#"IU$ef)|~!݅5ꎉ T51S"K'rM%4$qjfJu WUi*` Ml]0U dMHv3ԢrM2U<șZAS]e:ۮ۴Qe&>(UT!#)!JETڦ T@"B@ Tj y)s(2ZȢA0JN.JjB0Mj ?<4dDt HU@TjD14  cTf `XBz"?Mu];]+Vt)  k˶)].~c?b<[o|7Ζ f+޾-vo\3Q!w׵{3]h|E`d+iWr :~t{n.0jN"`iAZR;ۗ˔ܶCCr9R yhs4]kԡ!fUB"P]Ś ̮k7/xHѶM_ڛc,5#+.HDoB$kZǧO7Rt>jI;qM` ѓoeIbruqūE!U4US@Ȟ|Xf8+@hw۸l݇N಼hݠՆ«gO }xzyWqCz3aӝcd?LR5HcYSo`տ<,ont>@"13#UmmMYow0 ѵr:sF#<qa>O}7{W E] e& ~V[l1-})YlR"s)i2OS۵}1 ibM; _jMu^.@W7(Ú~i\ {.9l@!k[r`сT%6%4;fp utm2F8^_݄\RC|MQ@BbB5Qc U:$<3kU% IDATZ 3E4fM!\ jUD!z"N_%@!_D\`G@h3$ hbR !Rr7gE*`BDLӔjwƞ Jyiɔ  bNq̹4vY̜w$@F ~i~9]0Y 0"YT6O+ׂ4ç?C[@t*e]$B{* pUׁ.<4޽[OOO^IV}5:?}3j56~9@l;hjir/ zvwyb|4r_݇Н\k@  tw*kZ8@4'Z Xy"_׭^˄bX)UTڹ}CJ6锦.kYTf0c@5}7!3A0Ȏ@bw9nt|ß?BM-uͫQrY(p}L8€NIOcpZH9J77Jk5:.W^OOia:=-l1*LMo};Bx 1#+`X^ R`$piepJH<.Z粊eyPR@QZ*5:On?̙N#l^j̀RYQk9\e+e FVcbɰOW%f$V8CBs̈I)>>}W˥Ӷ2(%]t?=e쥞,nit,۾wk)eNA5"Y~ _I޷ۻi,?xI@-o xfWlh(UܾeT(R3TmK|?xyz~y7iz|qw;7L]qs)6mFyHbyz|uuey 5MTs!5Nuw4urhO߿Ogd 2u%|89ܢffAuDC]islM􆊄ەE+͐330esFj]? LWYP-|pq03܄dÈ́CcAVu6hBF@H(.Bp C @"Hy1,wm[LHx_pȤʗeZH_ b%F3iYdj̦8S _~03]ȌD]0w$Q-X2[l@*?CӸӇ]8կc$]-dq\km#wy"͵QXWUo|~>ŕz|~9ݻ;ۦnݗy.iihY2c}s~p.Xgc.tz҂oon\kb_U6}ٽ߽ ~|Ӹ,.ZmO;e}5 7!FFu]3!t ]X%eK.ֻM^ :pΙdsE)hH$`VL6]o<\V]cI "C\˕sUWqCnnab+u5] :y>6ݮ7vC24e( )Hzo6Ms7wI|޾.0:p_$A~z<̅>_ҔvtHM 6LCii~'w)᷿U}[2tDZ2K$B0k9j%V @RP" H H".Hb̕EcZM4r<%›"ݲpI~?H Y DS`uԂ5&lT<PyB6+b4bHyETҢc~sM+kiݦ{L밬=yƹG0<=}~>~ww߽Ch MD jz)TZ@Յ>p߼\.SrsQ4t1,~'5Glxor<O^K*c brD۟.9M /޾}@M@viۛ6n;rmf1}~ۯcl6o^~;tn}4\u:x78JYڶkMuͰ'z 3 $%%Ǯ..0ͷ}{{Ϲ,DVќGA*JXzXۗh'!jdV*&seV;'w6sר<3Pk73>ME78n"GsfZLHٙ@:kRĮ1%@\+wM+ b/:6ѹ ZF2q$v>33CլZ*!]5M2YMZytCF]F(d\lZeZ1-c-+YD@&N+35qsg M/&3:ߍ)"e`f`Dpm@9 ;$@ p~כux|~r::}l].37lm1׼?wo_߼y8-pIIARݦgiM*Ljw#149f|:Oq.|onͰqq|ӹ,,Lx<$}*sz}ͯոֹ/)9ͧE)ӿWmMj+Uk17n88qo:Oue-bce9Evon@PIa1[%cP C6J (!8mH65X") 29(ŪBtαGeM=y"Yzr J>@۸m\7loߔR t:=~`{}nP9/%9m[| oZwgGiȑxku:=׉i:2/׬`dR_cc)WYk^"5ov!bh< &Ha{eZ.ϟݝ?܌09 ^ݟ㦏MsY)뺬nw1b$PL&Q!:3 ! af;jG̵lc16hA qhChUJ @kd!&j(Ղ1@VMj ތ0( VlN{82TCuޔ}7&3d{Ikte6& q|r^T^c9LN/7;"p%ՂFRKIۛӨ/ص~|mvq^#~Pdy.N+Kin&@ (URYC:W8 C kym~}5?P[Voڡ<S78PPHUʐJNsAp}s?Kq_}GBwpժ& vD75GrCa_~pl,tuwain6CTP".2@=LͦENC^ |泮2]DF_4<#B`V M5 Pbv Ɍͮc1Td)eIeR ޑ.iDZd&HA%4AEBf#a%O;Zk+`C:G&u-rm}4&9ymuc4^0FtN rR(l 2PvLQ 4J5eSt~aخK~~>5F@DV/͝V"TcrU@φfp6s""P~w$O=֬;3UXՊ,DZYf3lm/ir0lWq\JY[|+ ZL88asJd"XyBmm5U0uƕS`ST,HT5@VlʚR Ri| 9'&)Kƙ%_8cHz# ٢rXr $Y\b@~)6fxrnlTo 77mϬf>(a{[$EyjTQܶ ~>A~0{_Ex F sLNՄ9* ϱ&YrIub!Y4j05"HU 89o-Kq2br# m&E{†5)9z"e>^ Pz,fJֺ&{M ='bFtNkDFxh!y]GcJk|N& ڏ?~]U}ZP#޴ZI{贞l;_=9>|j{u3U n^~:>Oy؄]xX#Y׆fl|;Q99fͿ{B5}<z^g;N%:amta(o}??Mpz9`eA$5RPd)+ƅ sc1' ]64-];Fw8'Mi=ջ}~~I6 E ]q^$n*ܬ󺞔vAWrJjJW%PUQt` ltfԴ,4e:#fZ2t=9B\\ɲy:{7]{yiW`vmoB2/SD6^.t>]mzOݏGU çB}dnI8"^R%\FM㧑޾}D Y$\nujҘp΅cﺝw:e8z2sz&51iUuĎXp8!LJj+h} cQ솎^p ۣ#4p58&Rfh@q0݇}{P)eш;L@lsn1ŰA[lة-JDeEnE_j51mOO/OˢLV(˲* wwR[b70Qk6 IDATꜳJdtJSIQ!ΧIie{-%L 8.72Z QEk.Hlr_KTWB XjKwM92KBp]d?oV[E4F43$e{(c2חSSو,:2@#VUU𔏵e2rԀ':zx?tي|>Ua5iŤi3EUfNe=M]Z|peGCHM U@j-4KW% r̀{f-p7 ɺTli6L}E . s<W!dnɵI>EZtKrYK)mv|{zB>k2GG_i^R2(Q}q u㸵L}t>YU:t!j5 } o6mwX; ldVՂs=Pͭ!#E s̘KެU$#& %kZTp:fpGΣ4Q#z1"7d  mƶZ>:18G^9CZb*bjnvӸE%4ReDU]qVS]tj},6Ua˧3Šs&pE,&5}L~vxJJP~-?}z.QhfQlcѩ/ L6D H"{|dE'u `fA '2j2XnPӮwZI͜hl bEfM!e4QGVox1 :F$b"'LE҈RjGU<Šy&K0:j3f,:7W1p\sK @K)uq#*&֨"1+0:~=̈́]nÓ Nő@i>z[s^3yk[fm4{'Ճm߹9K:pA-2enpg7!5H?>sxsǟiطyZgUt۫TZ^}9yץq 1<"Tk:7)XΫ\m}S 覥Aalî}fk9g!RPb=K[C.&msj]bBB#GAA-> ޱj#5$R/8{3EF oknet.)rs9ѭkw a,uU4ls =$\.$j&>>97ލ%b=6w`YLUL_ "*PL ԡ"!ɦu_|N+a9䒫RRz!2&pĎhK!"?[|Q.S&h(50 !DKi^km<*VA.Pjv3"_~ @g[@΅Z2kFMC/E'.pD&m EGaLؙq2;uJ6fLDM213]H>@Z5jZ_ޙXt:3\DD/|@4eAv3a켖|Z Yj77>fPz^i >t~x5~عT CQ.Ck9.xo`etׁr:ãKݛ뇧`nǏOt8}RV*t z1GRѥEj&蹭}vl6^|ʺ{-h6WT3mڑA)Pߌiqvo{}>@BUqmRǀHf%^rnrYNmɔ}hM>ՇnY7])`p9P jBtzaA|S RܔȆA\xRU'JM EԐ=pTC f $kPԃfFhd @P=Э$лY@sa cM`rD  1Z]mnonixǢUK#Ag*uc4o>ݯOo!ZtF_o2'ijXAr[={B*.kSf@ّ . ZkIXUX'@Zg+1* Q\0N *1:+VV xd`$sBҦ.pQPtDAL" l̈TAA[ #lOU`3ZEV1{&3Oat|Z[m{1hF?~:ŸJA7}e"1RJ a:Oy%W,HgI=/Ǒ&.v{χ7;hr.^ݎP,e`ѷ$jd!:4SHknUq^k3+4u"A !s ٗh6 Z0TCTO@~lI7cEz )G1o߼s:OVsպlf@8OŹV#+"!#"|>8 B옃&׿_ ˚ @$^&h[9 մd;j/ozU\*Mk/zL* Z.AKb&b8=77tz>~:Lk9^M"{y7qLDM/~X bPUUfFbCٰSi" cRiZsˋ2yiQd@kkYU9} ETEKH.ľ ވ=k*@D@ 6P!&h+ 9g׵|\g!6F40!֞1%C ۇ_}ZNF9ZtlC߾(x"ϟ[3cͪa-pfm7IōvH1F(Z氋c&Ma }<083hC2C.0= WETQ= )41Z0ym+* ꩶZ,$!OF`FhcDEH JiUam}e* 1m7}Ƨ!TZֵ֎y }hsӜ룚`3jc,}eYqȒq34dW;pK9={,JUCcB]zjV~(Z,-[|w=uYcSqqgLA| pyDA<7E0sEi ,ЄVQ6hfhAֺuo.:م$M;[p ))!R3# m P@ ])Xy F):C 8Ct`"L 6!R(:. FH\W䞃]t.(]^w{ H0m'?bLW$^&!x,׿\mZښ҃✗[^JRH9msy-9 KN]4?~>wt:"k}u z]R봍*Λs|:z>:-Ӧt)Fy]jͩVnO,P&VsDRT۫.:e0X։yЏݦ?-S`3ΩE8ge?/c2T7 ]+TEK)//:Mz8"Z_]43,M`-Jb.xgV0ιR*111RE˚{)Z1frz3LjM؜S,-?nGC8w~J)v)45DvrfسAs Ӷ,HeO:)FZj0V6B'惺ںmJ]8 R\m Š,{d@h>YWl=i|Xn߾y-;'JE?}ιrڅHĨZ75ӧ?$U<v4, v1KۍY6m 0Yc49a~z<~ʯkmbxpoB xn%L]QvKr[r]4ux>!R ]Z3p'e-kX׺J|x n#{ThT{@-3Zv!vt켔x<YS$evėuvDWHީ4vCT*X3E[T@nz<|z~eZ˒uGZB~7y*(҂6̺ wh0OY >%߾꯮Mԩ===Ml,snw<,vO?4wjB߿]W{z:D!Hxʔ9l2q 4C C_U#̜='h !0:u?]k9wc*bg Żk/c/H3"F@Q5QQ7D$22 rp)bOLgs1"2!1ʗi7)e([͖Y8 &Wm$/ϋTl40n0,W:"uV|tO_)_oW~Ftж1Fᇏyz~DZ#n͚T0ğOI4zTfj8Uwo޽wPo'T\jpFGW5h^Е?~>~wk9^N7om?F'9<mVRT~i?ٻff$vV.J˕@ysȧ0>}1]=Bqf_Bݯ.Tנ:v8 nս78D k1q'E0{Au)DD8R׼V̚h]2MN?O糉q !ܻ#j1,dŴoH"Δ\ElۤuD o˜qUGBoB&FHČ  P 2uVy-EiSP$t*zɌUR}y/=|~/7 3*`ŐV XS 1յYT R ;1 ;_D9eISU"ER<3CjfC63 !V]' QU#"QhUEQTإn1J$)8&&S0 "v.y-*f*zU)ٮ,ӏ7qz1f](Vh3ݶ>/Ԛ`&R -ԕ* ,krbl.wm޹p,y>k}cDp;$?~n3d}Cěս};ׇu{=1)ԍi^]qцaȯh4rμݼ{h|¾zTbM0-V ] ACȰG7WF8j s^Y*H99W:=}GV0>*_ZSUSӼOϹqnA,k.E \Fe]Ju]fM;~K)e\bۻk+µ +>p?l5ssIwnrG,LG|{sպ(/EKhd7_."|2n6t8.OO_o߼nz:BG$ʹq&Hdj`-FO-X7R5QUMԀ(h8߿uȝ3P\"?S R(\02ZU  [f` ~?LyEkfVPĊHf&]*48?bJtۛ &)#8r1ԯ̇zLכwM~> 9Wyc9&[1:eˤn}byo֖I= 뜏>xW|DuL!c:iӺNϟԥE˳NcwݏԇǗtxv Ϗ7Ѭ}I-=ӻ_?|Cȝ0 @ ɪ`!WZ8k!r鼾uqpclYJ],8Y߼{?j4p.|w`cnJiN.L&uu]6˩ExYagمL۱bSԅmݏq;D o7qx=!5`|=M7>Q!ZVBc@B7b <ͧUњdW%4ٌChjˆ}ܥ#wR Bǹ\~F|X(zhWTa<ໍOv{}Lӟ||Ya=*4#l2reʧgfִybg䌜(8?S65EM_Ӓ+ 9R̎y1#F&ET#3S%& .9Me-ZK.9/χRZ??Oϧ$":O [Xw=ۺ@|Uۯ/_{6llrד?~B0q7[>X޾=7A0ZVn 30V Ƞ)r{'6ꊦ"=LhH PQr{5w,s|p~75U ǐ=-f L/u>\H PMV@sF\ćDRT&Fw4O'a\2Y3UƂXT ҥ@Ct7͚'r9W\ֺei/YN vvӇIC3vdqCPͅ8?߾~z:H|z?|th]xw1XW@MMj#*00Iyx,כQ âK~~(-Miyss(=zff.qs=D^|r_]ZY/o,&XԶ.޼|mFnmyﯶ!sp6$ -`vbZ^ڊ M6Clі˪VӊvHnRy]̩v/|m l7>P5s}N܇\B S*ȱ-cʥdTS`fbKP4#VK5a&l>ZJbf 7PuH  O1eӊhm wU+|}@^4WO4#XJYҲI/hTrM9ObuYB܎ Գgr.~s7.m>/= /'@&ޣ)zO1ckCuyeimAhլVK5Eff;y.e=39&bD"DPE$RCLfM:O*Mie9̇0#eyy-䦢vYxD5E"Pmmr:iV!%CT{{fD5.VEږU?oaĨ9ۿ0MO埣{<<=6G.*%#nbS|ߧӹo}!*t|mE )y(t \^wfxץC)]}t"K̃|>+%nkM`ɏ7oimd)( \Vk+bKK-JHem/kkUv8DvCPtHxnTpWi|>t+1TZ8]I[}ׅ6-= CH]qNQf=~d˲sDŽKwﭪ"@!h&@Q",w]0l n5(@am$9<,}ymkOn'"lanᵃ⮾r|zlK +ϰZ%UPHᗹ2B[8/|gt u{l x#7æ~ X+s\/?ʇU& dMcIc'1<||*ECY继Ǐ9sTM!p6=.eYVN]#L%~OsS/CǛ13K4eR7y)ӫe! (R׌rvP:fJO7ufpn)"C< m0 wt{k0jZm2cZ"S7N>v @~9(;( 0"^NVsZć" Pr0n%MUM@[u/|VKhizkYBRu*ۛk{zv22&x>-yNc ]q[VӴ^Bmuݛ]ݾwR:0`V|VTՑ˅[sPDQмkIQ@а_YR ;z FnPDdj)vw @@Fhf$+DFvsWu7u ~q!#!Z2`e c,80u n:]2"WsoQbߨ>-ZF>H gXN}f#}ol"@B9ۃ fxt26UbA:,w>>m0jA&`L젪vMDkXѧ]bp7:]=y] =A>=\}ΩOti>qݜ?BdbFU EZS`G @`@&Ԇ)uں63jIyZ1VshNHM;23^jPKMkJ}R  U5G˴B , BfLĦڅ^(l#(v%P\m>>~_-?O]sĚץL8]#\P>_ &gxs3bZCnkyz.OXERx3b)4FOc!2tcw P/M?k5Zf])bn痧2Z<9!HTjyfHCuk]/>=wphpZb,K||?w7:~0Ls Ե՗ 1bi PV+fk+Б4r<pp9p7ލ;66qOޭKW[6Gs.]߿L];6c͒YZv;?n ,Uc]7k-dM[3AEF@ĨWų#ҿS\yDWA)m]Fj htMS&`DPmQ7w+{R-O 1tmͮMO;imiM:mcz:?J( \fŐe 9$ \U<%̕3hv-VUQm\C~i;B1ZӻݡPjSX)2 |nErǽdDxe!DaaSm #k@ֵ0nԹD8tf%@Rܚ)8@w,w_zm?q[RJb j#6la:xIvL]71=?}lѽ߽(Az.ZHJC7<==E16i; zXW{9pD'S]ZMm^4/8~8NsEIwE'bg %ƪf@͵bI IDAT0yi[2@BզЁH1+Z$4j^ , '7 ft}gn(θmw]tJCb ,°/Y:b B5JwǗkAul7]jc "N=u%OP/ɓgV̥\8=Cҵ5x!^_]vnŰaQ1L=Dvd'V77js8]8Ʊ+A?.Zs NӼ٥UX"ETG(nK1L(!d0Y+V $شjsB"@:WhFb6zIBY²櫿y.@bcgT]s0!'&U0k;;`,,D㍜q{;3u}]w_mI#^<]M;ۇAw~8Yn8b]KRlIo|m|pZZS[-fΒkVfeϧƇہܓՇs5[ GбR+^Š7v\x4MȄ̴g^|~s?}z27ba`׎ۇ?9)/˺5 ~S+ m2M)ȷ_Zv}C|)S/#߼! Rlsv;%9m:XuqwteQli݅LmeV`^5wk —<Ʈp5vty\B3WWD`LÕZʪxei/LTwT\4—9.y*vl[hZF AN,H_f~^9ˢe]i-3#r:="Wp#g Z]S}bk@nlj- i37y~:r29!^ݮ.R.]ԆᆸK̄}6Fэ̑(Ę-dwQPŕTmt\ 0]O0KdDT_-7n;  Gb$$wR 1rQ7ޝ9ususɵ;@DM[kB D$f^pD8x$֌cwOk~;?*;93 Hs8\N.=~OO| DwCG$୨5'eHCp!'AǭDZ ],e ]׍ @i:N9k8zmyhH.)P}zymcs'c" †FYjkq>OVa7vH~l7! @ֶbAYDD퐺uPXb|^#"4תe^1ju],"r:ՊS0t.J'6 #`W|ǥTW6Ӽ{{|X` R,0Trk2ɏ+2C!j=:U K1b`|^1~7ZԵ1\1_v!D& Z~fܖ<'ؘAnqȧi380;ӗWg&$tp3JyWD`! X6:OqD}SsF74uUP5UgYɚ-kUff |I;~\j./Nk/Vx R\ە=jCs"6s0pg2C`pԚsn)TN)֪զq7r?A_S U ^~k~;a#\;[!jЏ/܏n:vRGA 0JdTF% c !@FN@ܸi$@ϏZ_}[\^u<0#z[wygc))~#:^iz! }z>CB^˅-y{xKa||Nyq1*Hp`:~Dw|'Oz{sj~?icLbDv39p% "8p#ZQ]mCz:WA) 7>bON^ Dv>}qGABjZJZZʲV[^R2v{uCHχ7հ a3CVJ]wy`$sQs f$Bh`\ NTI՚굆cCvAbPւfKA%A%~]zUbJ8X%P`+|ǮVERaz?D_yYN[c~~ JKn?p{h~|lF2G}Ƈ4 nsd.T]AW7n}n˼;sH(, M:.Xuby @}n .KC 9gOn78ϯl iK1Zt7OOyoG*E-k,$WAt -3kL,@jZJ DrRm01AWn؈\Mڗ2 njZJrJiZ?y<}:j,܏۟N}]Ф FRRsһ4'$<.k6>oþooLZ&< n tA#\`ya]M̺p;Z`wJ qH"d\gA(SƟJ}$%qm;)| Wbi%7r||?8J %e-8v7H7}%脦]gy]-Wy*]?"pmiN`Hs~}ηe Qr-Xy%r۷Ch˥"? EǦaZ\.s>7XI.-UfK^̐ZRzM}Zgt8P$Ev)C~7]eBDޣHy/SQOmg][+@}w꜋VX'7Jq7y]yC (&dB5U$nnۗ镃,e9_&3Qjݎ&1 6D2Xm@m?Kx^y-V$9JN~^ fie)v]5`##8 p8v5 r ҏnhO)۷5|ާIc}Yui8z\Լ56NCO͏9]aAmޔ!tVץn;^Ը ;a3c&xB1m @]PYOǬh}J|sѕ2ek-0r4pl  \.)n&i a9\ ՏQ щ8_'hj!US֊;7Ȁ A_ȍ 8P:@S"[!_^ e=~[309.]U}~/M1Z.$hdsϗIsk"BP͈ /BfdUF!Ov/S9AzZk,>MC7RyS^v[ia9Y&lx:>m7xCNkU+"T+bh"U \.:0eֆU¦t1HV!X6 E,)Tyʼ<i!H*o_C;?<ݦ+Y04(kN4^U|sČ sw P7C{Hij;[A@t"6((y|vu)\.UeK o^V@j[;^֣0~%-o^8Huɕ} ]KN@#t Ŕq.fZ c&J(Qn}S?qᄏ9ܞG,Tiw?'!() ]3d",ϜEJfRHasݶ)=ѵVkz yG6mhZMSY DP՜c'kRAEJc915B 55UBBfDsbtb`j( :J2@M|Cj~ho7RxD6MP֔yv065=Yu"BҼvo^!}7ǧƧiۄ)wts4 K!ԴmaY4Nfŧ Z1vk$ΡJ!PӦu\&dP91tYd\]!M/R& ;sRwbiنᒬ-6>/<N{at-ĸPJ^ʧe}P@ L!9dv ?<}2nNS*:F4 k(V*"s| *;WK\k71ʎ) )1;rv`F`?ffjɫe#qb1"$Eڦul*x=@_z#"uZLNXբTD LTI,#!(LyY$U+C`pLdjp}ss,` DUy!JZuUYT@B̥/K>xSLRҺGq9@N J=UKWE7iTЀ UU@bYmMt8˱ۤ~߾T,DW(8 Q4fZcm]0kVqqy]]۞bS[:R=R癄>}9 Z[*n:O)x/["Jt!P̂aXҼ2OiUZ$U%HP)q7owi,î9zh6POIRj6}6bv67c(m}ҵmoORDluM:2rm}9T:/f2@C}Q̩o7/_QM&PKqc|waL۝Gm=a>qN@5vU LE3^uQͫqw}S4(b"D\.bU]LQU!Jr-ԌV"C60, 2+xn6^UTzM9cJ%IwZt]C̢戩2/U|^&Dw9c#E%q(iyy/MnyU)f#1O fp*s^t\ "ɒ ];?/I\6"sI iMSEVa3g[OUB/Sm]aST]voC]&xzV6,95F  7 (dHW";Bb"W FbDflQ-P3UG33E(W!"U5z:D pŦRSͳ̗b ző - IDATm7y{`0_neK`8 ZJomK'UtW}xt_FwD_}XL iLe0kHssJf5PeQb q->KIU)[52 n obZ՛4U-7qvC?-`Yd۴!UQ0]/ 5༆ַ\4,RTp00帔,]K\а~1Ħ@ap%9׵TZqX\\XfVCzs ne|\)sEAkVa4-e趏q<®3G왈WK٨@{q{w>]>:M# d@ W; @i`rB2DC3 5Bb4H@>zOi}]jz\tMCD\)je"de0H hZ!V!!; ;vAI!ps怊s?CQ 1Y>TUkYJRd r.+ۈp]&\- z"D!TT5 W$ aP$E8fiidFVMMULDDR4gQ`rl+v5kj% ؇Vdࠀ Ͽ`b WٕTh<n(n@13xCC H3.X#j L\@ :8!@s?>j[YOSOpw}SY y]5&nЂ vCNjPwx<9H Q "-?{s?ti\5-KfۅMUClLb /6al)uOsM[t,w7+BPmUԺM;ߝ.v Ż7(7S "Iyưs ?=ܻW 'ɂ$~77ۆ$VKr.gsM.UTsav)"`8"j91 ~oPBӫݖDUshicpæ=QqZt܆EGV7p/p:]H5)p7 8w.'p/cMS)iMUiU}پ7[W,m^yS" z1C΅A!}v|}Z C(jLb%KQg !W. 祦DNj`_9-)(Χb C Y*.rNO߾Xאre" -YVդָ{xɘ8#XkrE:+3"GpPB{ms"3R )8UvōB%cWku CC+5&Sf߅lnYRfwTtr~<_n]IwoÐWRJl7gSRm8fd$ `nE[I:+)**R 5T*^ O6X )F0er2V9j  848p?&3xLtY l:WCs۝s η]sYV- kV,.t>6-_߾=ۗ˧3,ER0aJ\5AkX=LJ$j5"ӔGnո+Cr5U| ZqXhM [׵ր1IKJ̎^x*UB·qZԣRy$2Q 4x6U0UA& Kɵ&@E4$,8QUM#]^LWf?khS@}0xN. Ȅv? !yrMXjMB35P0D$#Br(R)@(qc&U29dDڔ `RU'A@@ @5h HʢY8fGE +21tM 4FfZɈ̌*UoUm8w*Ņ Ͽ!W5)4+mM7|׸77rǯ\y3#`@(94LJ@j1 @&cl݇/y6]:_^M0=/9Z/yH.cΕ)q}euOƮ8tj3nCi6YOlT>æ MWQKϘ/3.:/?_r5M4楂s&Z[̾VEwv Pl~Ws}zyk**\ 䔊cpαꕔ9,"uDۻ[f,&e*,&"өq`X֩ۻw[lDi29t ?o|q<ի˗/^ ?@g_o-X?-_*Ԃ5e9`ݬOhgu8BlfѨK)i Vd" YSTe鑶7/?>ѻa.%~qY ;Yr7ow^l*Z4U XlKh")0W^IV@O>g`T5TTPq`LF7 QAJsu'+^ZPFi";VG#/ĩ]yӋjor?pߒyo nw|>]jn[m@՟&<Х!Z`j9KZBbl{:`)#+& Xa]{Z׳z<X֡qdЁגJiԑ֯ |軦%tk̚77e:u;/vsׄFդ<7w_>5u\6%4tݦmR%9n/-Z&*uT(4M7ǵ|ju[J TB(΂2+$l1i)) !fPќ2K[10"L8ZbwЭi)蘈԰fl&p?a34~@ j*p:l]^e JLA5OjPwi0qkNyJӒ&CΉ^ :r{ Ի"=jUjbb·?W#ğ3g̀8k>!a.%MKjJL|@V܆L R-{dCS3D BJ Qbb)Bq]*BАLԪuU ETV@gC׳ !C`fFĪ,{DiK)W(0R 4Ҋ+ƆmƱH秩CkZHmt:NcIԱuLn?o_5rSBmkYk(`?"]K-PWZ|HN==1b( T 0늚UVl]r5fa]S0MaB/b= MTsO_~h7jMCՍ~WeJՄBc}q{w|f?{o/$o/m^$!݋w8wWoش?.o߽݅97])ezkb~,Zk㞙D4uk-ӻw?RYӡŏx?ՋϗCؕ`oϦiIֺ6DømtѸSTTc.הEZz+"0dAln㗧_~xx|z6hyZ#7SOW\stݼn]m ]i?}8^ne{7sLU$SZ5$9d"@A@2d3lYpfϩf*bWW5LUk.^FDь:@Eh(W!^5(`j׼cU=:OE<-jUb[OqXj-`F5]7w?~LdX]ymKlu򗯿y?|nC>@ bJpS]+zbSR A )TcWdS)/dN%F)VTRhbZ%\S`VṲPrmb<ӸiChJ9A^݉u46>$IӧSv_-ˈ;V\u에 qjv8MNsVC7^rYN\&jt8M~qR|Kl DWkB[I)]|z]^gI"Tmeu^31# 0nWNSɜuuu4#(1'5VQ̎ٓs"C.yYaT*!G,>zZ\g'>("xbx|!?./ #ltR =#2;w%>T1Ъe9)!1!"h`>ma|̜ ^ѴJ:- tfOuԵg?+f f5`B웦6; 42az*Cp;vHXS3iyc岤` L0V+ @*3ꇍ Cpo5sV׵aB3XւhP @#ps4 с\if®yu5+i:c!\E?OqL_y~่7@5T ~5`dJo6@ r.fsZʮa[Q7_n[ԍ-mYBs hf;<7`ьq\aLC7G]Zkn2n[GF%><Oվy,lzwpɗ5JeՆ[oCP,u_l`ߵi,Eelcs9Vt~jn^˚֔ϩNfuصÍj!|js>u_eZtZ3v>˸LQM2y2Aj*~ibӇx}w^#(`?DNߗOI<ic/s[Gӛݫm^mM on/\oǏ <+XdgŐڈwa&= vLJo_hɓԃ&]@Oea}rB6441ZE%@|倀#J)$~V*bה!r]SV $_""9X ]d0#y@ ޵6t<9yپr@rџNIWW=zxռ]o B048}ߏ bx2Nk9vhu7waغǦo?>-xp Z$<\w":~~Ӎ]5mcy}OǚsWMb^tZ^H8\K)un]> aؑVC!fPQKWj|zqr:~o^BB0W_6  G i CS 53CMr9[:d@=;PUJ9ql0 V$fdEq;Bk eT C:,9-EEc Ȍ Mv)3Q72ٌZ|u}GǪ42x}燅I"Oy0͗ Ζ7Jn_ÐX IHPt}5M>zYt|@B`?CT#p@E^|aSPMM~4!"?m "H0TX*B)eKͶOs=DR+ت$AI:/&PFr 8bf`UvSː`TA#q(jƴ&&m]C#fQ(/""/3sd<\sx!ϋfS ”JaQG^Q!YAyP]SW#m1m{=w |<}îW7_dMe09:NexӘm4ד4\| 4$(8j}؅ٻ&+3 rE7sa;FMpL9ܵs}{.h^%]}tCrEJ]r) Dzj*1/2O|<>_}Y@HB,JAiI< B=<>e!,m뻉AxxGD e<9TL:ayDUw-@U+)K4r6kmm6HSZ,ѬU<}bpt,Pj6Қ>=B4K ]v_vez 3]Uj)Z84ϗ)6Դ)w RpsnߴìZ<9¦u Us EC4ϟ.ѴsIc>mvs,Xqyi7q.~rWcJXȷ4|Y:jC0 њfRKZRզm\+e;Ѭ́=jj-u0kg|6n7W߇ TA6@AGGSջpd6pdZGQ,,Hciz؅Vkzg&ЀQŭc")д[L5CDř3c3jyRwfDCrDA( 'U6 vigO\ ]%%jAb•KD@2-#Fb=i?x[2ZOtJ٘k嫸,?dkICɑ!4mSǖ")!eSȈeq||@Mmjb M9%sTҾ ɷp\.mxlw|7~#u߷U8ﶵ:1]$Oֲ5d5ǭ̷xY=_#ص5}0в;2in:fAlLԖ: }wf2ղo]*_5p4?{Y=/KcÄ\٫0R}DKJZ/f"$e"(1!ӂ.Iy-SJK[gZf+۵!mb JޛU|ydfcm4*ˮIҶѴi5yia4eJS}l7tu  0 9IJ:0Z.uLR ewAO˒ZuCq?hYPJ.ڵk@m!\H*z:re΂*!E؉8stmձk\ئ>.)=vX=zpPmWsXRN>8A&.Sz><¦o]y1n`9u@}KM $d6MA[R"G2fxL aR*`BTDUЗ.Z3ch "@sʽϗ.n|}S.x{$XI r^9xWAc5/9ӢUuMokh%C2/cLæ1n֓ T.4-S&6=7`6KuoO'*bk ʫT2evTEΗeIK2ɦ׎*ޅ*<:3}5-UhۙU*nLIUr^TUM'-`eNR<;bEbB%3+U"е Z/Ū(@Jf\V3D"dǑ 8W.P[.׻rf8nùiX6.h}m wb{wo?@n!")6A lդ]G d 5U_|W[O]sE+֫Rx.󼐋o رhz\+0jD6,|q1=ՒnvOJ&Q5mWsra U A@RV CTjFҸ8_Nq}vNLK"ZDݗq & "si.`K.n#- ѱw/\awt*?{P)TKI}+A벉@/puܿ [3B$$2 QAao7,l}P3x:Oinnm]T՗4-ƈ9vMhw qeNir.vq0009Z(}MOɋ:ˬ#͗+?C*T&fvrE,WIq$ir¼HbDL"VsbW]/y:IESBu!UEN̪GPժH6ym{Sdk5q*;77}| q:NQLLWAelas*Y2/%:yh,⪅Wb\Ϗ%BIL @+>0%0-3gw]pL]Fy sX=!A5l+0`wi7W2S&]NUny=Χ)Ņ}~/e9ߡu&CtTkӄI̚jv<#aowi}>(67C͗R|i1sׅن ]{^x<SJΣc:fVNVtJK2u\|6~ _Ś/! dGZ^H(ZaiOej70qM|FHaFs*p9|__\{.䛒>.i|m#)c"5pZ j6+f`9#MVy\22X:XkhU~s(j"$MSgZUonZnCY92z`Ix,.ita"뤜'BÐF.f[.+$/y(۽fvMh7U4h}`{+ #Ir Ra ´\M̂V&zy\}##`Pjdrѻex+fhf F/nWfbKͩƱeF" *"uy2ύcf#5+*_. s`X+_1*RF0fݮ J㼰c IDATmTviuԔ{@7mZY |Mnڦ#7 K-KD4eG(ʎ8!6Sp/#BU4SD̈"d=9vm xbgbj0Ϣhf"_Ry&_|@>Kl ~ vں^ x징g`@ eka/*'4 j YLmx:Q-!F$uy@7{qZh{ Z:/T5)W^477W_n;].P o !RB:tX }lC[L#~$|!߽pݹm0tۻI̵bwz?%W;`g[ٓ'ZCh;ϹUZJ4}bh4׷yNbml@T6kx>ױty;p+s͉x;\G{5}̯;j6i\ 9PO}#zFTCMx:=wZ7y>|wM9'dh("FX-(NUEt@%jf_g'>_Ƕݾ?rI)>ϡ%0SQY!,:07 =]N 6,2P!04OR6BPPSvۚRR6{Vpu@w@Rht}^}mzز![Lӛ5qxtip8u㟿+ۭ{zz$ }BgC@:PRP4N_{7w]ܾ=ꛟ}YT?*\i'8Ӓ X 9 D-)gޒɥ*9)suu%zwo:~ ,4D <<y0=SeLC} \`" ! rWC${B"Դ b\XE hPI-gq?Ͼat8/ۥR^O/ev&do,jq̱K$vZwB֊#5[9D( JV=kr9Qe$U9eic2:zޠھVF+r>=Yq\ujEC+6(9e\4?ÀBu2Emr$78_&Iݮ㶓rmf7Ur>~wDk.!ssN\KhL{E.G~w8\!*jtH9 \ʌYA*XS2rno˿ms2\n!d)O~lg#+%&i-DCgu9ӬIk~nmh#~{}94e|KND}زrpu: ݫ 2?<|f<7m%xwo۔zyh~ͯBEy6.k51pY|4!|:e1BX<soCQTD$y˰tC*ڤꗞs7UC?ORqLv{s;_Q SRa:]~<ͮ>9-836) 0U NEkN2`ڮUYgJ3 64_nCۯ]r~Wn M/Efssow^e0۷=snQ7kDf*Di]^׷:ӫC{Huh)d! wOw8bf|{93 #G\4ȼKMvykDq]Mk4σ&M1mJon7>vuJ7jAp!:R|pƹݺ횴߾?~׮m oX?< 1)$ a{=^q<}t˜B"FlM㥖R*5M8-0xP_$ tHSh<߼}}o˶yf72*27bL=Va * ]*i*$x>`5"v-EKM.02H397Ml*:քBJ@]v jj0R$a4- iO=.ϯo4ČVaKwH܅zHCi 7>t; 8_ Ry:w힛 Y9`fVkͥaqw}. xfcµyc3+|%c Hf+L4Bbzm%%%ϋ}4/⹽>l̋CD!6We,)62P_R%BD@hVZZiك ?y*}|%pܶEd+b"bEuf,Yk9ev{ZVSk[sIue l5 5].#ocgFTWz , >BDCS"18B({dIvi*9eN#"3 Ri~yyYLϔt (*yPK0LDͮcJ˨LLX$5UIq*u>/?{r._$Qc"fvD"̴/AC3΋.۲"C@G-$#EZsd j - 0ranB7LA""+ B):ΙК bf4#>|Հ4h Z*3 @S2h]cho9P=JF&P"D<M4 T-Y#;c)}* pL7ݮKȹW k6hr{0jUSjr: E0Ujwr~ztJ}Cx͊ yMOW|{W7}_ޜ?ypVj y4Bmco+ԍI2] T><ΰZBY &'(LΕ 53]w9{oCkCΓȱkK -XIH.\߬?||>>MTbDccd pAr,K PU#@3 QDSV f4"HCeny{Ui/k :C$,,ə51^rs5UӢZkRA yi}]cUA!)-|OgTqL h6P5b֞)&ϖV @ i$nBӸ/‡=~_3pCraH㹂+Rue\F(f f3 ڲRš] 1D RĻfLԻPK)u]w>\n DbdDK5uo Y0*L"}"T.O&5S<#Ĭi[b>̹i6)aQaϳY /  N,>mԭPr y.;kv FJ)UYc>v.fXPl7l$ *րR5Bo,xi#.Y(~40b U'bd j`NYsߕ#P+űǎ"BR":{tpv]O~|:M)P1"c*r>-93V96+2JظSɻ]ž֒.2WƵL LPr3LR[ōFXin}sO*mtO}uV95T[ĉ:&nR>&v ,bDjm(4}y,nכu0ZhWRt~p̗﷬T@/)yDbOXZY9i*D Qا1wԺx(1: MVպ͵NL>F.ǡSygy&Pz>Mi4lq~}V0tSf9<6D`0   ̤hF^ yj="\f~#(.?\N2sZBAԔA 9T EH$RjU޴.FdMcCDdgrqb޵FMh f<0p ĎsD!!!!F()b״ .KQ<(*Z&di7wϏ dSCmVa/kMN}U{ &1)d2ϓ>[ aX )9~ ;%lkMCi_՗(K[e>cJ)afw nVzuH|Ӯsq8'_~x/ֻ۫?}z8~hBS}@̇oNnu,F~N )j* kޑUe|j7+QQgdLDՇеDen;$%Vbyט*m*T Mg-M}.a~<}_lih}}Mb2Va8iJ}| 5Oݚ]Ĉ"2\LZsxq/>d:0Sش3 6ffS'FA+XK8_U q@4MOx[%l&5HM&y10:T& sdދ*&YP^$@V$D ԠUD]˫ icM̤HK 4 "PTc44Hu,ص݇_t|)_n@ʸ[_^_Mc$()5# RUXL+pp BXqVȌA.UE쇑ڮ뺕w. D Ɣ16>bTƘ4 JNafM x &ZM}W!W`unolW[wTKZw%^ֻv du4瑅ZjjihiYֆ m@Z ^mvo<͋iDD%RcP37$rTM6ս2s*UBUE&Ķ\EB"F V)焦z|Btt]ߟ~ZoD*[$/ƀevq!0sUT/L(A͒,n"~HTklZc59_νi +4j&A&`HRO$0. b^-W=" 3)V)<9 IDATHslV$fvHJ9ZgDLKhhR+xG>*JPt\] } QE@0@RDK$G,!g}*UAUV(dkH(I0@0R8Ce9o! ^8 Ys'w-ECV2\΄:RbBd4'2`#ѐM b@d)Zw^\GTZs?~7c9>˩0>.Sݶ =vס۬3ܾ{y]<4|r0Ԝaۇjn/cM-|ͪMnwU3Nz繀QӜ?C%!9#68x]}gǸ]pj2iM7!:}O4Cg}?"ܵ~ WFF)#HRuY|qztc]װpgJJjӾش̦C{L|~&3VۮR}a*T$1,Kv=1—@{^˃sX  "DT3ڄHA{, rT[\90*i|ji8}"eBO"ELbl{@T3 s9/#XM%#v)1cv"`^oWxVׯx:xLq`fOK2 +`ٸ#3>^S=2WrʄlWmeέc898%(U Dq.fMAѱg 0s9،M*0iK)H~>L91 h5%]|Z1TDt@%jxO]O࣋]Ǧ7sixfIBWm'2t6ykMK׺4)6t8>|zūߠw/(c>᫗uMzס֑rs%sIonn\̗x7_]_]_/^]ߍC_?U0vS^7rt2VȌ2iM|%G3H&Fd1FMNeZq?)srV~u_ܭ6L2c.m(@x!,eT%RjL:}<|W+8w&bnd߽yjmu-دwOcq|܏ 2"wĤƈ  -=Q\S0%mt+oJHLdU! :F`U`\R.◯__`ue<;W]^%ZT.I/JX}q]aG}8E<'$m$gPQtn ! !2GrUY1"yޅ|>R3; q3GP x.hd Ň=?MS ;j>>}jw5_]=W@ODӾ7㩱v 8%XYk86lz)CX iFbůzuPkar1&DD* d0!Tu~%ݩ6)x)UєjEPmXe$CΊ\Fm~CcvZ-xͪa/gM#lbӄ77Wնg!Yw} ё+Ex`Cq~ 1|$u3 LTr)ͥ$$k!r,!y $aF@4d0[ZN'֙Xz,gfYLL - @ gs=c]kw/0t8ԋr;3{\}uwC5<<]=~ Wv!pyuV2ʍoK}.=ct6\)D9$=—wMZMݺCwnH?=0~|Ud~4۔;yu:}}nRuՆ x\Ra$* bt%%H_y !{"\TOOߟlէۮG\CԶ@Ӊjx9"&]s޴NttuYmQ\'Ʌֳ/nodqy::oFGԞ3VI!Pw1T/=QyLYv)6@?Wk:˗o޿T9r=߫!\CRG|5ZINj#xb] ~43O;Gm,YT̂Af\㠇}TOӄA+ (FȞ=G 2cNծWz-xIp&>緗?}黏OW_6çii}D _3Sڞ?Y)@LgG @1GUbh۶saȀF"e T3gVٮ3Avlrunn xU˛~#:p8'%ɂĞ#ȌdK@%oĊLDZ R©<~\FZb*"fCOlA -~/B3Ono|]?yhf5>o7/-=◷-ګ۵S\g|ۇiqr,{Æl\PT1l$Bnu!""oҜ M+Ti 蔲 :t{{\ݘj5*q`5}yyi|)Հ53L]7m*16نzmrOS>VPoW >ݮjN)͓&*DMdRE RJRù0NYޠ릹 #9h8"J2H`rK%vU s옜1"fi>3"* 2GZ4If5!"H% "~znnww*eV=qK5g*EKEM.3=S6h*cwW}1yy)ETcǎLClڦ[H`8emo#[ys/sSPg}?[~.1#@5ZRIHX@J9Tӂh(Ȏȕs& ovU9̧T9DHLJLds9L2i5B藇̌VK2織Č:&yDDUHzx۾4`*DaBElKl5T%?~oW|&|:0Ħ 5" ^!99Ј%GGxjr<*b\(lH8$hubdDN9B3.=n3ixtfVts!<Ӑ'p|n]o6zM䎗x1R,2&W}ݮ鿺vӇO NO?~,|Ջׯno7~LY-9yʪl&L,c蠍8?7zӶQu< WS=\;L#[`p`$V.Gl>C)X+jb(@r0c\4V,vخ*߼ۓi<5E,z,cCZM%?/*x/_we M(x_NOZ~ڏA"vg!l)WpbX tY *-$`fLHO;Ŋ`Dy/2Rj8`2fHW5ٴMY9a9qv*:ap2O?06<Ѻ 1-3/U @\ Ú s"Y(2T31RБB5 M՛9ϴ v4/^٤8ؠIQ HSr>;6*ӪA)g-)0'x:e!.8)pv0;T^*+bDg|,*WeC`ТsX (m8Lc*9u*y>gŧP?}W[߾xg#gZ~o8d{ ΰ!RE}h9WSU\.Hjۏo?CRO_OcRѾmRy%Hc.RJY o**9Os.FHbMC!"#6Z *3"(-"H-5WJ -=s-*"1`ݐkϺ.Z9nԐ Etϓ \2d??Lc& M=T^Ap%;mI%r{̛]QO FJq}%̌]$8Fd bA {->>N #Nߕ嘒:o~1cB08+qyhj@˺Php} ? [^?? _X_2S*@صfAt:uYNytkhc"W Nˌz?{wЙo0FZ)լXEx\rUool,qyЍLЋ@]k)KD^DE:sfdURT3BulAf&e#sb8!E~?4Cαqq0lSHo~P7 ZUW\‛@[DTLR@=橔c'f ]׾*\rx:dwW۰aϾuYC6x9<>hWpxDb|-n(k5t]zǮ\>ٛ@m"+%.KSR6Tq}қMzTZZ}4:r?vZM(R̦q4王 =&̴ʴ\y 蛶* :1jZҼcp``烯1s3gs.]l)%AtM㵨 L,FbRmiwPqͶ_ʤs5Txr  ,kz!DXoxVw)j&|~5,J9":D*D3C@E^71L85rLUATJɥZ+y٪9`.B IDAT`Y AR$ʊjF XDE ]p {Zs,othRdQh!V2+)a)ƪ` "sT*1[! `&"lRLl@w-P<{eL-> *_q[ئ@<~_dqr(`'Ԭn_Ve~~;wTbW| pۿSF4s''(/a|;#^YgE54en` ﳳ]8esnSWkԃ%[zu~y0ΐ؃a^6u]e&f1=9%&y]6]lBBU{7{r`%¡yUUn lNR}; 7urŇMQA$\<<pާY=``G\TM^/{&j\21KU&\S\-`t?ʉ|:>7EP fXiT*U$h9HEѳ9XƺKtNkNv۝Y"{W?9HzzWNO0M"BM9z⺘eyySZ/2-wmr=Rn{K6ra ϏX)Mi,Kz lZLk\c"wy\7E1γ4rgU)! T0ȺnsÚFGt[<^Ǯ[+;Dժ)X}:,qcLLc|3n!aj* g9?pjHj "?g? !TUA4@"" gc#KeK9X d]ooڝ#W}S]>6_Q̪2čb3h]=S`c1H*@-zh $;$ 4UJ"fpZՀ|)JGywN,<*77חWFa BQ]|g'{<)6= ?}GOTKO/s64tH//8w%+!Zku%N.Wo, R&nEИ|z~|y4so/@Cv@LŃl[~qeI\}/<9Gði/jiD*{9Gq*bJQg&b!j h$*V6Gd5<#'`*fpGJUP4qd wG(:LXq௿ q€c;FEȚTJU5Ϯi\ b m j"g5S`(F`BHJQ;}/'D`DFp̆F V@@C+D2a eUL̔X̵m}%\Ҽw@Dpx];0%WpNӹhZAV+PC60Td5 '= {Q¹$r6+D`3笏@# Ȯ>7CjZ'Y?1|Sb!TKa)|z|b[.)*ؙ4R̓Z/WE@y]q#czuߠ5CN>H dEr]؉/UidT̹T_S\ zW;;Ӿ|T'##y,wxkdO%(k.6es*M \JtΩI.BSCdT6$ DSJëAzyY G"9Yh0-DQ|BRհBJDkL]\*iuknwݧxqYezǷQnɨbkRܪxm#qm*9".8D-2Oеs׺Omw/?7dA$B-mYԼ޻2.'s岕KNy.#_㺮sm;uퟖ?o/[?eS沅 |0-@1ѼMkzJjU0/##d;=!TbRe1DnD+%mKwn|,?Ο^- ·^N{=|YbȞgɵ.%tB!I-p\E xSZ+p`1kE%o"k"{2UMl,*Vzfd::GET01T5"dCT |R.nX%CH뽼72J4]]o<(yex67~˭;pV [%UnYDcXHR+؇mB۲Y>TV(PDhb`b XTX<80SfJx/(Z]JųG XQ8)*)C۾\dZW#˚,4VjiS5|Ӵm\\ݰ퐏4hu1y<8٧-֢:7YB(M TmLVSsRaBYB湔"*֟}F2%L99dHuƅ8C8f)Q`dѝ)e#(inHQ8 Vjh8(q;/Ef䰔95E-%)T$S D,0i9_D+@T OuTQ&``1@*сBaaG* !bGvm&lQ/cgW')JUDUׂ"9Cg@k^ FCZMY15s4  LPUKMΑc"GN@.ּNIIhZ,s M^H|P˺"HTdxn "ѹ'F@ZU1 ;GngrZIj::f5T244$20 h@Abb`KVUSAU)8HBv!V"B`<vr>DTU;a!(Ys) @2Xu^㗛݂Tw9};氘>v_6炥[aoY[3 :8W: z@gSvƅΙc2s!CȀ *UERdMu~V*.CJJɵbsZ/rR0:LnǏqޖu&x~~9?0>?,%^=O6-\Sv (ӜcEِvZv46%C.ʱK*}&sOwZrܵyegj%.J@9'E#Q**Bs1W>.#iˡ;&1a˚Ljpr1b! K]yrVϣ4ZMh[8wLUp9pab] 鴊U$]ox S}C)|_~˫f7~<vG71yvytX0gcw|]qfae;|K]|;lwk#bih;2IGjby=yԯ>R-u=h y]Az:҄n,i)yliTwm`0-#y[m9aǍV#ߝbB]xhjVTT X-C$f\J&|Tgè*s$U{Wx! . w+ ;FdB 7AuGXG,’ˡ 7R7tUA@d< QJchHhUUT:QM+9tu]LeW杬I ,5R) Y12"KqD.r V5QFFr縤